Browse Source

Change Flask.__init__ to accept two new keyword arguments, host_matching and static_host. (#1560)

This enables host_matching to be set properly by the time the constructor adds
the static route, and enables the static route to be properly associated with
the required host.

Previously, you could only enable host_matching once your app was already
instantiated (e.g. app.url_map.host_matching = True), but at that point
the constructor would have already added the static route without host matching
and an associated host, leaving the static route in a broken state.

Fixes #1559.
pull/2237/head
jab 8 years ago committed by Markus Unterwaditzer
parent
commit
00d6e339ec
  1. 1
      AUTHORS
  2. 5
      CHANGES
  3. 28
      flask/app.py
  4. 19
      tests/test_basic.py

1
AUTHORS

@ -21,6 +21,7 @@ Patches and Suggestions
- Florent Xicluna - Florent Xicluna
- Georg Brandl - Georg Brandl
- Jeff Widman @jeffwidman - Jeff Widman @jeffwidman
- Joshua Bronson @jab
- Justin Quick - Justin Quick
- Kenneth Reitz - Kenneth Reitz
- Keyan Pishdadian - Keyan Pishdadian

5
CHANGES

@ -14,6 +14,11 @@ Major release, unreleased
- Change default configuration `JSONIFY_PRETTYPRINT_REGULAR=False`. jsonify() - Change default configuration `JSONIFY_PRETTYPRINT_REGULAR=False`. jsonify()
method returns compressed response by default, and pretty response in method returns compressed response by default, and pretty response in
debug mode. debug mode.
- Change Flask.__init__ to accept two new keyword arguments, ``host_matching``
and ``static_host``. This enables ``host_matching`` to be set properly by the
time the constructor adds the static route, and enables the static route to
be properly associated with the required host. (``#1559``)
Version 0.12.1 Version 0.12.1
-------------- --------------

28
flask/app.py

@ -123,6 +123,9 @@ class Flask(_PackageBoundObject):
.. versionadded:: 0.11 .. versionadded:: 0.11
The `root_path` parameter was added. The `root_path` parameter was added.
.. versionadded:: 0.13
The `host_matching` and `static_host` parameters were added.
:param import_name: the name of the application package :param import_name: the name of the application package
:param static_url_path: can be used to specify a different path for the :param static_url_path: can be used to specify a different path for the
static files on the web. Defaults to the name static files on the web. Defaults to the name
@ -130,6 +133,13 @@ class Flask(_PackageBoundObject):
:param static_folder: the folder with static files that should be served :param static_folder: the folder with static files that should be served
at `static_url_path`. Defaults to the ``'static'`` at `static_url_path`. Defaults to the ``'static'``
folder in the root path of the application. folder in the root path of the application.
folder in the root path of the application. Defaults
to None.
:param host_matching: sets the app's ``url_map.host_matching`` to the given
given value. Defaults to False.
:param static_host: the host to use when adding the static route. Defaults
to None. Required when using ``host_matching=True``
with a ``static_folder`` configured.
:param template_folder: the folder that contains the templates that should :param template_folder: the folder that contains the templates that should
be used by the application. Defaults to be used by the application. Defaults to
``'templates'`` folder in the root path of the ``'templates'`` folder in the root path of the
@ -337,7 +347,8 @@ class Flask(_PackageBoundObject):
session_interface = SecureCookieSessionInterface() session_interface = SecureCookieSessionInterface()
def __init__(self, import_name, static_path=None, static_url_path=None, def __init__(self, import_name, static_path=None, static_url_path=None,
static_folder='static', template_folder='templates', static_folder='static', static_host=None,
host_matching=False, template_folder='templates',
instance_path=None, instance_relative_config=False, instance_path=None, instance_relative_config=False,
root_path=None): root_path=None):
_PackageBoundObject.__init__(self, import_name, _PackageBoundObject.__init__(self, import_name,
@ -525,19 +536,22 @@ class Flask(_PackageBoundObject):
#: app.url_map.converters['list'] = ListConverter #: app.url_map.converters['list'] = ListConverter
self.url_map = Map() self.url_map = Map()
self.url_map.host_matching = host_matching
# tracks internally if the application already handled at least one # tracks internally if the application already handled at least one
# request. # request.
self._got_first_request = False self._got_first_request = False
self._before_request_lock = Lock() self._before_request_lock = Lock()
# register the static folder for the application. Do that even # Add a static route using the provided static_url_path, static_host,
# if the folder does not exist. First of all it might be created # and static_folder iff there is a configured static_folder.
# while the server is running (usually happens during development) # Note we do this without checking if static_folder exists.
# but also because google appengine stores static files somewhere # For one, it might be created while the server is running (e.g. during
# else when mapped with the .yml file. # development). Also, Google App Engine stores static files somewhere
if self.has_static_folder: if self.has_static_folder:
assert bool(static_host) == host_matching, 'Invalid static_host/host_matching combination'
self.add_url_rule(self.static_url_path + '/<path:filename>', self.add_url_rule(self.static_url_path + '/<path:filename>',
endpoint='static', endpoint='static', host=static_host,
view_func=self.send_static_file) view_func=self.send_static_file)
#: The click command line context for this application. Commands #: The click command line context for this application. Commands

19
tests/test_basic.py

@ -1188,6 +1188,25 @@ def test_static_url_path():
assert flask.url_for('static', filename='index.html') == '/foo/index.html' assert flask.url_for('static', filename='index.html') == '/foo/index.html'
def test_static_route_with_host_matching():
app = flask.Flask(__name__, host_matching=True, static_host='example.com')
c = app.test_client()
rv = c.get('http://example.com/static/index.html')
assert rv.status_code == 200
rv.close()
with app.test_request_context():
rv = flask.url_for('static', filename='index.html', _external=True)
assert rv == 'http://example.com/static/index.html'
# Providing static_host without host_matching=True should error.
with pytest.raises(Exception):
flask.Flask(__name__, static_host='example.com')
# Providing host_matching=True with static_folder but without static_host should error.
with pytest.raises(Exception):
flask.Flask(__name__, host_matching=True)
# Providing host_matching=True without static_host but with static_folder=None should not error.
flask.Flask(__name__, host_matching=True, static_folder=None)
def test_none_response(): def test_none_response():
app = flask.Flask(__name__) app = flask.Flask(__name__)
app.testing = True app.testing = True

Loading…
Cancel
Save