Fix FormPOST max_file_size exceeded bug.

When using FormPOST, if the size of the file being posted exceeds
max_file_size, a HTTP 499 was being returned rather than HTTP 400.

Change-Id: I48c781735c66eccde3deb6f9c3c184aee964a4a5
This commit is contained in:
Richard (Rick) Hawkins 2014-09-08 13:51:07 -05:00
parent f436da3b9b
commit d2a94bd43c
2 changed files with 37 additions and 24 deletions

View File

@ -278,11 +278,13 @@ class _CappedFileLikeObject(object):
self.fp = fp self.fp = fp
self.max_file_size = max_file_size self.max_file_size = max_file_size
self.amount_read = 0 self.amount_read = 0
self.file_size_exceeded = False
def read(self, size=None): def read(self, size=None):
ret = self.fp.read(size) ret = self.fp.read(size)
self.amount_read += len(ret) self.amount_read += len(ret)
if self.amount_read > self.max_file_size: if self.amount_read > self.max_file_size:
self.file_size_exceeded = True
raise EOFError('max_file_size exceeded') raise EOFError('max_file_size exceeded')
return ret return ret
@ -290,6 +292,7 @@ class _CappedFileLikeObject(object):
ret = self.fp.readline() ret = self.fp.readline()
self.amount_read += len(ret) self.amount_read += len(ret)
if self.amount_read > self.max_file_size: if self.amount_read > self.max_file_size:
self.file_size_exceeded = True
raise EOFError('max_file_size exceeded') raise EOFError('max_file_size exceeded')
return ret return ret
@ -334,7 +337,7 @@ class FormPost(object):
status, headers, body = self._translate_form( status, headers, body = self._translate_form(
env, attrs['boundary']) env, attrs['boundary'])
start_response(status, headers) start_response(status, headers)
return body return [body]
except (FormInvalid, EOFError) as err: except (FormInvalid, EOFError) as err:
body = 'FormPost: %s' % err body = 'FormPost: %s' % err
start_response( start_response(
@ -492,7 +495,12 @@ class FormPost(object):
substatus = [None] substatus = [None]
subheaders = [None] subheaders = [None]
wsgi_input = subenv['wsgi.input']
def _start_response(status, headers, exc_info=None): def _start_response(status, headers, exc_info=None):
if wsgi_input.file_size_exceeded:
raise EOFError("max_file_size exceeded")
substatus[0] = status substatus[0] = status
subheaders[0] = headers subheaders[0] = headers

View File

@ -38,6 +38,7 @@ class FakeApp(object):
self.check_no_query_string = check_no_query_string self.check_no_query_string = check_no_query_string
def __call__(self, env, start_response): def __call__(self, env, start_response):
try:
if self.check_no_query_string and env.get('QUERY_STRING'): if self.check_no_query_string and env.get('QUERY_STRING'):
raise Exception('Query string %s should have been discarded!' % raise Exception('Query string %s should have been discarded!' %
env['QUERY_STRING']) env['QUERY_STRING'])
@ -61,6 +62,10 @@ class FakeApp(object):
status, headers, body = self.status_headers_body_iter.next() status, headers, body = self.status_headers_body_iter.next()
return Response(status=status, headers=headers, return Response(status=status, headers=headers,
body=body)(env, start_response) body=body)(env, start_response)
except EOFError:
start_response('499 Client Disconnect',
[('Content-Type', 'text/plain')])
return ['Client Disconnect\n']
class TestParseAttrs(unittest.TestCase): class TestParseAttrs(unittest.TestCase):