annotate roundup/cgi/wsgi_handler.py @ 5837:883c9e90b403

Fix problem with cgi.escape being depricated a different way. This way uses anypy and is cleaner. Also fixes incorrect/incomplete change that resulted in escaped in TAL generated by TALInterpreter.py. The escaped quotes break javascript etc. defined using tal string: values. TODO: add test cases for TAL. This wouldn't have snuck through for a month if we had good coverage of that library.
author John Rouillard <rouilj@ieee.org>
date Sat, 06 Jul 2019 13:12:58 -0400
parents edd9e2c67785
children 40f5b20d1e70
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1 # WSGI interface for Roundup Issue Tracker
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2 #
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3 # This module is free software, you may redistribute it
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
4 # and/or modify under the same terms as Python.
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
5 #
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
6
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
7 import os
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
8 import cgi
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
9 import weakref
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
10
5837
883c9e90b403 Fix problem with cgi.escape being depricated a different way. This way
John Rouillard <rouilj@ieee.org>
parents: 5823
diff changeset
11 from roundup.anypy.html import html_escape
5800
1a835db41674 Call cgi.escape only on python 2. Replace with html.escapeif it can be
John Rouillard <rouilj@ieee.org>
parents: 5664
diff changeset
12
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
13 import roundup.instance
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
14 from roundup.cgi import TranslationService
5409
277e91bf7936 Python 3 preparation: update BaseHTTPServer imports.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
15 from roundup.anypy import http_
5609
dccf9b7e5ee4 Fix CSV export with WSGI and Python 3 (issue2551019).
Tom Ekberg <tekberg@uw.edu>
parents: 5539
diff changeset
16 from roundup.anypy.strings import s2b, bs2b
5409
277e91bf7936 Python 3 preparation: update BaseHTTPServer imports.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
17 BaseHTTPRequestHandler = http_.server.BaseHTTPRequestHandler
277e91bf7936 Python 3 preparation: update BaseHTTPServer imports.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5378
diff changeset
18 DEFAULT_ERROR_MESSAGE = http_.server.DEFAULT_ERROR_MESSAGE
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
19
5821
e7b30ab60941 Fix REST API for WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5800
diff changeset
20 class Headers(object):
e7b30ab60941 Fix REST API for WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5800
diff changeset
21 """ Idea more or less stolen from the 'apache.py' in same directory.
e7b30ab60941 Fix REST API for WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5800
diff changeset
22 Except that wsgi stores http headers in environment.
e7b30ab60941 Fix REST API for WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5800
diff changeset
23 """
e7b30ab60941 Fix REST API for WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5800
diff changeset
24 def __init__(self, environ):
e7b30ab60941 Fix REST API for WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5800
diff changeset
25 self.environ = environ
e7b30ab60941 Fix REST API for WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5800
diff changeset
26
e7b30ab60941 Fix REST API for WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5800
diff changeset
27 def mangle_name(self, name):
5823
edd9e2c67785 Make REST-API updates work with WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5821
diff changeset
28 """ Content-Type is handled specially, it doesn't have a HTTP_
edd9e2c67785 Make REST-API updates work with WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5821
diff changeset
29 prefix in cgi.
edd9e2c67785 Make REST-API updates work with WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5821
diff changeset
30 """
5821
e7b30ab60941 Fix REST API for WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5800
diff changeset
31 n = name.replace('-', '_').upper()
5823
edd9e2c67785 Make REST-API updates work with WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5821
diff changeset
32 if n == 'CONTENT_TYPE':
edd9e2c67785 Make REST-API updates work with WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5821
diff changeset
33 return n
5821
e7b30ab60941 Fix REST API for WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5800
diff changeset
34 return 'HTTP_' + n
e7b30ab60941 Fix REST API for WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5800
diff changeset
35
e7b30ab60941 Fix REST API for WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5800
diff changeset
36 def get(self, name, default = None):
e7b30ab60941 Fix REST API for WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5800
diff changeset
37 return self.environ.get(self.mangle_name(name), default)
e7b30ab60941 Fix REST API for WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5800
diff changeset
38 getheader = get
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
39
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
40 class Writer(object):
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
41 '''Perform a start_response if need be when we start writing.'''
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
42 def __init__(self, request):
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
43 self.request = request #weakref.ref(request)
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
44 def write(self, data):
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
45 f = self.request.get_wfile()
5609
dccf9b7e5ee4 Fix CSV export with WSGI and Python 3 (issue2551019).
Tom Ekberg <tekberg@uw.edu>
parents: 5539
diff changeset
46 self.write = lambda data: f(bs2b(data))
dccf9b7e5ee4 Fix CSV export with WSGI and Python 3 (issue2551019).
Tom Ekberg <tekberg@uw.edu>
parents: 5539
diff changeset
47 return self.write(data)
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
48
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
49 class RequestDispatcher(object):
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
50 def __init__(self, home, debug=False, timing=False, lang=None):
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
51 assert os.path.isdir(home), '%r is not a directory'%(home,)
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
52 self.home = home
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
53 self.debug = debug
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
54 self.timing = timing
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
55 if lang:
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
56 self.translator = TranslationService.get_translation(lang,
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
57 tracker_home=home)
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
58 else:
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
59 self.translator = None
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
60
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
61 def __call__(self, environ, start_response):
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
62 """Initialize with `apache.Request` object"""
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
63 self.environ = environ
3990
0728808fdf5c make WSGI threadsafe
Richard Jones <richard@users.sourceforge.net>
parents: 3736
diff changeset
64 request = RequestDispatcher(self.home, self.debug, self.timing)
0728808fdf5c make WSGI threadsafe
Richard Jones <richard@users.sourceforge.net>
parents: 3736
diff changeset
65 request.__start_response = start_response
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
66
3990
0728808fdf5c make WSGI threadsafe
Richard Jones <richard@users.sourceforge.net>
parents: 3736
diff changeset
67 request.wfile = Writer(request)
0728808fdf5c make WSGI threadsafe
Richard Jones <richard@users.sourceforge.net>
parents: 3736
diff changeset
68 request.__wfile = None
5821
e7b30ab60941 Fix REST API for WSGI
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5800
diff changeset
69 request.headers = Headers(environ)
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
70
4292
859ab007829f Handle OPTIONS http request method in wsgi handler, fixes issue2550587.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3990
diff changeset
71 if environ ['REQUEST_METHOD'] == 'OPTIONS':
859ab007829f Handle OPTIONS http request method in wsgi handler, fixes issue2550587.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3990
diff changeset
72 code = 501
859ab007829f Handle OPTIONS http request method in wsgi handler, fixes issue2550587.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3990
diff changeset
73 message, explain = BaseHTTPRequestHandler.responses[code]
859ab007829f Handle OPTIONS http request method in wsgi handler, fixes issue2550587.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3990
diff changeset
74 request.start_response([('Content-Type', 'text/html'),
859ab007829f Handle OPTIONS http request method in wsgi handler, fixes issue2550587.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3990
diff changeset
75 ('Connection', 'close')], code)
5539
3a07c57d72bb Handle string-to-bytes conversions for Python 3 for wsgi_handler.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5409
diff changeset
76 request.wfile.write(s2b(DEFAULT_ERROR_MESSAGE % locals()))
4292
859ab007829f Handle OPTIONS http request method in wsgi handler, fixes issue2550587.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3990
diff changeset
77 return []
859ab007829f Handle OPTIONS http request method in wsgi handler, fixes issue2550587.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents: 3990
diff changeset
78
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
79 tracker = roundup.instance.open(self.home, not self.debug)
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
80
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
81 # need to strip the leading '/'
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
82 environ["PATH_INFO"] = environ["PATH_INFO"][1:]
3990
0728808fdf5c make WSGI threadsafe
Richard Jones <richard@users.sourceforge.net>
parents: 3736
diff changeset
83 if request.timing:
0728808fdf5c make WSGI threadsafe
Richard Jones <richard@users.sourceforge.net>
parents: 3736
diff changeset
84 environ["CGI_SHOW_TIMING"] = request.timing
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
85
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
86 form = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ)
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
87
3990
0728808fdf5c make WSGI threadsafe
Richard Jones <richard@users.sourceforge.net>
parents: 3736
diff changeset
88 client = tracker.Client(tracker, request, environ, form,
0728808fdf5c make WSGI threadsafe
Richard Jones <richard@users.sourceforge.net>
parents: 3736
diff changeset
89 request.translator)
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
90 try:
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
91 client.main()
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
92 except roundup.cgi.client.NotFound:
3990
0728808fdf5c make WSGI threadsafe
Richard Jones <richard@users.sourceforge.net>
parents: 3736
diff changeset
93 request.start_response([('Content-Type', 'text/html')], 404)
5800
1a835db41674 Call cgi.escape only on python 2. Replace with html.escapeif it can be
John Rouillard <rouilj@ieee.org>
parents: 5664
diff changeset
94 request.wfile.write(s2b('Not found: %s'%html_escape(client.path)))
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
95
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
96 # all body data has been written using wfile
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
97 return []
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
98
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
99 def start_response(self, headers, response_code):
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
100 """Set HTTP response code"""
4303
7aa72c31464d Fix WSGI response code (thanks Peter Pöml)
Richard Jones <richard@users.sourceforge.net>
parents: 4292
diff changeset
101 message, explain = BaseHTTPRequestHandler.responses[response_code]
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
102 self.__wfile = self.__start_response('%d %s'%(response_code,
4303
7aa72c31464d Fix WSGI response code (thanks Peter Pöml)
Richard Jones <richard@users.sourceforge.net>
parents: 4292
diff changeset
103 message), headers)
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
104
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
105 def get_wfile(self):
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
106 if self.__wfile is None:
5378
35ea9b1efc14 Python 3 preparation: "raise" syntax.
Joseph Myers <jsm@polyomino.org.uk>
parents: 4303
diff changeset
107 raise ValueError('start_response() not called')
3736
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
108 return self.__wfile
a2d22d0de0bc WSGI support via roundup.cgi.wsgi_handler
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
109

Roundup Issue Tracker: http://roundup-tracker.org/