##// END OF EJS Templates
hgweb: delete a local variable instead of setting to `None`...
Matt Harbison -
r44445:873d0fec default
parent child Browse files
Show More
@@ -1,94 +1,94 b''
1 # hgweb/wsgicgi.py - CGI->WSGI translator
1 # hgweb/wsgicgi.py - CGI->WSGI translator
2 #
2 #
3 # Copyright 2006 Eric Hopper <hopper@omnifarious.org>
3 # Copyright 2006 Eric Hopper <hopper@omnifarious.org>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
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.
6 # GNU General Public License version 2 or any later version.
7 #
7 #
8 # This was originally copied from the public domain code at
8 # This was originally copied from the public domain code at
9 # http://www.python.org/dev/peps/pep-0333/#the-server-gateway-side
9 # http://www.python.org/dev/peps/pep-0333/#the-server-gateway-side
10
10
11 from __future__ import absolute_import
11 from __future__ import absolute_import
12
12
13 import os
13 import os
14
14
15 from ..pycompat import getattr
15 from ..pycompat import getattr
16 from .. import pycompat
16 from .. import pycompat
17
17
18 from ..utils import procutil
18 from ..utils import procutil
19
19
20 from . import common
20 from . import common
21
21
22
22
23 def launch(application):
23 def launch(application):
24 procutil.setbinary(procutil.stdin)
24 procutil.setbinary(procutil.stdin)
25 procutil.setbinary(procutil.stdout)
25 procutil.setbinary(procutil.stdout)
26
26
27 environ = dict(pycompat.iteritems(os.environ)) # re-exports
27 environ = dict(pycompat.iteritems(os.environ)) # re-exports
28 environ.setdefault('PATH_INFO', b'')
28 environ.setdefault('PATH_INFO', b'')
29 if environ.get('SERVER_SOFTWARE', '').startswith('Microsoft-IIS'):
29 if environ.get('SERVER_SOFTWARE', '').startswith('Microsoft-IIS'):
30 # IIS includes script_name in PATH_INFO
30 # IIS includes script_name in PATH_INFO
31 scriptname = environ['SCRIPT_NAME']
31 scriptname = environ['SCRIPT_NAME']
32 if environ['PATH_INFO'].startswith(scriptname):
32 if environ['PATH_INFO'].startswith(scriptname):
33 environ['PATH_INFO'] = environ['PATH_INFO'][len(scriptname) :]
33 environ['PATH_INFO'] = environ['PATH_INFO'][len(scriptname) :]
34
34
35 stdin = procutil.stdin
35 stdin = procutil.stdin
36 if environ.get('HTTP_EXPECT', '').lower() == '100-continue':
36 if environ.get('HTTP_EXPECT', '').lower() == '100-continue':
37 stdin = common.continuereader(stdin, procutil.stdout.write)
37 stdin = common.continuereader(stdin, procutil.stdout.write)
38
38
39 environ['wsgi.input'] = stdin
39 environ['wsgi.input'] = stdin
40 environ['wsgi.errors'] = procutil.stderr
40 environ['wsgi.errors'] = procutil.stderr
41 environ['wsgi.version'] = (1, 0)
41 environ['wsgi.version'] = (1, 0)
42 environ['wsgi.multithread'] = False
42 environ['wsgi.multithread'] = False
43 environ['wsgi.multiprocess'] = True
43 environ['wsgi.multiprocess'] = True
44 environ['wsgi.run_once'] = True
44 environ['wsgi.run_once'] = True
45
45
46 if environ.get('HTTPS', 'off').lower() in ('on', '1', 'yes'):
46 if environ.get('HTTPS', 'off').lower() in ('on', '1', 'yes'):
47 environ['wsgi.url_scheme'] = 'https'
47 environ['wsgi.url_scheme'] = 'https'
48 else:
48 else:
49 environ['wsgi.url_scheme'] = 'http'
49 environ['wsgi.url_scheme'] = 'http'
50
50
51 headers_set = []
51 headers_set = []
52 headers_sent = []
52 headers_sent = []
53 out = procutil.stdout
53 out = procutil.stdout
54
54
55 def write(data):
55 def write(data):
56 if not headers_set:
56 if not headers_set:
57 raise AssertionError(b"write() before start_response()")
57 raise AssertionError(b"write() before start_response()")
58
58
59 elif not headers_sent:
59 elif not headers_sent:
60 # Before the first output, send the stored headers
60 # Before the first output, send the stored headers
61 status, response_headers = headers_sent[:] = headers_set
61 status, response_headers = headers_sent[:] = headers_set
62 out.write(b'Status: %s\r\n' % pycompat.bytesurl(status))
62 out.write(b'Status: %s\r\n' % pycompat.bytesurl(status))
63 for hk, hv in response_headers:
63 for hk, hv in response_headers:
64 out.write(
64 out.write(
65 b'%s: %s\r\n'
65 b'%s: %s\r\n'
66 % (pycompat.bytesurl(hk), pycompat.bytesurl(hv))
66 % (pycompat.bytesurl(hk), pycompat.bytesurl(hv))
67 )
67 )
68 out.write(b'\r\n')
68 out.write(b'\r\n')
69
69
70 out.write(data)
70 out.write(data)
71 out.flush()
71 out.flush()
72
72
73 def start_response(status, response_headers, exc_info=None):
73 def start_response(status, response_headers, exc_info=None):
74 if exc_info:
74 if exc_info:
75 try:
75 try:
76 if headers_sent:
76 if headers_sent:
77 # Re-raise original exception if headers sent
77 # Re-raise original exception if headers sent
78 raise exc_info[0](exc_info[1], exc_info[2])
78 raise exc_info[0](exc_info[1], exc_info[2])
79 finally:
79 finally:
80 exc_info = None # avoid dangling circular ref
80 del exc_info # avoid dangling circular ref
81 elif headers_set:
81 elif headers_set:
82 raise AssertionError(b"Headers already set!")
82 raise AssertionError(b"Headers already set!")
83
83
84 headers_set[:] = [status, response_headers]
84 headers_set[:] = [status, response_headers]
85 return write
85 return write
86
86
87 content = application(environ, start_response)
87 content = application(environ, start_response)
88 try:
88 try:
89 for chunk in content:
89 for chunk in content:
90 write(chunk)
90 write(chunk)
91 if not headers_sent:
91 if not headers_sent:
92 write(b'') # send headers now if body was empty
92 write(b'') # send headers now if body was empty
93 finally:
93 finally:
94 getattr(content, 'close', lambda: None)()
94 getattr(content, 'close', lambda: None)()
General Comments 0
You need to be logged in to leave comments. Login now