Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add kwarg to disable auto OPTIONS on add_url_rule #1489

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ Version 1.0
- ``flask.g`` now has ``pop()`` and ``setdefault`` methods.
- Turn on autoescape for ``flask.templating.render_template_string`` by default
(pull request ``#1515``).
- Added support for `provide_automatic_options` in :meth:`add_url_rule` to
turn off automatic OPTIONS when the `view_func` argument is not a class

This comment was marked as off-topic.

(pull request ``#1489``).

Version 0.10.2
--------------
Expand Down
12 changes: 9 additions & 3 deletions flask/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -944,7 +944,8 @@ def iter_blueprints(self):
return iter(self._blueprint_order)

@setupmethod
def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
def add_url_rule(self, rule, endpoint=None, view_func=None,
provide_automatic_options=None, **options):
"""Connects a URL rule. Works exactly like the :meth:`route`
decorator. If a view_func is provided it will be registered with the
endpoint.
Expand Down Expand Up @@ -984,6 +985,10 @@ def index():
endpoint
:param view_func: the function to call when serving a request to the
provided endpoint
:param provide_automatic_options: controls whether ``OPTIONS`` should
be provided automatically. If this
is not set, will check attributes on
the view or list of methods.
:param options: the options to be forwarded to the underlying
:class:`~werkzeug.routing.Rule` object. A change
to Werkzeug is handling of method options. methods
Expand Down Expand Up @@ -1013,8 +1018,9 @@ def index():

# starting with Flask 0.8 the view_func object can disable and
# force-enable the automatic options handling.
provide_automatic_options = getattr(view_func,
'provide_automatic_options', None)
if provide_automatic_options is None:
provide_automatic_options = getattr(view_func,
'provide_automatic_options', None)

if provide_automatic_options is None:
if 'OPTIONS' not in methods:
Expand Down
41 changes: 41 additions & 0 deletions tests/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1616,3 +1616,44 @@ def run_simple_mock(hostname, port, application, *args, **kwargs):
hostname, port = 'localhost', 8000
app.run(hostname, port, debug=True)
assert rv['result'] == 'running on %s:%s ...' % (hostname, port)


def test_disable_automatic_options():
# Issue 1488: Add support for a kwarg to add_url_rule to disable the auto OPTIONS response
app = flask.Flask(__name__)

def index():
return flask.request.method

def more():
return flask.request.method

app.add_url_rule('/', 'index', index, provide_automatic_options=False)
app.add_url_rule('/more', 'more', more, methods=['GET', 'POST'], provide_automatic_options=False)

c = app.test_client()
assert c.get('/').data == b'GET'
rv = c.post('/')
assert rv.status_code == 405
assert sorted(rv.allow) == ['GET', 'HEAD']
# Older versions of Werkzeug.test.Client don't have an options method
if hasattr(c, 'options'):
rv = c.options('/')
else:
rv = c.open('/', method='OPTIONS')
assert rv.status_code == 405

rv = c.head('/')
assert rv.status_code == 200
assert not rv.data # head truncates
assert c.post('/more').data == b'POST'
assert c.get('/more').data == b'GET'
rv = c.delete('/more')
assert rv.status_code == 405
assert sorted(rv.allow) == ['GET', 'HEAD', 'POST']
# Older versions of Werkzeug.test.Client don't have an options method
if hasattr(c, 'options'):
rv = c.options('/more')
else:
rv = c.open('/more', method='OPTIONS')
assert rv.status_code == 405