diff roundup/cgi/client.py @ 5656:d26d2590cd8c

Implement different workaround for https://bugs.python.org/issue27777 suggested by jsm/Joseph Myers. Subclass cgi.FieldStorage into BinaryFieldStorage and use that class rather then monkey patching cgi.FieldStorage.make_file. This should eliminate race conditions issues inherent with the prior way I tried to do it by flipping the class method back and forth at runtime. Also import new class into rest_common.py and use it in place of old mechanism.
author John Rouillard <rouilj@ieee.org>
date Tue, 19 Mar 2019 21:58:49 -0400
parents 207e0f5d551c
children 7e1b2a723253
line wrap: on
line diff
--- a/roundup/cgi/client.py	Mon Mar 18 21:42:33 2019 -0400
+++ b/roundup/cgi/client.py	Tue Mar 19 21:58:49 2019 -0400
@@ -230,7 +230,18 @@
         if set_cookie:
             self.client.add_cookie(self.cookie_name, self._sid, expire=expire)
 
+class BinaryFieldStorage(cgi.FieldStorage):
+    '''This class works around the bug https://bugs.python.org/issue27777.
 
+       cgi.FieldStorage must save all data as binary/bytes. This is
+       needed for handling json and xml data blobs under python
+       3. Under python 2, str and binary are interchangable, not so
+       under 3.
+    '''
+    def make_file(self, mode=None):
+        ''' work around https://bugs.python.org/issue27777 '''
+        import tempfile
+        return tempfile.TemporaryFile("wb+")
 
 class Client:
     """Instantiate to handle one CGI request.
@@ -376,18 +387,10 @@
                                 self.env['REQUEST_METHOD'])
 
             # cgi.FieldStorage must save all data as
-            # binary/bytes. This is needed for handling json and xml
-            # data blobs under python 3. Under python 2, str and binary
-            # are interchangable, not so under 3.
-            def make_file(self):
-                ''' work around https://bugs.python.org/issue27777 '''
-                import tempfile
-                return tempfile.TemporaryFile("wb+")
-
-            saved_make_file = cgi.FieldStorage.make_file
-            cgi.FieldStorage.make_file = make_file
-            self.form = cgi.FieldStorage(fp=request.rfile, environ=env)
-            cgi.FieldStorage.make_file = saved_make_file
+            # binary/bytes. Subclass BinaryFieldStorage does this.
+            # It's a workaround for a bug in cgi.FieldStorage. See class
+            # def for details.
+            self.form = BinaryFieldStorage(fp=request.rfile, environ=env)
             # In some case (e.g. content-type application/xml), cgi
             # will not parse anything. Fake a list property in this case
             if self.form.list is None:

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