Skip to content

Commit c414430

Browse files
committed
Fix expect header handling for not found and not allowed routes #340
1 parent 94a5a68 commit c414430

File tree

4 files changed

+76
-12
lines changed

4 files changed

+76
-12
lines changed

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ CHANGES
66

77
- Fix graceful shutdown handling.
88

9+
- Fix `Expect` header handling for not found and not allowed routes #340
10+
911

1012
0.15.2 (04-19-2015)
1113
-------------------

aiohttp/web_urldispatcher.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -205,19 +205,29 @@ def __repr__(self):
205205
directory=self._directory)
206206

207207

208+
class SystemRoute(Route):
209+
210+
def __init__(self, name):
211+
super().__init__(hdrs.METH_ANY, None, name)
212+
213+
def url(self, **kwargs):
214+
return ''
215+
216+
def match(self, path):
217+
return None
218+
219+
208220
class _NotFoundMatchInfo(UrlMappingMatchInfo):
209221

222+
route = SystemRoute('')
223+
210224
def __init__(self):
211225
super().__init__({}, None)
212226

213227
@property
214228
def handler(self):
215229
return self._not_found
216230

217-
@property
218-
def route(self):
219-
return None
220-
221231
@asyncio.coroutine
222232
def _not_found(self, request):
223233
raise HTTPNotFound()
@@ -228,6 +238,8 @@ def __repr__(self):
228238

229239
class _MethodNotAllowedMatchInfo(UrlMappingMatchInfo):
230240

241+
route = SystemRoute('')
242+
231243
def __init__(self, method, allowed_methods):
232244
super().__init__({}, None)
233245
self._method = method
@@ -237,10 +249,6 @@ def __init__(self, method, allowed_methods):
237249
def handler(self):
238250
return self._not_allowed
239251

240-
@property
241-
def route(self):
242-
return None
243-
244252
@asyncio.coroutine
245253
def _not_allowed(self, request):
246254
raise HTTPMethodNotAllowed(self._method, self._allowed_methods)

tests/test_urldispatch.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
from aiohttp.protocol import HttpVersion, RawRequestMessage
1111
from aiohttp.web_urldispatcher import (_defaultExpectHandler,
1212
DynamicRoute,
13-
PlainRoute)
13+
PlainRoute,
14+
SystemRoute)
1415

1516

1617
class TestUrlDispatcher(unittest.TestCase):
@@ -43,6 +44,11 @@ def handler(request):
4344

4445
return handler
4546

47+
def test_system_route(self):
48+
route = SystemRoute('test')
49+
self.assertIsNone(route.match('any'))
50+
self.assertEqual(route.url(), '')
51+
4652
def test_register_route(self):
4753
handler = self.make_handler()
4854
route = PlainRoute('GET', handler, 'test', '/handler/to/path')
@@ -181,7 +187,7 @@ def test_raise_method_not_allowed(self):
181187
req = self.make_request('PUT', '/')
182188

183189
match_info = self.loop.run_until_complete(self.router.resolve(req))
184-
self.assertIsNone(match_info.route)
190+
self.assertIsInstance(match_info.route, SystemRoute)
185191
self.assertEqual({}, match_info)
186192

187193
with self.assertRaises(HTTPMethodNotAllowed) as ctx:
@@ -198,7 +204,7 @@ def test_raise_method_not_found(self):
198204
req = self.make_request('GET', '/b')
199205

200206
match_info = self.loop.run_until_complete(self.router.resolve(req))
201-
self.assertIsNone(match_info.route)
207+
self.assertIsInstance(match_info.route, SystemRoute)
202208
self.assertEqual({}, match_info)
203209

204210
with self.assertRaises(HTTPNotFound) as ctx:
@@ -359,7 +365,7 @@ def test_add_route_with_re_not_match(self):
359365

360366
req = self.make_request('GET', '/handler/tail')
361367
match_info = self.loop.run_until_complete(self.router.resolve(req))
362-
self.assertIsNone(match_info.route)
368+
self.assertIsInstance(match_info.route, SystemRoute)
363369
self.assertEqual({}, match_info)
364370
with self.assertRaises(HTTPNotFound):
365371
self.loop.run_until_complete(match_info.handler(req))

tests/test_web_functional.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,54 @@ def go():
469469

470470
self.loop.run_until_complete(go())
471471

472+
def test_100_continue_for_not_found(self):
473+
474+
@asyncio.coroutine
475+
def handler(request):
476+
return web.Response()
477+
478+
@asyncio.coroutine
479+
def go():
480+
app, _, url = yield from self.create_server('POST', '/')
481+
app.router.add_route('POST', '/', handler)
482+
483+
form = FormData()
484+
form.add_field('name', b'123',
485+
content_transfer_encoding='base64')
486+
487+
resp = yield from request(
488+
'post', url + 'not_found', data=form,
489+
expect100=True, # wait until server returns 100 continue
490+
loop=self.loop)
491+
492+
self.assertEqual(404, resp.status)
493+
494+
self.loop.run_until_complete(go())
495+
496+
def test_100_continue_for_not_allowed(self):
497+
498+
@asyncio.coroutine
499+
def handler(request):
500+
return web.Response()
501+
502+
@asyncio.coroutine
503+
def go():
504+
app, _, url = yield from self.create_server('POST', '/')
505+
app.router.add_route('POST', '/', handler)
506+
507+
form = FormData()
508+
form.add_field('name', b'123',
509+
content_transfer_encoding='base64')
510+
511+
resp = yield from request(
512+
'GET', url, data=form,
513+
expect100=True, # wait until server returns 100 continue
514+
loop=self.loop)
515+
516+
self.assertEqual(405, resp.status)
517+
518+
self.loop.run_until_complete(go())
519+
472520
def test_http10_keep_alive_default(self):
473521

474522
@asyncio.coroutine

0 commit comments

Comments
 (0)