#!/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:
Let's make this obey robots.txt.
Do both GET -> POST and POST -> GET.
Get Content-Location to work properly.
Link to the TAG documentation on the issue.
Ask www-tag about this.
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, "