Merge branch 'trunk' into 9496-names-traceback
This commit is contained in:
commit
fecfc159fe
|
@ -873,7 +873,8 @@ class Request:
|
|||
@type version: C{bytes}
|
||||
@param version: The HTTP version of this request.
|
||||
"""
|
||||
self.content.seek(0,0)
|
||||
clength = self.content.tell()
|
||||
self.content.seek(0, 0)
|
||||
self.args = {}
|
||||
|
||||
self.method, self.uri = command, path
|
||||
|
@ -889,16 +890,16 @@ class Request:
|
|||
# Argument processing
|
||||
args = self.args
|
||||
ctype = self.requestHeaders.getRawHeaders(b'content-type')
|
||||
clength = self.requestHeaders.getRawHeaders(b'content-length')
|
||||
if ctype is not None:
|
||||
ctype = ctype[0]
|
||||
|
||||
if clength is not None:
|
||||
clength = clength[0]
|
||||
|
||||
if self.method == b"POST" and ctype and clength:
|
||||
mfd = b'multipart/form-data'
|
||||
key, pdict = _parseHeader(ctype)
|
||||
# This weird CONTENT-LENGTH param is required by
|
||||
# cgi.parse_multipart() in some versions of Python 3.7+, see
|
||||
# bpo-29979. It looks like this will be relaxed and backported, see
|
||||
# https://github.com/python/cpython/pull/8530.
|
||||
pdict["CONTENT-LENGTH"] = clength
|
||||
if key == b'application/x-www-form-urlencoded':
|
||||
args.update(parse_qs(self.content.read(), 1))
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
twisted.web.http.Request now correctly parses multipart-encoded form data submitted as a chunked request on Python 3.7+.
|
|
@ -1426,6 +1426,73 @@ class ChunkingTests(unittest.TestCase, ResponseTestMixin):
|
|||
b"Transfer-Encoding: chunked",
|
||||
b"5\r\nHello\r\n6\r\nWorld!\r\n")])
|
||||
|
||||
def runChunkedRequest(self, httpRequest, requestFactory=None,
|
||||
chunkSize=1):
|
||||
"""
|
||||
Execute a web request based on plain text content, chunking
|
||||
the request payload.
|
||||
|
||||
This is a stripped-down, chunking version of ParsingTests.runRequest.
|
||||
"""
|
||||
channel = http.HTTPChannel()
|
||||
|
||||
if requestFactory:
|
||||
channel.requestFactory = _makeRequestProxyFactory(requestFactory)
|
||||
|
||||
httpRequest = httpRequest.replace(b"\n", b"\r\n")
|
||||
header, body = httpRequest.split(b"\r\n\r\n", 1)
|
||||
|
||||
transport = StringTransport()
|
||||
|
||||
channel.makeConnection(transport)
|
||||
channel.dataReceived(header+b"\r\n\r\n")
|
||||
|
||||
for pos in range(len(body)//chunkSize+1):
|
||||
if channel.transport.disconnecting:
|
||||
break
|
||||
channel.dataReceived(b"".join(
|
||||
http.toChunk(body[pos*chunkSize:(pos+1)*chunkSize])))
|
||||
|
||||
channel.dataReceived(b"".join(http.toChunk(b"")))
|
||||
channel.connectionLost(IOError("all done"))
|
||||
|
||||
return channel
|
||||
|
||||
def test_multipartFormData(self):
|
||||
"""
|
||||
Test that chunked uploads are actually processed into args.
|
||||
|
||||
This is essentially a copy of ParsingTests.test_multipartFormData,
|
||||
just with chunking put in.
|
||||
|
||||
This fails as of twisted version 18.9.0 because of bug #9678.
|
||||
"""
|
||||
processed = []
|
||||
|
||||
class MyRequest(http.Request):
|
||||
def process(self):
|
||||
processed.append(self)
|
||||
self.write(b"done")
|
||||
self.finish()
|
||||
req = b'''\
|
||||
POST / HTTP/1.0
|
||||
Content-Type: multipart/form-data; boundary=AaB03x
|
||||
Transfer-Encoding: chunked
|
||||
|
||||
--AaB03x
|
||||
Content-Type: text/plain
|
||||
Content-Disposition: form-data; name="text"
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
abasdfg
|
||||
--AaB03x--
|
||||
'''
|
||||
channel = self.runChunkedRequest(req, MyRequest, chunkSize=5)
|
||||
self.assertEqual(channel.transport.value(),
|
||||
b"HTTP/1.0 200 OK\r\n\r\ndone")
|
||||
self.assertEqual(len(processed), 1)
|
||||
self.assertEqual(processed[0].args, {b"text": [b"abasdfg"]})
|
||||
|
||||
|
||||
|
||||
class ParsingTests(unittest.TestCase):
|
||||
|
|
6
tox.ini
6
tox.ini
|
@ -48,9 +48,9 @@ extras =
|
|||
deps =
|
||||
py27-alldeps-{posix,macos}: pysqlite
|
||||
|
||||
; Coverage 5.0 does not work with codecov.
|
||||
{withcov}: coverage<5.0
|
||||
{coverage-prepare,codecov-publish}: coverage<5.0
|
||||
{withcov}: coverage
|
||||
|
||||
{coverage-prepare,codecov-publish}: coverage
|
||||
|
||||
{codecov-push,codecov-publish}: codecov
|
||||
|
||||
|
|
Loading…
Reference in New Issue