0001# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org)
0002# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
0003import os
0004import sys
0005
0006def paste_run_cgi(wsgi_app, global_conf):
0007    run_with_cgi(wsgi_app)
0008
0009stdout = sys.__stdout__
0010
0011# Taken from the WSGI spec:
0012
0013def run_with_cgi(application):
0014
0015    environ = dict(os.environ.items())
0016    environ['wsgi.input']        = sys.stdin
0017    environ['wsgi.errors']       = sys.stderr
0018    environ['wsgi.version']      = (1,0)
0019    environ['wsgi.multithread']  = False
0020    environ['wsgi.multiprocess'] = True
0021    environ['wsgi.run_once']    = True
0022
0023    if environ.get('HTTPS','off') in ('on','1'):
0024        environ['wsgi.url_scheme'] = 'https'
0025    else:
0026        environ['wsgi.url_scheme'] = 'http'
0027
0028    headers_set = []
0029    headers_sent = []
0030
0031    def write(data):
0032        if not headers_set:
0033             raise AssertionError("write() before start_response()")
0034
0035        elif not headers_sent:
0036             # Before the first output, send the stored headers
0037             status, response_headers = headers_sent[:] = headers_set
0038             stdout.write('Status: %s\r\n' % status)
0039             for header in response_headers:
0040                 stdout.write('%s: %s\r\n' % header)
0041             stdout.write('\r\n')
0042
0043        stdout.write(data)
0044        stdout.flush()
0045
0046    def start_response(status,response_headers,exc_info=None):
0047        if exc_info:
0048            try:
0049                if headers_sent:
0050                    # Re-raise original exception if headers sent
0051                    raise exc_info[0], exc_info[1], exc_info[2]
0052            finally:
0053                exc_info = None     # avoid dangling circular ref
0054        elif headers_set:
0055            raise AssertionError("Headers already set!")
0056
0057        headers_set[:] = [status,response_headers]
0058        return write
0059
0060    result = application(environ, start_response)
0061    try:
0062        for data in result:
0063            if data:    # don't send headers until body appears
0064                write(data)
0065        if not headers_sent:
0066            write('')   # send headers now if body was empty
0067    finally:
0068        if hasattr(result,'close'):
0069            result.close()