Fixed behavior for missing Content-Type in multipart parts
This commit is contained in:
parent
b453721821
commit
00bcae9874
2 changed files with 34 additions and 18 deletions
|
@ -185,6 +185,35 @@ class TestParseRequest(unittest.TestCase):
|
||||||
self.assertEqual('', args['foo'].get_str())
|
self.assertEqual('', args['foo'].get_str())
|
||||||
self.assertEqual('42', args['bar'].get_str())
|
self.assertEqual('42', args['bar'].get_str())
|
||||||
|
|
||||||
|
def test_parse_post_multipart_no_contenttype(self):
|
||||||
|
"""
|
||||||
|
Test that the Content-Type is set to 'application/octet-stream' if it is absent from the multipart header.
|
||||||
|
"""
|
||||||
|
path, args = parse_args('/',
|
||||||
|
postbody=b'--testBoundary1337\r\n'
|
||||||
|
b'Content-Disposition: form-data; name="foo"\r\n'
|
||||||
|
b'Content-Type: text/plain\r\n\r\n'
|
||||||
|
b'42\r\n'
|
||||||
|
b'--testBoundary1337\r\n'
|
||||||
|
b'Content-Disposition: form-data; name="bar"; filename="bar.bin"\r\n'
|
||||||
|
b'Content-Type: application/octet-stream\r\n\r\n'
|
||||||
|
b'1337\r\n'
|
||||||
|
b'--testBoundary1337\r\n'
|
||||||
|
b'Content-Disposition: form-data; name="baz"\r\n\r\n'
|
||||||
|
b'Hello, World!\r\n'
|
||||||
|
b'--testBoundary1337--\r\n',
|
||||||
|
enctype='multipart/form-data; boundary=testBoundary1337')
|
||||||
|
self.assertEqual('/', path)
|
||||||
|
self.assertEqual(3, len(args))
|
||||||
|
self.assertIn('foo', args)
|
||||||
|
self.assertIn('bar', args)
|
||||||
|
self.assertIn('baz', args)
|
||||||
|
self.assertTrue(args['foo'].is_scalar)
|
||||||
|
self.assertTrue(args['bar'].is_scalar)
|
||||||
|
self.assertTrue(args['baz'].is_scalar)
|
||||||
|
self.assertEqual('application/octet-stream', args['baz'].get_content_type())
|
||||||
|
self.assertEqual('Hello, World!', args['baz'].get_str())
|
||||||
|
|
||||||
def test_parse_post_multipart_broken_boundaries(self):
|
def test_parse_post_multipart_broken_boundaries(self):
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
# Boundary not defined in Content-Type
|
# Boundary not defined in Content-Type
|
||||||
|
@ -237,22 +266,6 @@ class TestParseRequest(unittest.TestCase):
|
||||||
b'Hello, World!\r\n'
|
b'Hello, World!\r\n'
|
||||||
b'--testBoundary1337\r\n',
|
b'--testBoundary1337\r\n',
|
||||||
enctype='multipart/form-data; boundary=testBoundary1337')
|
enctype='multipart/form-data; boundary=testBoundary1337')
|
||||||
with self.assertRaises(ValueError):
|
|
||||||
# Missing Content-Type header in one part
|
|
||||||
parse_args('/',
|
|
||||||
postbody=b'--testBoundary1337\r\n'
|
|
||||||
b'Content-Disposition: form-data; name="foo"\r\n'
|
|
||||||
b'Content-Type: text/plain\r\n\r\n'
|
|
||||||
b'42\r\n'
|
|
||||||
b'--testBoundary1337\r\n'
|
|
||||||
b'Content-Disposition: form-data; name="bar"; filename="bar.bin"\r\n'
|
|
||||||
b'Content-Type: application/octet-stream\r\n\r\n'
|
|
||||||
b'1337\r\n'
|
|
||||||
b'--testBoundary1337\r\n'
|
|
||||||
b'Content-Disposition: form-data; name="baz"\r\n\r\n'
|
|
||||||
b'Hello, World!\r\n'
|
|
||||||
b'--testBoundary1337--\r\n',
|
|
||||||
enctype='multipart/form-data; boundary=testBoundary1337')
|
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
# Missing Content-Disposition header in one part
|
# Missing Content-Disposition header in one part
|
||||||
parse_args('/',
|
parse_args('/',
|
||||||
|
|
|
@ -46,8 +46,11 @@ def _parse_multipart(body: bytes, boundary: str) -> List[RequestArgument]:
|
||||||
# Add header to hdr dict
|
# Add header to hdr dict
|
||||||
hk, hv = head.decode('utf-8').split(':')
|
hk, hv = head.decode('utf-8').split(':')
|
||||||
hdr[hk.strip()] = hv.strip()
|
hdr[hk.strip()] = hv.strip()
|
||||||
# At least Content-Type and Content-Disposition must be present
|
# No content type set - set broadest possible type
|
||||||
if 'Content-Type' not in hdr or 'Content-Disposition' not in hdr:
|
if 'Content-Type' not in hdr:
|
||||||
|
hdr['Content-Type'] = 'application/octet-stream'
|
||||||
|
# At least Content-Disposition must be present
|
||||||
|
if 'Content-Disposition' not in hdr:
|
||||||
raise ValueError('Missing Content-Type or Content-Disposition header')
|
raise ValueError('Missing Content-Type or Content-Disposition header')
|
||||||
# Extract Content-Disposition header value and its arguments
|
# Extract Content-Disposition header value and its arguments
|
||||||
cd, *cdargs = hdr['Content-Disposition'].split(';')
|
cd, *cdargs = hdr['Content-Disposition'].split(';')
|
||||||
|
|
Loading…
Reference in a new issue