Generic Web Proxies

In my quest for increased adoption of geospatial web services, I would constantly bash my head against the wall trying to debug GIS applications. So if you have suffered from “what the” behaviour such as …

  • weird uri encoding
  • apps pretending to talk SSL but only on some requests
  • not supporting BASIC authentication when they say they do
  • clients not sending the required STYLES WMS kvp
  • sending hundreds upon hundreds of chunked requests …

then these scripts/apps may be for you. They are pretty generic and can be applied to any AJAX-type cross-domain restriction. The only OGC specific type line is the string replace of the online resource with the proxy uri (for obvious reasons for the getcapabilities document).

Other recommends ..

  1. For desktop based apps, i highly recommend fiddler2 as man in the middle proxy interceptor for debugging HTTP. It even does HTTPS mitm :)
  2. If you want to enable HTTPS/BASIC authentication on a desktop client that doesnt support it, check out InteProxy or email me for my own “Gismo” command line version. This will allow apps such as GRASS or QGIS which only has standard WMS support to magically start working on these services

But if you are just trying to get your poor OpenLayers application talking to that lonesome WFS server sitting on the interweb, these might come in handy!

Note that these are open proxies by default!

< ?php
	$urlparams = urldecode($_SERVER['QUERY_STRING']);
         $ch = curl_init();
	curl_setopt($ch, CURLOPT_URL,$url."&Styles=");
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,  2);
 	curl_setopt($ch, CURLOPT_USERAGENT, "Openlayers proxy - CTweedie hax"); // Set a different user-agent so we can track usage easier
	curl_setopt($ch, CURLOPT_FAILONERROR,1);
	//curl_setopt($ch, CURLOPT_VERBOSE, 1);
   	curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);  // the next 3 lines makes it work through https SSL3 with authorization.
	curl_setopt($ch, CURLOPT_SSLVERSION, 3);
	curl_setopt($ch, CURLOPT_USERPWD, $user.":".$pass);
	$data = curl_exec($ch); // Execute query
        $data = str_replace("https://www.wms.com/server/to/reflect/to?","https://www.wms.com/server/proxy?", $data)
        $content_type = curl_getinfo( $ch, CURLINFO_CONTENT_TYPE );
	header('Content-Type: '.$content_type);
	echo $data;
	curl_close($ch);
>

Python equivalent … almost identical to the OpenLayers version. In most situations, py urllib runs hands down quicker than php curl but it could well be my dodgy code!

#!/usr/bin/env python -u

import urllib
import urllib2
import cgi
import socket
import msvcrt
import os
import sys
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
# timeout in seconds
timeout = 15
socket.setdefaulttimeout(timeout)

fs = cgi.FieldStorage()
urlt = "https://www.wms.com/server/to/reflect/to?"

for i in fs.keys():
  urlt += i+"="+fs[i].value+"&"
url = urllib.unquote(urlt)
try:
    if url.startswith("http://") or url.startswith("https://"):
           passman = urllib2.HTTPPasswordMgrWithDefaultRealm()      # this creates a password manager
           passman.add_password(None, urlt, 'user', 'password')      # because we have put None at the start it will always use this username/password combination
           authhandler = urllib2.HTTPBasicAuthHandler(passman)                 # create the AuthHandler
           opener = urllib2.build_opener(authhandler)
           urllib2.install_opener(opener)
        y = urllib2.urlopen(url)

        headers = str(y.info()).split('\n')
        for h in headers:
            if h.startswith("Content-Type:"):
                print h
        print
        print y.read().replace("https://www.wms.com/server/to/reflect/to?","https://www.wms.com/server/proxy?")
        y.close()
    else:
        print """Content-Type: text/plain Illegal request."""
except Exception, E:
    print "Status: 500 Unexpected Error"
    print "Content-Type: text/plain"
    print
    print url
    print "Some unexpected error occurred. Error text was:", E

2 thoughts on “Generic Web Proxies”

  1. Great stuff, thanks… I have been looking to develop a generic, reusable proxy, and/or a “JSONifier” for XML web services, just haven’t yet had a lot of time to dig into it yet…

    Ever since AJAX was effectively broken by the cross-domain restrictions put in place, this type of thing has been a huge need.

    You raise some good points with regard to other wierdnesses and inconsistencies from one web service to the next, which proxies may help to solve as well.

Comments are closed.