diff options
author | Ryan Petrello <lists@ryanpetrello.com> | 2014-06-26 10:11:44 -0400 |
---|---|---|
committer | Ryan Petrello <lists@ryanpetrello.com> | 2014-06-26 10:22:08 -0400 |
commit | 63d9d3d8fdab69323010ace0f05ddfe10cae41f1 (patch) | |
tree | 822f164cd6ce7c6cba6f4f774dd251aa7824edaa /pecan | |
parent | 7d5b94e2f68aa254d4905e90572aa7dc5e04ab28 (diff) | |
download | pecan-63d9d3d8fdab69323010ace0f05ddfe10cae41f1.tar.gz |
For an HTTP 405 on generic methods, attempt to specify an Allow header.
Change-Id: I726d698fc014c21cc1e43a09a129384fa1f1235f
Diffstat (limited to 'pecan')
-rw-r--r-- | pecan/core.py | 6 | ||||
-rw-r--r-- | pecan/decorators.py | 2 | ||||
-rw-r--r-- | pecan/tests/test_generic.py | 25 |
3 files changed, 32 insertions, 1 deletions
diff --git a/pecan/core.py b/pecan/core.py index a43f3de..fae1502 100644 --- a/pecan/core.py +++ b/pecan/core.py @@ -631,6 +631,12 @@ class PecanBase(object): else: if not isinstance(e, exc.HTTPException): raise + + # if this is an HTTP 405, attempt to specify an Allow header + if isinstance(e, exc.HTTPMethodNotAllowed) and controller: + allowed_methods = _cfg(controller).get('allowed_methods', []) + if allowed_methods: + state.response.allow = sorted(allowed_methods) finally: # handle "after" hooks self.handle_hooks( diff --git a/pecan/decorators.py b/pecan/decorators.py index f40d16a..45ad635 100644 --- a/pecan/decorators.py +++ b/pecan/decorators.py @@ -16,6 +16,7 @@ def when_for(controller): expose(**kw)(f) _cfg(f)['generic_handler'] = True controller._pecan['generic_handlers'][method.upper()] = f + controller._pecan['allowed_methods'].append(method.upper()) return f return decorate return when @@ -56,6 +57,7 @@ def expose(template=None, if generic: cfg['generic'] = True cfg['generic_handlers'] = dict(DEFAULT=f) + cfg['allowed_methods'] = [] f.when = when_for(f) # store the arguments for this controller method diff --git a/pecan/tests/test_generic.py b/pecan/tests/test_generic.py index 879ad26..453f123 100644 --- a/pecan/tests/test_generic.py +++ b/pecan/tests/test_generic.py @@ -6,7 +6,7 @@ except: from six import b as b_ -from pecan import Pecan, expose +from pecan import Pecan, expose, abort from pecan.tests import PecanTestCase @@ -37,3 +37,26 @@ class TestGeneric(PecanTestCase): r = app.get('/do_get', status=404) assert r.status_int == 404 + + def test_generic_allow_header(self): + class RootController(object): + @expose(generic=True) + def index(self): + abort(405) + + @index.when(method='POST', template='json') + def do_post(self): + return dict(result='POST') + + @index.when(method='GET') + def do_get(self): + return 'GET' + + @index.when(method='PATCH') + def do_patch(self): + return 'PATCH' + + app = TestApp(Pecan(RootController())) + r = app.delete('/', expect_errors=True) + assert r.status_int == 405 + assert r.headers['Allow'] == 'GET, PATCH, POST' |