1 #!/usr/local/bin/python 2 3 """ 4 WSGI CGI handler code originating from PEP 333, transcribed by Titus Brown. 5 Previously a standalone CGI program, this is now a module imported by the actual 6 CGI programs. 7 """ 8 9 import os, sys 10 11 def run_with_cgi(application): 12 13 environ = dict(os.environ.items()) 14 environ['wsgi.input'] = sys.stdin 15 environ['wsgi.errors'] = sys.stderr 16 environ['wsgi.version'] = (1,0) 17 environ['wsgi.multithread'] = False 18 environ['wsgi.multiprocess'] = True 19 environ['wsgi.run_once'] = True 20 21 if environ.get('HTTPS','off') in ('on','1'): 22 environ['wsgi.url_scheme'] = 'https' 23 else: 24 environ['wsgi.url_scheme'] = 'http' 25 26 headers_set = [] 27 headers_sent = [] 28 29 def write(data): 30 if not headers_set: 31 raise AssertionError("write() before start_response()") 32 33 elif not headers_sent: 34 # Before the first output, send the stored headers 35 status, response_headers = headers_sent[:] = headers_set 36 sys.stdout.write('Status: %s\r\n' % status) 37 for header in response_headers: 38 sys.stdout.write('%s: %s\r\n' % header) 39 sys.stdout.write('\r\n') 40 41 sys.stdout.write(data) 42 sys.stdout.flush() 43 44 def start_response(status,response_headers,exc_info=None): 45 if exc_info: 46 try: 47 if headers_sent: 48 # Re-raise original exception if headers sent 49 raise exc_info[0], exc_info[1], exc_info[2] 50 finally: 51 exc_info = None # avoid dangling circular ref 52 elif headers_set: 53 raise AssertionError("Headers already set!") 54 55 headers_set[:] = [status,response_headers] 56 return write 57 58 result = application(environ, start_response) 59 try: 60 for data in result: 61 if data: # don't send headers until body appears 62 write(data) 63 if not headers_sent: 64 write('') # send headers now if body was empty 65 finally: 66 if hasattr(result,'close'): 67 result.close() 68 69 # vim: tabstop=4 expandtab shiftwidth=4