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 15 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. 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 Version 0.6
----------- -----------

23
flask/app.py

@ -19,7 +19,8 @@ from jinja2 import Environment
from werkzeug import ImmutableDict from werkzeug import ImmutableDict
from werkzeug.routing import Map, Rule 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, \ from .helpers import _PackageBoundObject, url_for, get_flashed_messages, \
_tojson_filter, _endpoint_from_view_func _tojson_filter, _endpoint_from_view_func
@ -689,14 +690,28 @@ class Flask(_PackageBoundObject):
# if we provide automatic options for this URL and the # if we provide automatic options for this URL and the
# request came with the OPTIONS method, reply automatically # request came with the OPTIONS method, reply automatically
if rule.provide_automatic_options and req.method == 'OPTIONS': if rule.provide_automatic_options and req.method == 'OPTIONS':
rv = self.response_class() return self._make_default_options_response()
rv.allow.update(rule.methods)
return rv
# otherwise dispatch to the handler for that endpoint # otherwise dispatch to the handler for that endpoint
return self.view_functions[rule.endpoint](**req.view_args) return self.view_functions[rule.endpoint](**req.view_args)
except HTTPException, e: except HTTPException, e:
return self.handle_http_exception(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): def make_response(self, rv):
"""Converts the return value from a view function to a real """Converts the return value from a view function to a real
response object that is an instance of :attr:`response_class`. 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 sorted(rv.allow) == ['GET', 'HEAD', 'OPTIONS', 'POST']
assert rv.data == '' 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): def test_request_dispatching(self):
app = flask.Flask(__name__) app = flask.Flask(__name__)
@app.route('/') @app.route('/')

Loading…
Cancel
Save