Sunday, 9 December 2012

Building your own mapagent http handler in .net/PHP/Java

This post basically answers a question I posed 5 years ago. Is it possible to build a pure .net/PHP/Java mapagent handler that does not require Apache or IIS? The motivation being, we want a "portable" self-contained web tier that does not require the cumbersome administration/configuration that Apache or IIS requires.

At the time of that post, Windows XP was still the dominant client version of Windows and as we all know IIS was absolutely crippled on XP, making ASP.net development an absolute pain. My question was born out of a desire to ditch this crippled IIS and be able to use something lightweight like Cassini to host my development MapGuide web applications.

At the time, I didn't think it was possible due to the belief that key APIs were missing to support operations required by the AJAX viewer (namely the ability to manipulate the MgMap display parameters as most MgMap properties in the public API are read-only).

Fast forward 5 years, and in the process of hacking on the AS YET UN-ANNOUNCED PROJECT, I got hit with the same problem. Without a way to manipulate the MgMap over http using the existing public MapGuide APIs, we cannot have a functional self-contained AJAX viewer free of IIS/Apache.

Well fortunately as I found out, there is a way to do this. Say hello to the following classes:

  • MgHttpRequest
  • MgHttpResponse
For the longest time, these classes were sitting there in the MapGuide API with the most scant of API documentation, and nobody having any idea what these classes actually do. As it turns out, the naming of these classes is a bit deceptive. If I were to have named these classes, they would've been called:
  • MgHttpRequestHandler
  • MgHttpRequestHandlerResponse
Which would've greatly clarified what these classes are supposed to do. Which is to:
  1. Set up a collection of key-value pairs from incoming http request parameters
  2. Invoke the request handler with these parameters
  3. Receive the handler response and output the contents
If you look at the source code for the Apache/ISAPI/CGI handlers, they all follow this same process using MgHttpRequest and MgHttpResponse:
  • The key-value pairs are collected using the respective APIs in Apache/ISAPI/CGI
  • The handler response is outputted using the respective APIs in Apache/ISAPI/CGI
So back to the pressing issue, how does one manipulate MgMap display parameters if the public API can't let us do this? Simple, we use MgHttpRequest to build up the required key-value parameter pairs for a GETDYNAMICMAPOVERLAYIMAGE request. When executed, MgHttpRequest will resolve the correct HTTP operation handler, forward your specified parameters across to the handler and receive back the response from this handler. The handlers (that you'll never directly see or access) does the actual grunt work. All we have to do from our end is pass the correct operation and parameters to MgHttpRequest.

This response returned by the handler (MgHttpResponse) you then use to output the result back out to the http response stream.

So how can we have a mapagent http handler in say ... ASP.net (WebForms)?
  • Collect the required parameters from Request.Form (for POST) or Request.QueryString (for GET)
  • Check the existence of USERNAME, PASSWORD parameter (or extract from http authentication header) or the SESSION parameter. Return a http 401 if none of these parameters are found.
  • Create a MgHttpRequest, plug in these collected parameters
  • Execute the MgHttpRequest
  • Write out the necessary response headers based on information in the MgHttpResponse
  • Write out the MgHttpResponse contents
If implemented correctly, your ASP.net page will function exactly as mapagent.fcgi, taking the same parameters and returning the same responses.

For PHP/Java the process is the same with obviously different APIs to extract http request parameters, do 401 statuses and output of http responses.

This is what we do in our AS YET UN-ANNOUNCED PROJECT, and as a result we are able to fully replicate the mapagent http handler without the need to have Apache or IIS.

The AS YET UN-ANNOUNCED PROJECT will be revealed shortly.

1 comment:

Jason B said...

That's pretty cool Jackie! Not a huge Java fan, but could easily see this used with a .Net self hosted app or simple light weight c-based http server like Haris wrote for GeoREST. He may have even taken this approach for the initial MgRest app he was demoing a few years back.