eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/hgweb/wsgicgi.py
changeset 69 c6bca38c1cbf
equal deleted inserted replaced
68:5ff1fc726848 69:c6bca38c1cbf
       
     1 # hgweb/wsgicgi.py - CGI->WSGI translator
       
     2 #
       
     3 # Copyright 2006 Eric Hopper <hopper@omnifarious.org>
       
     4 #
       
     5 # This software may be used and distributed according to the terms of the
       
     6 # GNU General Public License version 2 or any later version.
       
     7 #
       
     8 # This was originally copied from the public domain code at
       
     9 # http://www.python.org/dev/peps/pep-0333/#the-server-gateway-side
       
    10 
       
    11 import os, sys
       
    12 from mercurial import util
       
    13 
       
    14 def launch(application):
       
    15     util.set_binary(sys.stdin)
       
    16     util.set_binary(sys.stdout)
       
    17 
       
    18     environ = dict(os.environ.iteritems())
       
    19     environ.setdefault('PATH_INFO', '')
       
    20     if environ.get('SERVER_SOFTWARE', '').startswith('Microsoft-IIS'):
       
    21         # IIS includes script_name in path_info
       
    22         scriptname = environ['SCRIPT_NAME']
       
    23         if environ['PATH_INFO'].startswith(scriptname):
       
    24             environ['PATH_INFO'] = environ['PATH_INFO'][len(scriptname):]
       
    25 
       
    26     environ['wsgi.input'] = sys.stdin
       
    27     environ['wsgi.errors'] = sys.stderr
       
    28     environ['wsgi.version'] = (1, 0)
       
    29     environ['wsgi.multithread'] = False
       
    30     environ['wsgi.multiprocess'] = True
       
    31     environ['wsgi.run_once'] = True
       
    32 
       
    33     if environ.get('HTTPS', 'off').lower() in ('on', '1', 'yes'):
       
    34         environ['wsgi.url_scheme'] = 'https'
       
    35     else:
       
    36         environ['wsgi.url_scheme'] = 'http'
       
    37 
       
    38     headers_set = []
       
    39     headers_sent = []
       
    40     out = sys.stdout
       
    41 
       
    42     def write(data):
       
    43         if not headers_set:
       
    44             raise AssertionError("write() before start_response()")
       
    45 
       
    46         elif not headers_sent:
       
    47             # Before the first output, send the stored headers
       
    48             status, response_headers = headers_sent[:] = headers_set
       
    49             out.write('Status: %s\r\n' % status)
       
    50             for header in response_headers:
       
    51                 out.write('%s: %s\r\n' % header)
       
    52             out.write('\r\n')
       
    53 
       
    54         out.write(data)
       
    55         out.flush()
       
    56 
       
    57     def start_response(status, response_headers, exc_info=None):
       
    58         if exc_info:
       
    59             try:
       
    60                 if headers_sent:
       
    61                     # Re-raise original exception if headers sent
       
    62                     raise exc_info[0](exc_info[1], exc_info[2])
       
    63             finally:
       
    64                 exc_info = None     # avoid dangling circular ref
       
    65         elif headers_set:
       
    66             raise AssertionError("Headers already set!")
       
    67 
       
    68         headers_set[:] = [status, response_headers]
       
    69         return write
       
    70 
       
    71     content = application(environ, start_response)
       
    72     try:
       
    73         for chunk in content:
       
    74             write(chunk)
       
    75     finally:
       
    76         if hasattr(content, 'close'):
       
    77             content.close()