aiohttp
aiohttp copied to clipboard
Client sends body after being redirected
Describe the bug
aiohttp keeps sending the body every time it's redirected.
To Reproduce
- Send body data via a GET request
- Site acknowledges data and redirects the client
- After redirection, aiohttp sends the body again
Expected behavior
aiohttp shouldn't send the body after being redirected. At the very least requests
doesn't behave in this way and avoids sending the body a second time.
Logs/tracebacks
Minimum reproducible code:
import asyncio
import json
import aiohttp
headers = {'Content-Type': 'application/json'}
data = {
"tags": "rating:general chibi",
"random": True
}
async def main():
async with aiohttp.ClientSession() as session:
async with session.get("https://danbooru.donmai.us/posts.json", data=json.dumps(data), headers=headers) as response:
response_payload = await response.read()
print(response.status)
print(response_payload)
asyncio.run(main())
Traceback (most recent call last):
File "/home/luni3359/.local/share/pyenv/versions/3.10.4/lib/python3.10/runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/home/luni3359/.local/share/pyenv/versions/3.10.4/lib/python3.10/runpy.py", line 86, in _run_code
exec(code, run_globals)
File "/home/luni3359/.vscode/extensions/ms-python.python-2022.6.2/pythonFiles/lib/python/debugpy/__main__.py", line 45, in <module>
cli.main()
File "/home/luni3359/.vscode/extensions/ms-python.python-2022.6.2/pythonFiles/lib/python/debugpy/../debugpy/server/cli.py", line 444, in main
run()
File "/home/luni3359/.vscode/extensions/ms-python.python-2022.6.2/pythonFiles/lib/python/debugpy/../debugpy/server/cli.py", line 285, in run_file
runpy.run_path(target_as_str, run_name=compat.force_str("__main__"))
File "/home/luni3359/.local/share/pyenv/versions/3.10.4/lib/python3.10/runpy.py", line 269, in run_path
return _run_module_code(code, init_globals, run_name,
File "/home/luni3359/.local/share/pyenv/versions/3.10.4/lib/python3.10/runpy.py", line 96, in _run_module_code
_run_code(code, mod_globals, init_globals,
File "/home/luni3359/.local/share/pyenv/versions/3.10.4/lib/python3.10/runpy.py", line 86, in _run_code
exec(code, run_globals)
File "/home/luni3359/Projects/Python/koa-bot/tests/booru_search_async.py", line 19, in <module>
asyncio.run(main())
File "/home/luni3359/.local/share/pyenv/versions/3.10.4/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/home/luni3359/.local/share/pyenv/versions/3.10.4/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
return future.result()
File "/home/luni3359/Projects/Python/koa-bot/tests/booru_search_async.py", line 14, in main
async with session.get("https://danbooru.donmai.us/posts.json", data=json.dumps(data), headers=headers) as response:
File "/home/luni3359/.local/share/pyenv/versions/koa-bot/lib/python3.10/site-packages/aiohttp/client.py", line 1138, in __aenter__
self._resp = await self._coro
File "/home/luni3359/.local/share/pyenv/versions/koa-bot/lib/python3.10/site-packages/aiohttp/client.py", line 585, in _request
raise TooManyRedirects(
aiohttp.client_exceptions.TooManyRedirects: 0, message='', url=URL('https://danbooru.donmai.us/posts.json')
Python Version
$ python --version
Python 3.10.4
aiohttp Version
$ python -m pip show aiohttp
Name: aiohttp
Version: 3.8.1
Summary: Async http client/server framework (asyncio)
Home-page: https://github.com/aio-libs/aiohttp
Author:
Author-email:
License: Apache 2
Location: /home/luni3359/.local/share/pyenv/versions/3.10.4/envs/koa-bot/lib/python3.10/site-packages
Requires: aiosignal, async-timeout, attrs, charset-normalizer, frozenlist, multidict, yarl
Required-by: asyncprawcore, discord.py, PixivPy-Async
multidict Version
$ python -m pip show multidict
Name: multidict
Version: 6.0.2
Summary: multidict implementation
Home-page: https://github.com/aio-libs/multidict
Author: Andrew Svetlov
Author-email: [email protected]
License: Apache 2
Location: /home/luni3359/.local/share/pyenv/versions/3.10.4/envs/koa-bot/lib/python3.10/site-packages
Requires:
Required-by: aiohttp, yarl
yarl Version
$ python -m pip show yarl
Name: yarl
Version: 1.7.2
Summary: Yet another URL library
Home-page: https://github.com/aio-libs/yarl/
Author: Andrew Svetlov
Author-email: [email protected]
License: Apache 2
Location: /home/luni3359/.local/share/pyenv/versions/3.10.4/envs/koa-bot/lib/python3.10/site-packages
Requires: idna, multidict
Required-by: aiohttp, asyncprawcore
OS
`..---+/---..` luni3359@souryuu
`---.`` `` `.---.` ----------------
.--.` `` `-:-. OS: KDE neon 20.04 (User Edition) [x86_64]
`:/: `.----//----.` :/- Host: 81Y6 Lenovo Legion 5 15IMH05H
.:. `---` `--.` .:` Kernel: 5.13.0-44-generic
.:` `--` .:- `:. Uptime: 1 day, 13 hours, 56 mins
`/ `:. `.-::-.` -:` `/` Packages: 2834 (dpkg), 15 (flatpak), 6 (snap)
/. /. `:++++++++:` .: .: Shell: bash 5.0.17
`/ .: `+++++++++++/ /` `+` Resolution: 1920x1080 @ 120Hz
/+` -- .++++++++++++` :. .+: DE: KDE Plasma 5.24.5
`/ .: `+++++++++++/ /` `+` WM: KWin (X11)
/` /. `:++++++++:` .: .: WM Theme: Breeze
./ `:. `.:::-.` -:` `/` Theme: Breeze (Dark) [Plasma], Breeze [GTK3]
.:` `--` .:- `:. Icons: breeze-dark [Plasma], breeze-dark [GTK2/3/4]
.:. `---` `--.` .:` Font: Noto Sans (10pt) [Plasma], Noto Sans (10pt) ]
`:/: `.----//----.` :/- Cursor: breeze (24px)
.-:.` `` `-:-. Terminal: konsole
`---.`` `` `.---.` CPU: Intel Core i5-10300H (8) @ 2.5GHz
`..---+/---..` GPU 1: Intel UHD Graphics
GPU 2: Nvidia GeForce GTX 1660 Ti Mobile
Memory: 11430MiB / 15870MiB (72%)
Related component
Client
Additional context
As far as I understand aiohttp shouldn't send the body after being redirected.
On danbooru/danbooru#5185 it was found out that aiohttp was behaving differently and was not being consistent with the behavior of other clients.
I'm not very well-versed in this topic so I apologize beforehand if I messed up the terminology but I can see the discrepancy. Please let me know if there's anything else that needs to be included in the issue.
Code of Conduct
- [X] I agree to follow the aio-libs Code of Conduct
I can't see any clear rules for this in the HTTP specifications.
I suspect that at the very least, a redirect that is meant to retain the same method (e.g. 307) should resend the payload. Maybe the codes which allow changing to GET should drop the payload (e.g 303). Which brings up the question of what redirect code they are using?
its using 302 redirect. redirects are keeping cookies and auth tokens, you can see that is a huge security risk
The same issue actually with auth
when redirecting to different origin. During the redirect, the authorization is reset in the https://github.com/aio-libs/aiohttp/blob/master/aiohttp/client.py#L601, but if the auth
parameter is passed to the ClientSession
, then the authorization will be reassigned in https://github.com/aio-libs/aiohttp/blob/master/aiohttp/client.py#L440
???????????