From f9b73885bebbe6f205a99e2bb925d46ffd1a334b Mon Sep 17 00:00:00 2001 From: David Glick Date: Tue, 26 Jun 2018 22:09:55 +0200 Subject: [PATCH] We need a different approach to preserve query string parameters --- src/ZPublisher/HTTPRequest.py | 29 ++++++++++--------------- src/ZPublisher/tests/testHTTPRequest.py | 13 +++++++++++ 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/ZPublisher/HTTPRequest.py b/src/ZPublisher/HTTPRequest.py index cead939268..80329bf7be 100644 --- a/src/ZPublisher/HTTPRequest.py +++ b/src/ZPublisher/HTTPRequest.py @@ -497,23 +497,8 @@ def processInputs( environ['QUERY_STRING'] = '' meth = None - - # Workaround for https://bugs.python.org/issue27777: - # If Content-Length is nonzero, manufacture a Content-Disposition - # with a filename to make sure a binary file is opened. - headers = None - if 'CONTENT_LENGTH' in environ and environ['CONTENT_LENGTH'] != '0': - # In order to override content-disposition we need to - # specify the full headers; this is based on FileStorage.__init__ - headers = { - 'content-type': 'application/x-www-form-urlencoded' - } - if 'CONTENT_TYPE' in environ: - headers['content-type'] = environ['CONTENT_TYPE'] - headers['content-length'] = environ['CONTENT_LENGTH'] - headers['content-disposition'] = 'inline; filename="stdin"' - fs = FieldStorage( - fp=fp, headers=headers, environ=environ, keep_blank_values=1) + fs = ZopeFieldStorage( + fp=fp, environ=environ, keep_blank_values=1) # Keep a reference to the FieldStorage. Otherwise it's # __del__ method is called too early and closing FieldStorage.file. @@ -1643,7 +1628,15 @@ def sane_environment(env): return dict -ZopeFieldStorage = FieldStorage # BBB +class ZopeFieldStorage(FieldStorage): + """This subclass exists to work around a Python bug + (see https://bugs.python.org/issue27777) to make sure + we can read binary data from a request body. + """ + + def read_binary(self): + self._binary_file = True + return super(ZopeFieldStorage, self).read_binary() # Original version: zope.publisher.browser.FileUpload diff --git a/src/ZPublisher/tests/testHTTPRequest.py b/src/ZPublisher/tests/testHTTPRequest.py index 5b72e400fa..696c8933a2 100644 --- a/src/ZPublisher/tests/testHTTPRequest.py +++ b/src/ZPublisher/tests/testHTTPRequest.py @@ -778,6 +778,19 @@ def test_processInputs_xmlrpc(self): self.assertEqual(req.PATH_INFO, '/test') self.assertEqual(req.args, ()) + def test_processInputs_w_urlencoded_and_qs(self): + body = b'foo=1' + environ = { + 'CONTENT_TYPE': 'application/x-www-form-urlencoded', + 'CONTENT_LENGTH': len(body), + 'QUERY_STRING': 'bar=2', + 'REQUEST_METHOD': 'POST', + } + req = self._makeOne(stdin=BytesIO(body), environ=environ) + req.processInputs() + self.assertEqual(req.form['foo'], '1') + self.assertEqual(req.form['bar'], '2') + def test_postProcessInputs(self): from ZPublisher.HTTPRequest import default_encoding