Skip to content

Commit b975dd4

Browse files
author
Kenneth Reitz
committed
Merge pull request pallets#667 from maxcountryman/secure-url-for
adding `_scheme` parameter to `url_for`
2 parents 6fa449d + b5069d0 commit b975dd4

2 files changed

Lines changed: 34 additions & 0 deletions

File tree

flask/helpers.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,9 @@ def external_url_handler(error, endpoint, **values):
229229
that this is for building URLs outside the current application, and not for
230230
handling 404 NotFound errors.
231231
232+
.. versionadded:: 0.10
233+
The `_scheme` parameter was added.
234+
232235
.. versionadded:: 0.9
233236
The `_anchor` and `_method` parameters were added.
234237
@@ -241,6 +244,8 @@ def external_url_handler(error, endpoint, **values):
241244
:param _external: if set to `True`, an absolute URL is generated. Server
242245
address can be changed via `SERVER_NAME` configuration variable which
243246
defaults to `localhost`.
247+
:param _scheme: a string specifying the desired URL scheme. The `_external`
248+
parameter must be set to `True` or a `ValueError` is raised.
244249
:param _anchor: if provided this is added as anchor to the URL.
245250
:param _method: if provided this explicitly specifies an HTTP method.
246251
"""
@@ -283,7 +288,14 @@ def external_url_handler(error, endpoint, **values):
283288

284289
anchor = values.pop('_anchor', None)
285290
method = values.pop('_method', None)
291+
scheme = values.pop('_scheme', None)
286292
appctx.app.inject_url_defaults(endpoint, values)
293+
294+
if scheme is not None:
295+
if not external:
296+
raise ValueError('When specifying _scheme, _external must be True')
297+
url_adapter.url_scheme = scheme
298+
287299
try:
288300
rv = url_adapter.build(endpoint, values, method=method,
289301
force_external=external)

flask/testsuite/helpers.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,28 @@ def index():
397397
self.assert_equal(flask.url_for('index', _anchor='x y'),
398398
'/#x%20y')
399399

400+
def test_url_for_with_scheme(self):
401+
app = flask.Flask(__name__)
402+
@app.route('/')
403+
def index():
404+
return '42'
405+
with app.test_request_context():
406+
self.assert_equal(flask.url_for('index',
407+
_external=True,
408+
_scheme='https'),
409+
'https://localhost/')
410+
411+
def test_url_for_with_scheme_not_external(self):
412+
app = flask.Flask(__name__)
413+
@app.route('/')
414+
def index():
415+
return '42'
416+
with app.test_request_context():
417+
self.assert_raises(ValueError,
418+
flask.url_for,
419+
'index',
420+
_scheme='https')
421+
400422
def test_url_with_method(self):
401423
from flask.views import MethodView
402424
app = flask.Flask(__name__)

0 commit comments

Comments
 (0)