ASP.NET xDomainProxy for OpenLayers getInfo requests

After a long time of just talking about using geoserver we have eventually installed it on our server. Making it work behind IIS is a subject for another article and I am hoping to post it soon.

Anyway, we decided to make our geoserver available at geoserver.cartoninjas.net, while the applications we write are likely to be hosted under different subdomains or even under different domains. Since x-domain requests are not allowed in JavaScript due to some security restrictions I needed to create a simple server side proxy that would be exposed to application as a local resource and would take care of pulling the info when a getInfo requests are issued by OpenLayers.

I started with setting up a proxyHost in OpenLayers:

//proxy host
OpenLayers.ProxyHost = 'xDomainProxy.ashx?url=';

Then a server side script for a generic handler:

<%@ WebHandler Language="C#" Class="xDomainProxy" %>

using System;
using System.Web;

public class xDomainProxy : IHttpHandler {
    
    public void ProcessRequest (HttpContext context) {

        //OpenLayers.ProxyHost = 'xdomainProxy.aspx?url=' so the requested url is passed in a url param
        string requestUrl = HttpUtility.UrlDecode(context.Request.QueryString["url"]);

        //test if the request string was passed and of so request data from the destination server
        if (requestUrl != null)
        {
            //create a new HttpWebRequest
            System.Net.HttpWebRequest webRequest;
            webRequest = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(requestUrl);
            webRequest.Method = "GET";

            System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)webRequest.GetResponse();

            //check if the data was successfully retrieved
            if (response.StatusCode.ToString().ToLower() == "ok")
            {
                //set the appropriate response content type
                context.Response.ContentType = response.ContentType;

                //Read the stream associated with the response.
                System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream());

                //and write it to response
                context.Response.Write(reader.ReadToEnd());
            }
        }
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }
}

And voila, it's ready to be used ;)

A side note: although in many cases this proxy will work properly this is a mini version of the code and should not be implemented in the production environment - it does not catch any errors and will fail if the connection is not available. Also it was written to work with OpenLayers specifically (OpenLayers.ProxyHost) and needs some extra work before it can act as a bit more flexible proxy allowing one to pull data without having to escape the passed url.

blog comments powered by Disqus