From b5069d07a24a3c3a54fb056aa6f4076a0e7088c7 Mon Sep 17 00:00:00 2001 From: Max Countryman Date: Thu, 17 Jan 2013 15:08:45 -0800 Subject: [PATCH] adding `_scheme` parameter to `url_for` In order to better facilitate generation of URLs that make use of an HTTPS URL scheme this patch adds a parameter with this specific purpose in mind. To achieve this we explicitly pass in a param, `_scheme='https'`, and then set the `url_scheme` attribute of our `MapAdapter` instance appropriately. Importantly, `_external=True` must be set in order for this to work properly. As such, failure to do so results in a `ValueError` being raised. --- flask/helpers.py | 12 ++++++++++++ flask/testsuite/helpers.py | 22 ++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/flask/helpers.py b/flask/helpers.py index 6aea45c6..a1c09cc5 100644 --- a/flask/helpers.py +++ b/flask/helpers.py @@ -229,6 +229,9 @@ def url_for(endpoint, **values): that this is for building URLs outside the current application, and not for handling 404 NotFound errors. + .. versionadded:: 0.10 + The `_scheme` parameter was added. + .. versionadded:: 0.9 The `_anchor` and `_method` parameters were added. @@ -241,6 +244,8 @@ def url_for(endpoint, **values): :param _external: if set to `True`, an absolute URL is generated. Server address can be changed via `SERVER_NAME` configuration variable which defaults to `localhost`. + :param _scheme: a string specifying the desired URL scheme. The `_external` + parameter must be set to `True` or a `ValueError` is raised. :param _anchor: if provided this is added as anchor to the URL. :param _method: if provided this explicitly specifies an HTTP method. """ @@ -283,7 +288,14 @@ def url_for(endpoint, **values): anchor = values.pop('_anchor', None) method = values.pop('_method', None) + scheme = values.pop('_scheme', None) appctx.app.inject_url_defaults(endpoint, values) + + if scheme is not None: + if not external: + raise ValueError('When specifying _scheme, _external must be True') + url_adapter.url_scheme = scheme + try: rv = url_adapter.build(endpoint, values, method=method, force_external=external) diff --git a/flask/testsuite/helpers.py b/flask/testsuite/helpers.py index 31f0dcb4..fdf2d89f 100644 --- a/flask/testsuite/helpers.py +++ b/flask/testsuite/helpers.py @@ -397,6 +397,28 @@ class LoggingTestCase(FlaskTestCase): self.assert_equal(flask.url_for('index', _anchor='x y'), '/#x%20y') + def test_url_for_with_scheme(self): + app = flask.Flask(__name__) + @app.route('/') + def index(): + return '42' + with app.test_request_context(): + self.assert_equal(flask.url_for('index', + _external=True, + _scheme='https'), + 'https://localhost/') + + def test_url_for_with_scheme_not_external(self): + app = flask.Flask(__name__) + @app.route('/') + def index(): + return '42' + with app.test_request_context(): + self.assert_raises(ValueError, + flask.url_for, + 'index', + _scheme='https') + def test_url_with_method(self): from flask.views import MethodView app = flask.Flask(__name__)