From 6aee9f6d77e0696bd570d6095445d73c48539f8a Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Sun, 22 May 2016 10:45:25 +0200 Subject: [PATCH] Resolve state issue for url_for with forced scheme This fixes #1596 --- flask/helpers.py | 13 +++++++++++-- tests/test_helpers.py | 10 ++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/flask/helpers.py b/flask/helpers.py index 02e99e37..a0606bf2 100644 --- a/flask/helpers.py +++ b/flask/helpers.py @@ -300,14 +300,23 @@ def url_for(endpoint, **values): scheme = values.pop('_scheme', None) appctx.app.inject_url_defaults(endpoint, values) + # This is not the best way to deal with this but currently the + # underlying Werkzeug router does not support overriding the scheme on + # a per build call basis. + old_scheme = None if scheme is not None: if not external: raise ValueError('When specifying _scheme, _external must be True') + old_scheme = url_adapter.url_scheme url_adapter.url_scheme = scheme try: - rv = url_adapter.build(endpoint, values, method=method, - force_external=external) + try: + rv = url_adapter.build(endpoint, values, method=method, + force_external=external) + finally: + if old_scheme is not None: + url_adapter.url_scheme = old_scheme except BuildError as error: # We need to inject the values again so that the app callback can # deal with that sort of stuff. diff --git a/tests/test_helpers.py b/tests/test_helpers.py index 5605c45d..6dc41fad 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -627,6 +627,16 @@ class TestLogging(object): 'index', _scheme='https') + def test_url_for_with_alternating_schemes(self): + app = flask.Flask(__name__) + @app.route('/') + def index(): + return '42' + with app.test_request_context(): + assert flask.url_for('index', _external=True) == 'http://localhost/' + assert flask.url_for('index', _external=True, _scheme='https') == 'https://localhost/' + assert flask.url_for('index', _external=True) == 'http://localhost/' + def test_url_with_method(self): from flask.views import MethodView app = flask.Flask(__name__)