Skip to content

Commit

Permalink
Fix unquoting (#2667)
Browse files Browse the repository at this point in the history
* Fix #2662: Properly unquote path parts

* Don't requote already quoted paths

* Update dependencies
  • Loading branch information
asvetlov authored Jan 15, 2018
1 parent ad2a833 commit dd16789
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 9 deletions.
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ Changelog

.. towncrier release notes start
2.3.8 (2018-01-15)
==================

- Do not use `yarl.unquote` internal function in aiohttp. Fix
incorrectly unquoted path part in URL dispatcher (#2662)

2.3.7 (2017-12-27)
==================

Expand Down
11 changes: 6 additions & 5 deletions aiohttp/web_urldispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
from pathlib import Path
from types import MappingProxyType

# do not use yarl.quote directly,
# do not use yarl.quote/unquote directly,
# use `URL(path).raw_path` instead of `quote(path)`
# Escaping of the URLs need to be consitent with the escaping done by yarl
from yarl import URL, unquote
from yarl import URL

from . import hdrs, helpers
from .abc import AbstractMatchInfo, AbstractRouter, AbstractView
Expand Down Expand Up @@ -427,7 +427,7 @@ def _match(self, path):
if match is None:
return None
else:
return {key: unquote(value, unsafe='+') for key, value in
return {key: URL(value, encoded=True).path for key, value in
match.groupdict().items()}

def get_info(self):
Expand Down Expand Up @@ -559,7 +559,8 @@ def resolve(self, request):
if method not in allowed_methods:
return None, allowed_methods

match_dict = {'filename': unquote(path[len(self._prefix)+1:])}
match_dict = {'filename': URL(path[len(self._prefix)+1:],
encoded=True).path}
return (UrlMappingMatchInfo(match_dict, self._routes[method]),
allowed_methods)
yield # pragma: no cover
Expand All @@ -572,7 +573,7 @@ def __iter__(self):

@asyncio.coroutine
def _handle(self, request):
filename = unquote(request.match_info['filename'])
filename = request.match_info['filename']
try:
filepath = self._directory.joinpath(filename).resolve()
if not self._follow_symlinks:
Expand Down
4 changes: 2 additions & 2 deletions requirements/ci-wheel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ cython==0.27.1
chardet==3.0.4
isort==4.2.15
tox==2.9.1
multidict==3.3.0
multidict==4.0.0
async-timeout==2.0.0
pytest==3.2.3
pytest-cov==2.5.1
pytest-mock==1.6.3
gunicorn==19.7.1
twine==1.9.1
yarl==0.13.0
yarl==1.0.0
brotlipy==0.7.0

# Using PEP 508 env markers to control dependency on runtimes:
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ def build_extension(self, ext):
raise RuntimeError('Unable to determine version.')


install_requires = ['chardet', 'multidict>=3.0.0',
'async_timeout>=1.2.0', 'yarl>=0.11']
install_requires = ['chardet', 'multidict>=4.0.0',
'async_timeout>=1.2.0', 'yarl>=1.0.0']


def read(f):
Expand Down

0 comments on commit dd16789

Please sign in to comment.