Repository: aio-libs/aiohttp

Issue:
StaticRoute should unquote filename
## Long story short

If I don't have web safe filenames (say I have a directory index), my browser turns "Darby uses the computer.jpg" into "Darby%20uses%20the%20computer.jpg", which StaticRoute will never find on the filesystem.
## Expected behaviour

I expect to see ![](https://c4.staticflickr.com/4/3065/2374224571_1d6b0bba2a_m.jpg)
## Actual behaviour

I get a 404 instead of a corgi.
## Steps to reproduce

Take an existing static route with a working image. Add a space to the image, then add the same space to your url. That's not that helpful, but in the code, this change gets images to load again for me. I can attempt to turn it into a pull request, but not this week.

```
$ git rev-parse HEAD
671617dc4a343c18a26831c8941fd55b844ed977
```

``` patch
diff --git a/aiohttp/web_urldispatcher.py b/aiohttp/web_urldispatcher.py
index 7b288fe..236701a 100644
--- a/aiohttp/web_urldispatcher.py
+++ b/aiohttp/web_urldispatcher.py
@@ -479,7 +479,7 @@ class StaticRoute(Route):

     @asyncio.coroutine
     def handle(self, request):
-        filename = request.match_info['filename']
+        filename = unquote(request.match_info['filename'])
         try:
             filepath = self._directory.joinpath(filename).resolve()
             filepath.relative_to(self._directory)
```
## Your environment

Python 3.5.0+
aiohttp==0.22.5



Discussion:
Agree with the problem but let's postpone the issue to 'after 1.0' times.


Resolving patch:
diff --git a/aiohttp/web_urldispatcher.py b/aiohttp/web_urldispatcher.py
--- a/aiohttp/web_urldispatcher.py
+++ b/aiohttp/web_urldispatcher.py
@@ -479,7 +479,7 @@ def get_info(self):
 
     @asyncio.coroutine
     def handle(self, request):
-        filename = request.match_info['filename']
+        filename = unquote(request.match_info['filename'])
         try:
             filepath = self._directory.joinpath(filename).resolve()
             filepath.relative_to(self._directory)


Test patch:
diff --git a/tests/test_web_urldispatcher.py b/tests/test_web_urldispatcher.py
--- a/tests/test_web_urldispatcher.py
+++ b/tests/test_web_urldispatcher.py
@@ -75,6 +75,39 @@ def test_access_root_of_static_handler(tmp_dir_path, create_app_and_client,
     yield from r.release()
 
 
+@pytest.mark.parametrize('dir_name,filename,data', [
+    ('', 'test file.txt', 'test text'),
+    ('test dir name', 'test dir file .txt', 'test text file folder')
+])
+@asyncio.coroutine
+def test_access_to_the_file_with_spaces(tmp_dir_path, create_app_and_client,
+                                        dir_name, filename, data):
+    """
+    Checks operation of static files with spaces
+    """
+
+    my_dir_path = os.path.join(tmp_dir_path, dir_name)
+
+    if dir_name:
+        os.mkdir(my_dir_path)
+
+    my_file_path = os.path.join(my_dir_path, filename)
+
+    with open(my_file_path, 'w') as fw:
+        fw.write(data)
+
+    app, client = yield from create_app_and_client()
+
+    url = os.path.join('/', dir_name, filename)
+
+    app.router.add_static('/', tmp_dir_path)
+
+    r = yield from client.get(url)
+    assert r.status == 200
+    assert (yield from r.text()) == data
+    yield from r.release()
+
+
 @asyncio.coroutine
 def test_access_non_existing_resource(tmp_dir_path, create_app_and_client):
     """