Browse Source

Fixed an issue where the default `OPTIONS` response was

not exposing all valid methods in the `Allow` header.

This fixes #97

Signed-off-by: Armin Ronacher <armin.ronacher@active-4.com>
pull/112/head
Armin Ronacher 14 years ago
parent
commit
dbf55de7e8
  1. 3
      CHANGES
  2. 23
      flask/app.py
  3. 11
      tests/flask_tests.py

3
CHANGES

@ -13,6 +13,9 @@ Version 0.6.1
Bugfix release, release date to be announced.
- Fixed an issue where the default `OPTIONS` response was
not exposing all valid methods in the `Allow` header.
Version 0.6
-----------

23
flask/app.py

@ -19,7 +19,8 @@ from jinja2 import Environment
from werkzeug import ImmutableDict
from werkzeug.routing import Map, Rule
from werkzeug.exceptions import HTTPException, InternalServerError
from werkzeug.exceptions import HTTPException, InternalServerError, \
MethodNotAllowed
from .helpers import _PackageBoundObject, url_for, get_flashed_messages, \
_tojson_filter, _endpoint_from_view_func
@ -689,14 +690,28 @@ class Flask(_PackageBoundObject):
# if we provide automatic options for this URL and the
# request came with the OPTIONS method, reply automatically
if rule.provide_automatic_options and req.method == 'OPTIONS':
rv = self.response_class()
rv.allow.update(rule.methods)
return rv
return self._make_default_options_response()
# otherwise dispatch to the handler for that endpoint
return self.view_functions[rule.endpoint](**req.view_args)
except HTTPException, e:
return self.handle_http_exception(e)
def _make_default_options_response(self):
# This would be nicer in Werkzeug 0.7, which however currently
# is not released. Werkzeug 0.7 provides a method called
# allowed_methods() that returns all methods that are valid for
# a given path.
methods = []
try:
_request_ctx_stack.top.url_adapter.match(method='--')
except MethodNotAllowed, e:
methods = e.valid_methods
except HTTPException, e:
pass
rv = self.response_class()
rv.allow.update(methods)
return rv
def make_response(self, rv):
"""Converts the return value from a view function to a real
response object that is an instance of :attr:`response_class`.

11
tests/flask_tests.py

@ -120,6 +120,17 @@ class BasicFunctionalityTestCase(unittest.TestCase):
assert sorted(rv.allow) == ['GET', 'HEAD', 'OPTIONS', 'POST']
assert rv.data == ''
def test_options_on_multiple_rules(self):
app = flask.Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def index():
return 'Hello World'
@app.route('/', methods=['PUT'])
def index_put():
return 'Aha!'
rv = app.test_client().open('/', method='OPTIONS')
assert sorted(rv.allow) == ['GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']
def test_request_dispatching(self):
app = flask.Flask(__name__)
@app.route('/')

Loading…
Cancel
Save