#!/usr/bin/env python """ A GET/POST Gateway License: GPL 2; share and enjoy! Author: Sean B. Palmer, inamidst.com Service: http://inamidst.com/getpost Source: http://inadmist.com/inside/getpost --- GET/POST Gateway

GET/POST Gateway

Abstract: This script allows people to have a permanent URI for inadvertantly POST-only resources. It has the side effect of breaking webarch to fix it. Source code.

Some sites use POST on their search forms, making you unable to bookmark or point to the results. This script allows you to circumvent that by doing the POST for you but providing a URI for the result.

For example, if a site uses the following form: <form action="http://example.org/cgi" method="post"><input type="text" name="search" /><input type="submit" /></form> and you wanted to provide a link to the search for "example term", you'd link to /getpost?uri=http://example.org/cgi&search=\ example+term. Note that if one of the form keys ends with "uri" (case insensitive), you must prefix an underscore: "_uri".

Example (the W3C's RDF Validator actually allows GET too, but POSTs by default).

Todo:

Sean B. Palmer
""" import cgitb; cgitb.enable() import sys, os, cgi, urllib method = os.environ.get('REQUEST_METHOD') form = cgi.FieldStorage() form.__call__ = lambda s: form[s].value def serve(status, body): sys.stdout.write("Status: %s\r\n" % status) sys.stdout.write("Content-Type: text/html; charset=utf-8\r\n\r\n") sys.stdout.write(body) sys.exit() def homepage(): i = __doc__.find('---') serve(200, __doc__[i+3:]) def getpost(head=None): if not form.has_key('uri'): homepage() uri = form('uri') data = {} for key in form.keys(): if key.startswith('_') and key.lower().endswith('_uri'): datakey = key[1:] else: datakey = key if key != 'uri': data[datakey] = form(key) u = urllib.urlopen(uri, urllib.urlencode(data)) info = u.info() info['Content-Location'] = uri # @@ argh! how does one get the status code? sys.stdout.write("Status: 200\r\n") sys.stdout.write(str(info)) sys.stdout.write("\r\n") if head: u.close() return while 1: # @@ relative links will all go astray; base munge? line = u.readline() if not line: break sys.stdout.write(line) u.close() def main(): if method == 'GET': getpost() elif method == 'HEAD': getpost(head=1) else: serve(501, "

Only GET and HEAD are supported.

\n") if __name__=="__main__": main()