aio-libs / aiohttp

Asynchronous HTTP client/server framework for asyncio and Python
https://docs.aiohttp.org
Other
14.98k stars 2k forks source link

request.path doesn't unquote as expected for aiohttp server #3713

Closed bmbouter closed 1 month ago

bmbouter commented 5 years ago

Long story short

The aiohttp server reference docs state the request.path attribute will be URL un-quoted.

So a url like /my+file.iso being requested by a client that performs url quoting would make a request like: GET http :8080/my%2Bfile.iso. I got this quoted url from:

>>> import urllib
>>> from urllib.parse import quote
>>> quote('my+file.iso')
'my%2Bfile.iso'
>>>

Expected behaviour

I expect the request.path to be /my+file.iso in this case.

Actual behaviour

Instead it comes in as /my%2Bfile.iso.

Steps to reproduce

from aiohttp import web

routes = web.RouteTableDef()

@routes.get('/{param:.+}')
async def hello(request):
    return web.Response(text=request.path)

app = web.Application()
app.add_routes(routes)
web.run_app(app)

Start the server then in another terminal window request the URL using httpie.

[vagrant@pulp3-source-fedora29 ~]$ http :8080/my%2Bfile.iso
HTTP/1.1 200 OK
Content-Length: 14
Content-Type: text/plain; charset=utf-8
Date: Wed, 24 Apr 2019 21:22:07 GMT
Server: Python/3.7 aiohttp/3.3.2

/my%2Bfile.iso

Your environment

server. I've tested against 3.3, 3.4, and 3.5.

asvetlov commented 5 years ago

Sorry, but your snippet works pretty fine to me. Tested against unmodified code:


$curl http://localhost:8080/file%2Bpart.jpg 
/file+part.jpg
ipanova commented 5 years ago

@asvetlov i can confirm that i can reproduce the issue as well. can you check against which version you tested ?

dkliban commented 5 years ago

I am not able to reproduce this issue. I tested on Fedora 28.

Python 3.6.5 aiohttp==3.5.4

bmbouter commented 5 years ago

I also just tested now on Fedora 28 Vanilla and I could not reproduce the issue there. There must be something wrong with the environment I was running in...

Thank you!

bmbouter commented 5 years ago

So using the latest aiohttp bits from pypi and vanilla Fedora 28 and Fedora29 images I can reproduce this on Fedora29 and I cannot reproduce this on Fedora28. Here are the environment details:

Fedora 28

(env) [vagrant@fedora28 ~]$ http :8080/my%2Bfile.iso
HTTP/1.1 200 OK
Content-Length: 12
Content-Type: text/plain; charset=utf-8
Date: Thu, 25 Apr 2019 14:41:05 GMT
Server: Python/3.6 aiohttp/3.5.4

/my+file.iso

(env) [vagrant@fedora28 ~]$ python --version
Python 3.6.5
(env) [vagrant@fedora28 ~]$ pip freeze
aiohttp==3.5.4
async-timeout==3.0.1
attrs==19.1.0
chardet==3.0.4
idna==2.8
idna-ssl==1.1.0
multidict==4.5.2
typing-extensions==3.7.2
yarl==1.3.0

Fedora 29

(env) [vagrant@fedora29 ~]$ http :8080/my%2Bfile.iso
HTTP/1.1 200 OK
Content-Length: 14
Content-Type: text/plain; charset=utf-8
Date: Thu, 25 Apr 2019 14:39:53 GMT
Server: Python/3.7 aiohttp/3.5.4

/my%2Bfile.iso

(env) [vagrant@fedora29 ~]$ python --version
Python 3.7.0
(env) [vagrant@fedora29 ~]$ pip freeze
aiohttp==3.5.4
async-timeout==3.0.1
attrs==19.1.0
chardet==3.0.4
idna==2.8
multidict==4.5.2
yarl==1.3.0

This shows the environments are using identical stacks (except an extra typing-extensions package somehow on F28). The main difference is the version of Python. @asvetlov did you try it on Python 3.7?

asvetlov commented 5 years ago

yes, sure. Python 3.7 Moreover, quoting algorithm is implemented in yarl library. It doesn't depend on Python version.

bmbouter commented 5 years ago

@asvetlov so you are saying that you tested on Python 3.7 and it is working on Python 3.7? Can you share some details about your testing environment?

bmbouter commented 5 years ago

Fedora 30 also had a problem and it's on Python 3.7.2

(env) [vagrant@fedora30 ~]$ http :8080/my%2Bfile.iso
HTTP/1.1 200 OK
Content-Length: 14
Content-Type: text/plain; charset=utf-8
Date: Thu, 25 Apr 2019 15:41:13 GMT
Server: Python/3.7 aiohttp/3.5.4

/my%2Bfile.iso

(env) [vagrant@fedora30 ~]$ python --version
Python 3.7.2
bmbouter commented 5 years ago

I opened this issue against yarl https://github.com/aio-libs/yarl/issues/304

derlih commented 3 years ago

Not reproduced on Fedora 33

$ python3 --version
Python 3.9.0
$ pip3 freeze
aiohttp==3.7.3
async-timeout==3.0.1
attrs==20.3.0
chardet==3.0.4
gpg==1.14.0
idna==2.10
libcomps==0.1.15
multidict==5.1.0
rpm==4.16.0
typing-extensions==3.7.4.3
yarl==1.6.3
Dreamsorcerer commented 1 month ago

This was fixed in yarl.