For an HTTP 405 on generic methods, attempt to specify an Allow header.
Change-Id: I726d698fc014c21cc1e43a09a129384fa1f1235f
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user