Description
I'm trying to handle binary flies uploaded with a polymer file-upload component (https://github.com/winhowes/file-upload). On the browser side (chrome) that just sticks the file in a FormData object, so I believe the sent form is correct. I'm using
reader = aiohttp.MultipartReader.from_response(request)
first_part = yield from reader.next()
data = yield from first_part.read()
to parse it on the server side and always get a trailing CRLF added to data.
As an example, the browser sends
[...]
0100500 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 003
0100520 \0 \0 \0 \0 \0 \0 + \0 \0 \0 \0 \0 \0 \0 \0 \0
0100540 \0 \0 \0 \0 \0 \0 001 \0 \0 \0 \0 \0 \0 \0 \0 \0
0100560 \0 \0 \0 \0 \0 \0 \r \n - - - - - - W e
0100600 b K i t F o r m B o u n d a r y
0100620 9 X r p F i 8 S X a A 2 9 t P v
0100640 - - \r \n
0100644
and data (incorrectly) ends with [...]\0\0\0\0\0\0\r\n. Looking at the aiohttp tests, this is by design:
class PartReaderTestCase(TestCase):
def setUp(self):
super().setUp()
self.boundary = b'--:'
def test_next(self):
obj = aiohttp.multipart.BodyPartReader(
self.boundary, {}, Stream(b'Hello, world!\r\n--:'))
result = yield from obj.next()
self.assertEqual(b'Hello, world!\r\n', result)But that seems wrong to me, the CRLF is supposed to be part of the boundary and should NOT be included in the body part.
The relevant RFC http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html says: "NOTE: The CRLF preceding the encapsulation line is considered part of the boundary so that it is possible to have a part that does not end with a CRLF (line break). Body parts that must be considered to end with line breaks, therefore, should have two CRLFs preceding the encapsulation line, the first of which is part of the preceding body part, and the second of which is part of the encapsulation boundary."