Bluish Coder

Programming Languages, Martials Arts and Computers. The Weblog of Chris Double.


2006-05-25

Script# - C# to Javascript compiler

Nikhil Kothari has a post on a C# to Javascript compiler. Similar in approach to Google's Web Toolkit it allows you to program your client side web code in C# and compile it to Javascript. From this:

using System;
using ScriptFX;
using ScriptFX.UI;

namespace HelloWorld {

    public class HelloWorldScriptlet : IScriptlet {

        private Button _okButton;
        private TextBox _nameTextBox;
        private Label _helloLabel;

        private XMLHttpRequest _request;

        public void Start() {
            _okButton = new Button(Document.GetElementById("okButton"));
            _nameTextBox = new TextBox(Document.GetElementById("nameTextBox"));
            _helloLabel = new Label(Document.GetElementById("helloLabel"));

            _okButton.Click += new EventHandler(OnOKButtonClick);
        }

        private void OnOKButtonClick(object sender, EventArgs e) {
            Callback completedCallback = new Callback(this.OnRequestComplete);

            _request = new XMLHttpRequest();
            _request.Onreadystatechange = Delegate.Unwrap(completedCallback);
            _request.Open("GET", "Hello.axd?name=" + _nameTextBox.Text, /* async */ true);
            _request.Send(null);
        }

        private void OnRequestComplete() {
            if (_request.ReadyState == 4) {
                _request.Onreadystatechange = null;

                string greeting = _request.ResponseText;
                _helloLabel.Text = greeting;
            }
        }
    }
}

It generates:

HelloWorld.HelloWorldScriptlet = function Scenarios_HelloWorldScriptlet() {
}
HelloWorld.HelloWorldScriptlet.prototype = {
    _okButton: null,
    _nameTextBox: null,
    _helloLabel: null,
    _request: null,

    start: function Scenarios_HelloWorldScriptlet$start() {
        this._okButton = new ScriptFX.UI.Button(document.getElementById('okButton'));
        this._nameTextBox = new ScriptFX.UI.TextBox(document.getElementById('nameTextBox'));
        this._helloLabel = new ScriptFX.UI.Label(document.getElementById('helloLabel'));
        this._okButton.add_click(new Delegate(this, this._onOKButtonClick));
    },

    _onOKButtonClick: function Scenarios_HelloWorldScriptlet$_onOKButtonClick(sender, e) {
        var completedCallback = new Delegate(this, this._onRequestComplete);
        this._request = new XMLHttpRequest();
        this._request.onreadystatechange = Delegate.unwrap(completedCallback);
        this._request.open('GET', 'Hello.axd?name=' + this._nameTextBox.get_text(), true);
        this._request.send(null);
    },

    _onRequestComplete: function Scenarios_HelloWorldScriptlet$_onRequestComplete() {
        if (this._request.readyState == 4) {
            this._request.onreadystatechange = null;
            var greeting = this._request.responseText;
            this._helloLabel.set_text(greeting);
        }
    }
}

HelloWorld.HelloWorldScriptlet.registerClass('HelloWorld.HelloWorldScriptlet', null, ScriptFX.IScriptlet);

Generating Javascript from other languages seems to be getting popular. Another system that does this is Morfik. They have some compelling demos and appear to compile C#, Pascal, Basic and Java into Javascript.

Tags: javascript 

2006-05-25

Handling X-Forwarded-For in Yaws

I run a Yaws webserver behind a Pound proxy. This works really well but all the IP addresses logged by Yaws appear as the localhost (127.0.0.1). This is due to Yaws picking up the IP address of the proxy as it forwards the request.

Pound sends the original IP address as a header in the HTTP request called X-Forwarded-For. This finally bugged me enough to modify Yaws to display the X-Forwarded-For IP address if the header was there, otherwise display the normal IP address.

The 'quick hack' change was quite simple. I modified the include/yaws_api.hrl file to add x_fowarded_for to the headers record:

-record(headers, {
   connection,
   accept,
   host,
   if_modified_since,
   if_match,
   if_none_match,
   if_range,
   if_unmodified_since,
   range,
   referer,
   user_agent,
   accept_ranges,
   cookie = [],
   keep_alive,
   location,
   content_length,
   content_type,
   content_encoding,
   authorization,
   transfer_encoding,
   x_forwarded_for,
   other = []   %% misc other headers
  }).

The idea being that this value will be set by Yaws when it first parses the HTTP request headers. This is done by modifying the http_collect_headers function in 'src/yaws.erl' to contain the following code:

{ok, {http_header, _Num, 'X-Forwarded-For',_, X}} ->
     http_collect_headers(CliSock, Req, H#headers{x_forwarded_for = X},SSL)

This was basically a copy and paste of the way the other headers are handled. In the code that handles the logging I just check for the header and output the IP address if it is there, otherwise use the IP address from the request itself. This is done by a helper function I added to src/yaws_server.erl:

x_forwarded_for_or_ip(Ip, Item)->
    case Item of
        undefined -> Ip;
        Item -> yaws:parse_ip(Item)
    end.

The 'Item' passed to this function is the x_forwarded_for element of the 'headers' record. If the 'X-Forwarded-For' header exists I parse the string into an IP address using yaws:parse_ip/1.

All that remains is to change the maybe_access_log/3 in src/yaws_server.erl to call this helper function:

     TrueIp = x_forwarded_for_or_ip(Ip, H#headers.x_forwarded_for),
     yaws_log:accesslog(SC#sconf.servername, TrueIp, User,
          [Meth, $\s, Path, $\s, Ver], 
          Status, Len, Referrer, UserAgent);

Now all my IP's appear correctly forwarded from Pound in the Yaws server.

Tags: erlang 

2006-05-24

Back in Wellington

I arrived back in Wellington this morning. Melbourne's weather was just taking a turn for the worse so it looked like a good time to leave. That and I'd managed to complete enough of the project I was working on not to be there full time. Wellington's weather is not looking much better though! Hopefully I can now churn through some of the projects I'd parked while away.

Tags: misc 

2006-05-24

Extending prototypes of built in Javascript objects

Web Graphics has a good post outlining the reasons why it is not a good idea to extend the prototype of Object and Array. Tracking down bugs caused by breaking 'for....in' is a pain...

Tags: javascript 

2006-05-24

Icing - A Scheme continuation based web framework

Tony from LShift has announced an interesting looking project they've put together called Icing. They put SISCWeb, SSAX and SXPath together, along with their own code, to create a web development system in Scheme.

It seems to cover generation of the user interface, accessing the database as well as using the continuation based SISCWeb framework for application flow. There is a presentation here.

Tags: continuations 


This site is accessable over tor as hidden service 6vp5u25g4izec5c37wv52skvecikld6kysvsivnl6sdg6q7wy25lixad.onion, or Freenet using key:
USK@1ORdIvjL2H1bZblJcP8hu2LjjKtVB-rVzp8mLty~5N4,8hL85otZBbq0geDsSKkBK4sKESL2SrNVecFZz9NxGVQ,AQACAAE/bluishcoder/-61/


Tags

Archives
Links