comparison 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
comparison
equal deleted inserted replaced
5655:207e0f5d551c 5656:d26d2590cd8c
228 self.session_db.commit() 228 self.session_db.commit()
229 229
230 if set_cookie: 230 if set_cookie:
231 self.client.add_cookie(self.cookie_name, self._sid, expire=expire) 231 self.client.add_cookie(self.cookie_name, self._sid, expire=expire)
232 232
233 233 class BinaryFieldStorage(cgi.FieldStorage):
234 '''This class works around the bug https://bugs.python.org/issue27777.
235
236 cgi.FieldStorage must save all data as binary/bytes. This is
237 needed for handling json and xml data blobs under python
238 3. Under python 2, str and binary are interchangable, not so
239 under 3.
240 '''
241 def make_file(self, mode=None):
242 ''' work around https://bugs.python.org/issue27777 '''
243 import tempfile
244 return tempfile.TemporaryFile("wb+")
234 245
235 class Client: 246 class Client:
236 """Instantiate to handle one CGI request. 247 """Instantiate to handle one CGI request.
237 248
238 See inner_main for request processing. 249 See inner_main for request processing.
374 self.env['CONTENT_LENGTH'] = 0 385 self.env['CONTENT_LENGTH'] = 0
375 logger.debug("Setting CONTENT_LENGTH to 0 for method: %s", 386 logger.debug("Setting CONTENT_LENGTH to 0 for method: %s",
376 self.env['REQUEST_METHOD']) 387 self.env['REQUEST_METHOD'])
377 388
378 # cgi.FieldStorage must save all data as 389 # cgi.FieldStorage must save all data as
379 # binary/bytes. This is needed for handling json and xml 390 # binary/bytes. Subclass BinaryFieldStorage does this.
380 # data blobs under python 3. Under python 2, str and binary 391 # It's a workaround for a bug in cgi.FieldStorage. See class
381 # are interchangable, not so under 3. 392 # def for details.
382 def make_file(self): 393 self.form = BinaryFieldStorage(fp=request.rfile, environ=env)
383 ''' work around https://bugs.python.org/issue27777 '''
384 import tempfile
385 return tempfile.TemporaryFile("wb+")
386
387 saved_make_file = cgi.FieldStorage.make_file
388 cgi.FieldStorage.make_file = make_file
389 self.form = cgi.FieldStorage(fp=request.rfile, environ=env)
390 cgi.FieldStorage.make_file = saved_make_file
391 # In some case (e.g. content-type application/xml), cgi 394 # In some case (e.g. content-type application/xml), cgi
392 # will not parse anything. Fake a list property in this case 395 # will not parse anything. Fake a list property in this case
393 if self.form.list is None: 396 if self.form.list is None:
394 self.form.list = [] 397 self.form.list = []
395 else: 398 else:

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