From 0b2d2ebc04b24cfef2d9e4a9e1c7aa95dac9b05c Mon Sep 17 00:00:00 2001 From: realcr Date: Thu, 25 Feb 2016 18:06:00 +0200 Subject: [PATCH 1/6] Making sure filepath is a file. Fixes a bug when filepath is a directory. --- aiohttp/web_urldispatcher.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/aiohttp/web_urldispatcher.py b/aiohttp/web_urldispatcher.py index e7361463012..9e7b08b0026 100644 --- a/aiohttp/web_urldispatcher.py +++ b/aiohttp/web_urldispatcher.py @@ -569,6 +569,10 @@ def handle(self, request): request.logger.exception(error) raise HTTPNotFound() from error + # Make sure that filepath is a file + if not filepath.is_file(): + raise HTTPNotFound() + st = filepath.stat() modsince = request.if_modified_since From 3fd7cda9be34dd0bbf884aae8012096d3962fad3 Mon Sep 17 00:00:00 2001 From: realcr Date: Thu, 25 Feb 2016 18:28:12 +0200 Subject: [PATCH 2/6] Test for accessing the root of a statically served dir. --- tests/test_web_urldispatcher.py | 103 ++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 tests/test_web_urldispatcher.py diff --git a/tests/test_web_urldispatcher.py b/tests/test_web_urldispatcher.py new file mode 100644 index 00000000000..e4bdfef8a1b --- /dev/null +++ b/tests/test_web_urldispatcher.py @@ -0,0 +1,103 @@ +import pytest +import tempfile +import aiohttp +from aiohttp import web +import os +import shutil +import asyncio + +SERVER_HOST = '127.0.0.1' +SERVER_PORT = 8080 + +# Timeout in seconds for an asynchronous test: +ASYNC_TEST_TIMEOUT = 1 + +class ExceptAsyncTestTimeout(Exception): pass + +def run_timeout(cor,loop,timeout=ASYNC_TEST_TIMEOUT): + """ + Run a given coroutine with timeout. + """ + task_with_timeout = asyncio.wait_for(cor,timeout,loop=loop) + try: + return loop.run_until_complete(task_with_timeout) + except asyncio.futures.TimeoutError: + # Timeout: + raise ExceptAsyncTestTimeout() + + +@pytest.fixture(scope='function') +def tloop(request): + """ + Obtain a test loop. We want each test case to have its own loop. + """ + # Create a new test loop: + tloop = asyncio.new_event_loop() + asyncio.set_event_loop(None) + + def teardown(): + # Close the test loop: + tloop.close() + + request.addfinalizer(teardown) + return tloop + + +@pytest.fixture(scope='function') +def tmp_dir_path(request): + """ + Give a path for a temporary directory + The directory is destroyed at the end of the test. + """ + # Temporary directory. + tmp_dir = tempfile.mkdtemp() + + def teardown(): + # Delete the whole directory: + shutil.rmtree(tmp_dir) + + request.addfinalizer(teardown) + return tmp_dir + + +def test_access_root_of_static_handler(tloop,tmp_dir_path): + """ + Tests the operation of static file server. + Try to access the root of static file server, and make + sure that a proper not found error is returned. + """ + # Put a file inside tmp_dir_path: + my_file_path = os.path.join(tmp_dir_path,'my_file') + with open(my_file_path,'w') as fw: + fw.write('hello') + + asyncio.set_event_loop(None) + app = web.Application(loop=tloop) + # Register global static route: + app.router.add_static('/', tmp_dir_path) + + @asyncio.coroutine + def inner_cor(): + handler = app.make_handler() + srv = yield from tloop.create_server(handler,\ + SERVER_HOST,SERVER_PORT ,reuse_address=True) + + # Request the root of the static directory. + # Expect an 404 error page. + url = 'http://{}:{}/'.format(\ + SERVER_HOST,SERVER_PORT) + + r = ( yield from aiohttp.get(url,loop=tloop) ) + assert r.status == 404 + # data = (yield from r.read()) + yield from r.release() + + srv.close() + yield from srv.wait_closed() + + yield from app.shutdown() + yield from handler.finish_connections(10.0) + yield from app.cleanup() + + + run_timeout(inner_cor(),tloop,timeout=5) From 8cf3dacedc5087f31f518f7aa53883c2f497e2fd Mon Sep 17 00:00:00 2001 From: realcr Date: Fri, 26 Feb 2016 10:14:22 +0200 Subject: [PATCH 3/6] Using unused_port fixture. --- tests/test_web_urldispatcher.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_web_urldispatcher.py b/tests/test_web_urldispatcher.py index e4bdfef8a1b..e1b913bd266 100644 --- a/tests/test_web_urldispatcher.py +++ b/tests/test_web_urldispatcher.py @@ -6,9 +6,6 @@ import shutil import asyncio -SERVER_HOST = '127.0.0.1' -SERVER_PORT = 8080 - # Timeout in seconds for an asynchronous test: ASYNC_TEST_TIMEOUT = 1 @@ -60,12 +57,15 @@ def teardown(): return tmp_dir -def test_access_root_of_static_handler(tloop,tmp_dir_path): +def test_access_root_of_static_handler(tloop, tmp_dir_path, unused_port): """ Tests the operation of static file server. Try to access the root of static file server, and make sure that a proper not found error is returned. """ + SERVER_PORT = unused_port() + SERVER_HOST = 'localhost' + # Put a file inside tmp_dir_path: my_file_path = os.path.join(tmp_dir_path,'my_file') with open(my_file_path,'w') as fw: From cf9afd6e4a14c866384a6363507a4be884947cc7 Mon Sep 17 00:00:00 2001 From: realcr Date: Fri, 26 Feb 2016 10:14:48 +0200 Subject: [PATCH 4/6] Fixes to comply with flake8. --- aiohttp/web_urldispatcher.py | 2 +- tests/test_web_urldispatcher.py | 25 +++++++++++++------------ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/aiohttp/web_urldispatcher.py b/aiohttp/web_urldispatcher.py index 9e7b08b0026..d867dba440c 100644 --- a/aiohttp/web_urldispatcher.py +++ b/aiohttp/web_urldispatcher.py @@ -571,7 +571,7 @@ def handle(self, request): # Make sure that filepath is a file if not filepath.is_file(): - raise HTTPNotFound() + raise HTTPNotFound() st = filepath.stat() diff --git a/tests/test_web_urldispatcher.py b/tests/test_web_urldispatcher.py index e1b913bd266..6e36da1428b 100644 --- a/tests/test_web_urldispatcher.py +++ b/tests/test_web_urldispatcher.py @@ -9,13 +9,16 @@ # Timeout in seconds for an asynchronous test: ASYNC_TEST_TIMEOUT = 1 -class ExceptAsyncTestTimeout(Exception): pass -def run_timeout(cor,loop,timeout=ASYNC_TEST_TIMEOUT): +class ExceptAsyncTestTimeout(Exception): + pass + + +def run_timeout(cor, loop, timeout=ASYNC_TEST_TIMEOUT): """ Run a given coroutine with timeout. """ - task_with_timeout = asyncio.wait_for(cor,timeout,loop=loop) + task_with_timeout = asyncio.wait_for(cor, timeout, loop=loop) try: return loop.run_until_complete(task_with_timeout) except asyncio.futures.TimeoutError: @@ -67,8 +70,8 @@ def test_access_root_of_static_handler(tloop, tmp_dir_path, unused_port): SERVER_HOST = 'localhost' # Put a file inside tmp_dir_path: - my_file_path = os.path.join(tmp_dir_path,'my_file') - with open(my_file_path,'w') as fw: + my_file_path = os.path.join(tmp_dir_path, 'my_file') + with open(my_file_path, 'w') as fw: fw.write('hello') asyncio.set_event_loop(None) @@ -79,15 +82,14 @@ def test_access_root_of_static_handler(tloop, tmp_dir_path, unused_port): @asyncio.coroutine def inner_cor(): handler = app.make_handler() - srv = yield from tloop.create_server(handler,\ - SERVER_HOST,SERVER_PORT ,reuse_address=True) + srv = yield from tloop.create_server( + handler, SERVER_HOST, SERVER_PORT, reuse_address=True) # Request the root of the static directory. # Expect an 404 error page. - url = 'http://{}:{}/'.format(\ - SERVER_HOST,SERVER_PORT) + url = 'http://{}:{}/'.format(SERVER_HOST, SERVER_PORT) - r = ( yield from aiohttp.get(url,loop=tloop) ) + r = (yield from aiohttp.get(url, loop=tloop)) assert r.status == 404 # data = (yield from r.read()) yield from r.release() @@ -99,5 +101,4 @@ def inner_cor(): yield from handler.finish_connections(10.0) yield from app.cleanup() - - run_timeout(inner_cor(),tloop,timeout=5) + run_timeout(inner_cor(), tloop, timeout=5) From c96fe98cd5b3910b8dd09d913f8d8161ce31138f Mon Sep 17 00:00:00 2001 From: realcr Date: Fri, 26 Feb 2016 11:18:25 +0200 Subject: [PATCH 5/6] Using loop fixture. --- tests/test_web_urldispatcher.py | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/tests/test_web_urldispatcher.py b/tests/test_web_urldispatcher.py index 6e36da1428b..6fafbd88a34 100644 --- a/tests/test_web_urldispatcher.py +++ b/tests/test_web_urldispatcher.py @@ -26,23 +26,6 @@ def run_timeout(cor, loop, timeout=ASYNC_TEST_TIMEOUT): raise ExceptAsyncTestTimeout() -@pytest.fixture(scope='function') -def tloop(request): - """ - Obtain a test loop. We want each test case to have its own loop. - """ - # Create a new test loop: - tloop = asyncio.new_event_loop() - asyncio.set_event_loop(None) - - def teardown(): - # Close the test loop: - tloop.close() - - request.addfinalizer(teardown) - return tloop - - @pytest.fixture(scope='function') def tmp_dir_path(request): """ @@ -60,7 +43,7 @@ def teardown(): return tmp_dir -def test_access_root_of_static_handler(tloop, tmp_dir_path, unused_port): +def test_access_root_of_static_handler(loop, tmp_dir_path, unused_port): """ Tests the operation of static file server. Try to access the root of static file server, and make @@ -75,21 +58,21 @@ def test_access_root_of_static_handler(tloop, tmp_dir_path, unused_port): fw.write('hello') asyncio.set_event_loop(None) - app = web.Application(loop=tloop) + app = web.Application(loop=loop) # Register global static route: app.router.add_static('/', tmp_dir_path) @asyncio.coroutine def inner_cor(): handler = app.make_handler() - srv = yield from tloop.create_server( + srv = yield from loop.create_server( handler, SERVER_HOST, SERVER_PORT, reuse_address=True) # Request the root of the static directory. # Expect an 404 error page. url = 'http://{}:{}/'.format(SERVER_HOST, SERVER_PORT) - r = (yield from aiohttp.get(url, loop=tloop)) + r = (yield from aiohttp.get(url, loop=loop)) assert r.status == 404 # data = (yield from r.read()) yield from r.release() @@ -101,4 +84,4 @@ def inner_cor(): yield from handler.finish_connections(10.0) yield from app.cleanup() - run_timeout(inner_cor(), tloop, timeout=5) + run_timeout(inner_cor(), loop, timeout=5) From c93da59bb4ed3dee336d204eb2fd377ab5b2557d Mon Sep 17 00:00:00 2001 From: realcr Date: Sat, 27 Feb 2016 15:26:40 +0200 Subject: [PATCH 6/6] Using mark.run_loop and create_app_and_client. --- tests/test_web_urldispatcher.py | 63 ++++++--------------------------- 1 file changed, 11 insertions(+), 52 deletions(-) diff --git a/tests/test_web_urldispatcher.py b/tests/test_web_urldispatcher.py index 6fafbd88a34..87ca5335ea8 100644 --- a/tests/test_web_urldispatcher.py +++ b/tests/test_web_urldispatcher.py @@ -1,29 +1,7 @@ import pytest -import tempfile -import aiohttp -from aiohttp import web import os import shutil -import asyncio - -# Timeout in seconds for an asynchronous test: -ASYNC_TEST_TIMEOUT = 1 - - -class ExceptAsyncTestTimeout(Exception): - pass - - -def run_timeout(cor, loop, timeout=ASYNC_TEST_TIMEOUT): - """ - Run a given coroutine with timeout. - """ - task_with_timeout = asyncio.wait_for(cor, timeout, loop=loop) - try: - return loop.run_until_complete(task_with_timeout) - except asyncio.futures.TimeoutError: - # Timeout: - raise ExceptAsyncTestTimeout() +import tempfile @pytest.fixture(scope='function') @@ -43,45 +21,26 @@ def teardown(): return tmp_dir -def test_access_root_of_static_handler(loop, tmp_dir_path, unused_port): +@pytest.mark.run_loop +def test_access_root_of_static_handler(tmp_dir_path, create_app_and_client): """ Tests the operation of static file server. Try to access the root of static file server, and make sure that a proper not found error is returned. """ - SERVER_PORT = unused_port() - SERVER_HOST = 'localhost' - # Put a file inside tmp_dir_path: my_file_path = os.path.join(tmp_dir_path, 'my_file') with open(my_file_path, 'w') as fw: fw.write('hello') - asyncio.set_event_loop(None) - app = web.Application(loop=loop) + app, client = yield from create_app_and_client() + # Register global static route: app.router.add_static('/', tmp_dir_path) - @asyncio.coroutine - def inner_cor(): - handler = app.make_handler() - srv = yield from loop.create_server( - handler, SERVER_HOST, SERVER_PORT, reuse_address=True) - - # Request the root of the static directory. - # Expect an 404 error page. - url = 'http://{}:{}/'.format(SERVER_HOST, SERVER_PORT) - - r = (yield from aiohttp.get(url, loop=loop)) - assert r.status == 404 - # data = (yield from r.read()) - yield from r.release() - - srv.close() - yield from srv.wait_closed() - - yield from app.shutdown() - yield from handler.finish_connections(10.0) - yield from app.cleanup() - - run_timeout(inner_cor(), loop, timeout=5) + # Request the root of the static directory. + # Expect an 404 error page. + r = (yield from client.get('/')) + assert r.status == 404 + # data = (yield from r.read()) + yield from r.release()