def get_app(self):
class StaticUrlHandler(RequestHandler):
def get(self, path):
- self.write(self.static_url(path))
+ with_v = int(self.get_argument('include_version', 1))
+ self.write(self.static_url(path, include_version=with_v))
- class AbsoluteStaticUrlHandler(RequestHandler):
+ class AbsoluteStaticUrlHandler(StaticUrlHandler):
include_host = True
- def get(self, path):
- self.write(self.static_url(path))
class OverrideStaticUrlHandler(RequestHandler):
def get(self, path):
self.assertEqual(response.body,
utf8(self.get_url("/") + "static/robots.txt?v=f71d2"))
+ def test_relative_version_exclusion(self):
+ response = self.fetch("/static_url/robots.txt?include_version=0")
+ self.assertEqual(response.body, b("/static/robots.txt"))
+
+ def test_absolute_version_exclusion(self):
+ response = self.fetch("/abs_static_url/robots.txt?include_version=0")
+ self.assertEqual(response.body,
+ utf8(self.get_url("/") + "static/robots.txt"))
+
def test_include_host_override(self):
self._trigger_include_host_check(False)
self._trigger_include_host_check(True)
self.write("bar")
@classmethod
- def make_static_url(cls, settings, path):
+ def make_static_url(cls, settings, path, include_version=True):
version_hash = cls.get_version(settings, path)
extension_index = path.rindex('.')
before_version = path[:extension_index]
return '<input type="hidden" name="_xsrf" value="' + \
escape.xhtml_escape(self.xsrf_token) + '"/>'
- def static_url(self, path, include_host=None):
+ def static_url(self, path, include_host=None, include_version=True):
"""Returns a static URL for the given relative static file path.
This method requires you set the 'static_path' setting in your
We append ?v=<signature> to the returned URL, which makes our
static file handler set an infinite expiration header on the
returned content. The signature is based on the content of the
- file.
+ file. This behavior can be avoided in case the ``include_version``
+ is set to False, i.e ?v=<signature> is not appended.
By default this method returns URLs relative to the current
host, but if ``include_host`` is true the URL returned will be
calls that do not pass ``include_host`` as a keyword argument.
"""
self.require_setting("static_path", "static_url")
- static_handler_class = self.settings.get(
- "static_handler_class", StaticFileHandler)
+ get_url = self.settings.get("static_handler_class",
+ StaticFileHandler).make_static_url
if include_host is None:
include_host = getattr(self, "include_host", False)
base = self.request.protocol + "://" + self.request.host
else:
base = ""
- return base + static_handler_class.make_static_url(self.settings, path)
+
+ return base + get_url(self.settings, path, include_version)
def async_callback(self, callback, *args, **kwargs):
"""Obsolete - catches exceptions from the wrapped function.
return self.CACHE_MAX_AGE if "v" in self.request.arguments else 0
@classmethod
- def make_static_url(cls, settings, path):
+ def make_static_url(cls, settings, path, include_version=True):
"""Constructs a versioned url for the given path.
This method may be overridden in subclasses (but note that it is
``settings`` is the `Application.settings` dictionary. ``path``
is the static path being requested. The url returned should be
relative to the current host.
+
+ ``include_version`` determines whether the generated URL should
+ include the query string containing the version hash of the
+ file corresponding to the given ``path``.
"""
- static_url_prefix = settings.get('static_url_prefix', '/static/')
+ url = settings.get('static_url_prefix', '/static/') + path
+ if not include_version:
+ return url
+
version_hash = cls.get_version(settings, path)
- if version_hash:
- return static_url_prefix + path + "?v=" + version_hash
- return static_url_prefix + path
+ if not version_hash:
+ return url
+
+ return '%s?v=%s' % (url, version_hash)
@classmethod
def get_version(cls, settings, path):