#!/usr/bin/env python """ data.cgi - Data URI Resolver Author: Sean B. Palmer, inamidst.com @@ Autodetect whether to use GET or POST """ import sys, os, cgi, urllib allowed = frozenset(['text/plain', 'text/html', 'image/svg+xml', 'application/xhtml+xml']) PATH_INFO = os.environ.get('PATH_INFO', '') QUERY_STRING = os.environ.get('QUERY_STRING', '') SCRIPT_NAME = os.environ.get('SCRIPT_NAME', '') REQUEST_URI = os.environ.get('REQUEST_URI', '') REQUEST_METHOD = os.environ.get('REQUEST_METHOD', '') script = REQUEST_URI.split('?')[0] def serve(status, headers, body): sys.stdout.write("Status: %s\r\n" % status) for header in headers.iteritems(): sys.stdout.write("%s: %s\r\n" % header) sys.stdout.write("\r\n") sys.stdout.write(str(body)) sys.exit() def ok(mime, body): serve(200, {'Content-Type': mime}, body) def redirect(uri, temp=False): if not uri.startswith('http:'): from urlparse import urljoin domain = os.environ.get('SERVER_NAME', 'localhost') uri = urljoin('http://' + domain + REQUEST_URI, uri) status = (301, 307)[temp] headers = {'Location': uri, 'Content-Type': 'text/html'} body = 'Go!' % uri serve(status, headers, body) def error(msg): body = '

%s

' % cgi.escape(msg) serve(501, {'Content-Type': 'text/html'}, body) def query(): form = cgi.FieldStorage() form.__call__ = lambda s: form[s].value if not form.has_key('data'): error('Form must have key "data".') uridata = urllib.quote(form('data')) # Commas, as metachars, need encoding: , uridata = uridata.replace(',', '%2C') # @@ It should be done with slashes too, but that breaks Apache... # uridata = uridata.replace('/', '%2F') if form.has_key('mime'): mime = form('mime') if mime != 'text/html': uridata = mime + ',' + uridata redirect(script + uridata) def homepage(): import textwrap ok('text/html', textwrap.dedent("""\ Data URI Resolver - Paste 'n' Go
Media Type: (Use POST)

The form above uses GET by default but only allows up to 2,048 bytes. By switching to POST you won't get a bookmarkable URI, but you will be able to send up to 51,200 bytes.

inamidst.com Data URI Resolver

By Sean B. Palmer. See the script for details.
""")) def post(): form = cgi.FieldStorage() form.__call__ = lambda s: form[s].value if not form.has_key('data'): error('Form must have key "data".') uridata = urllib.quote(form('data')) data('/' + uridata) def data(path): # path = REQUEST_URI[5:] # len(SCRIPT_NAME.rsplit('/', 1)[0]):] if path.startswith('/'): path = path[1:] if ',' in path: mime, uridata = path.split(',', 1) else: mime, uridata = 'text/html', path if mime.endswith(';base64'): import base64 mime = mime[:-7] uridata = base64.b64decode(uridata) if mime not in allowed: uridata = mime + ',' + uridata mime = 'text/html' # error('MIME type "%s" is not allowed.' % mime) import urllib # @@ Should probably do this above uridata = urllib.unquote(uridata) if (REQUEST_METHOD == 'GET') and (len(uridata) >= 2048): error('Data length must be less than 2048 bytes.') elif (REQUEST_METHOD == 'POST') and (len(uridata) >= 51200): error('Data length must be less than 51,200 bytes.') ok(mime, uridata) def main(): import cgitb cgitb.enable() if REQUEST_METHOD == 'GET': if QUERY_STRING: query() elif PATH_INFO == '/': homepage() elif not PATH_INFO: redirect(REQUEST_URI + '/') else: data(PATH_INFO) else: post() if __name__=="__main__": main()