-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Incorrect reuse of FormData on certain redirects #5577
Description
🐞 Describe the bug
If a POST request results in a redirect response with response code 307 or 308, aiohttp.client may attempt to construct another POST request with the redirected URL using the same data as the first request. If the value passed as the data argument is an instance of aiohttp.FormData, this will fail with a somewhat cryptic exception: "RuntimeError: Form data has been processed already".
💡 To Reproduce
- Send a POST request with FormData to a server that will respond with code 307 or 308
💡 Expected behavior
Instead of reconstructing the body for each request, perhaps the request body could be reused. This would also resolve #5530, which appears to have a similar root cause.
📋 Logs/tracebacks
File "--", line --, in --
async with session.post(url, data=data) as response:
File "/usr/local/lib/python3.8/dist-packages/aiohttp/client.py", line 1118, in __aenter__
self._resp = await self._coro
File "/usr/local/lib/python3.8/dist-packages/aiohttp/client.py", line 493, in _request
req = self._request_class(
File "/usr/local/lib/python3.8/dist-packages/aiohttp/client_reqrep.py", line 313, in __init__
self.update_body_from_data(data)
File "/usr/local/lib/python3.8/dist-packages/aiohttp/client_reqrep.py", line 507, in update_body_from_data
body = body()
File "/usr/local/lib/python3.8/dist-packages/aiohttp/formdata.py", line 169, in __call__
return self._gen_form_data()
File "/usr/local/lib/python3.8/dist-packages/aiohttp/formdata.py", line 133, in _gen_form_data
raise RuntimeError("Form data has been processed already")
RuntimeError: Form data has been processed already📋 Your version of the Python
$ python --version
Python 3.8.5📋 Your version of the aiohttp/yarl/multidict distributions
$ python -m pip show aiohttp
Name: aiohttp
Version: 3.7.4.post0
Summary: Async http client/server framework (asyncio)
Home-page: https://github.com/aio-libs/aiohttp
Author: Nikolay Kim
Author-email: [email protected]
License: Apache 2
Location: /usr/local/lib/python3.8/dist-packages
Requires: attrs, chardet, yarl, multidict, typing-extensions, async-timeout$ python -m pip show multidict
Version: 5.1.0
Summary: multidict implementation
Home-page: https://github.com/aio-libs/multidict
Author: Andrew Svetlov
Author-email: [email protected]
License: Apache 2
Location: /usr/local/lib/python3.8/dist-packages
Requires:
Required-by: yarl, aiohttp$ python -m pip show yarl
Name: yarl
Version: 1.6.3
Summary: Yet another URL library
Home-page: https://github.com/aio-libs/yarl/
Author: Andrew Svetlov
Author-email: [email protected]
License: Apache 2
Location: /usr/local/lib/python3.8/dist-packages
Requires: idna, multidict
Required-by: aiohttp📋 Additional context
This is a client issue.
For anyone else who has encountered this issue: Skipping the redirect by sending the original request to the redirected URL may be an adequate workaround at least in the case of a permanent redirect.