From 7a4c9772bef1619af595658e637b7875066f11ee Mon Sep 17 00:00:00 2001 From: malwaredllc <30509968+malwaredllc@users.noreply.github.com> Date: Wed, 5 Jan 2022 11:59:06 -0700 Subject: [PATCH] add no_auto_head option in app route decorator --- src/flask/app.py | 9 +++++++++ tests/test_basic.py | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/flask/app.py b/src/flask/app.py index 7c4076c5..e0502b59 100644 --- a/src/flask/app.py +++ b/src/flask/app.py @@ -1046,6 +1046,7 @@ class Flask(Scaffold): endpoint = _endpoint_from_view_func(view_func) # type: ignore options["endpoint"] = endpoint methods = options.pop("methods", None) + no_auto_head = options.pop("no_auto_head", None) # if the methods are not given and the view_func object knows its # methods we can use that instead. If neither exists, we go with @@ -1082,6 +1083,14 @@ class Flask(Scaffold): rule = self.url_rule_class(rule, methods=methods, **options) rule.provide_automatic_options = provide_automatic_options # type: ignore + # If GET is only specified method, Werkzeug automatically adds HEAD method. + # This option will disable that feature to allow the user to write their + # own handling for HEAD. + only_get = methods == {"GET", "OPTIONS"} + + if only_get and no_auto_head is not None: + rule.methods.discard("HEAD") + self.url_map.add(rule) if view_func is not None: old_func = self.view_functions.get(endpoint) diff --git a/tests/test_basic.py b/tests/test_basic.py index ce85ee71..b6014825 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -2024,3 +2024,16 @@ def test_app_freed_on_zero_refcount(): assert weak() is None finally: gc.enable() + + +def test_no_auto_head_option(app, client): + @app.route("/", methods=["GET"], no_auto_head=True) + def index(): + return "Hello world", 200 + + @app.route("/", methods=["HEAD"]) + def index_head(): + return "", 200, {"test-header": "test-value"} + + assert client.get("/").data == b"Hello world" + assert "test-header" in client.head("/").headers