]> git.lizzy.rs Git - plan9front.git/blob - sys/lib/python/mercurial/hgweb/wsgicgi.py
/sys/lib/dist/mkfile: test for .git directory
[plan9front.git] / sys / lib / python / mercurial / hgweb / wsgicgi.py
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, incorporated herein by reference.
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 '.cgi' in environ['PATH_INFO']:
21         environ['PATH_INFO'] = environ['PATH_INFO'].split('.cgi', 1)[1]
22
23     environ['wsgi.input'] = sys.stdin
24     environ['wsgi.errors'] = sys.stderr
25     environ['wsgi.version'] = (1, 0)
26     environ['wsgi.multithread'] = False
27     environ['wsgi.multiprocess'] = True
28     environ['wsgi.run_once'] = True
29
30     if environ.get('HTTPS','off').lower() in ('on','1','yes'):
31         environ['wsgi.url_scheme'] = 'https'
32     else:
33         environ['wsgi.url_scheme'] = 'http'
34
35     headers_set = []
36     headers_sent = []
37     out = sys.stdout
38
39     def write(data):
40         if not headers_set:
41             raise AssertionError("write() before start_response()")
42
43         elif not headers_sent:
44             # Before the first output, send the stored headers
45             status, response_headers = headers_sent[:] = headers_set
46             out.write('Status: %s\r\n' % status)
47             for header in response_headers:
48                 out.write('%s: %s\r\n' % header)
49             out.write('\r\n')
50
51         out.write(data)
52         out.flush()
53
54     def start_response(status, response_headers, exc_info=None):
55         if exc_info:
56             try:
57                 if headers_sent:
58                     # Re-raise original exception if headers sent
59                     raise exc_info[0](exc_info[1], exc_info[2])
60             finally:
61                 exc_info = None     # avoid dangling circular ref
62         elif headers_set:
63             raise AssertionError("Headers already set!")
64
65         headers_set[:] = [status, response_headers]
66         return write
67
68     content = application(environ, start_response)
69     for chunk in content:
70         write(chunk)