diff options
| author | Michael Merickel <michael@merickel.org> | 2013-03-19 13:04:44 -0700 |
|---|---|---|
| committer | Michael Merickel <michael@merickel.org> | 2013-03-19 13:04:44 -0700 |
| commit | cfbfdff04fa10b1b8ed1d0ef52edc937cf101060 (patch) | |
| tree | 31165cdac8d3006b8f3bda941729907febdd60d2 | |
| parent | 3fda611d2f9c515ed1e69f613641febceef387f8 (diff) | |
| parent | ff41f867aef84c06833f19de18d4fbc2957a983a (diff) | |
| download | pyramid-cfbfdff04fa10b1b8ed1d0ef52edc937cf101060.tar.gz pyramid-cfbfdff04fa10b1b8ed1d0ef52edc937cf101060.tar.bz2 pyramid-cfbfdff04fa10b1b8ed1d0ef52edc937cf101060.zip | |
Merge branch 'fix.798' of wosc/pyramid into pull.922
| -rw-r--r-- | CHANGES.txt | 4 | ||||
| -rw-r--r-- | pyramid/config/views.py | 24 | ||||
| -rw-r--r-- | pyramid/tests/test_config/test_views.py | 7 | ||||
| -rw-r--r-- | pyramid/tests/test_url.py | 15 |
4 files changed, 40 insertions, 10 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 2e96421ee..d087bf43b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -11,6 +11,10 @@ Features a dynamic property. It is recommended to define a dynamic ACL as a callable to avoid this ambiguity. See https://github.com/Pylons/pyramid/issues/735. +- Allow a protocol-relative URL (e.g. ``//example.com/images``) to be passed to + ``pyramid.config.Configurator.add_static_view``. This allows + externally-hosted static URLs to be generated based on the current protocol. + Bug Fixes --------- diff --git a/pyramid/config/views.py b/pyramid/config/views.py index c53b2b091..1c7620e67 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -1793,6 +1793,10 @@ class ViewsConfiguratorMixin(object): qualified URL (e.g. starts with ``http://`` or similar). In this mode, the ``name`` is used as the prefix of the full URL when generating a URL using :meth:`pyramid.request.Request.static_url`. + Furthermore, if a protocol-relative URL (e.g. ``//example.com/images``) + is used as the ``name`` argument, the generated URL will use the + protocol of the request (http or https, respectively). + For example, if ``add_static_view`` is called like so: .. code-block:: python @@ -1801,20 +1805,14 @@ class ViewsConfiguratorMixin(object): Subsequently, the URLs generated by :meth:`pyramid.request.Request.static_url` for that static view will - be prefixed with ``http://example.com/images``: + be prefixed with ``http://example.com/images`` (the external webserver + listening on ``example.com`` must be itself configured to respond + properly to such a request.): .. code-block:: python static_url('mypackage:images/logo.png', request) - When ``add_static_view`` is called with a ``name`` argument that is - the URL ``http://example.com/images``, subsequent calls to - :meth:`pyramid.request.Request.static_url` with paths that start with - the ``path`` argument passed to ``add_static_view`` will generate a - URL something like ``http://example.com/logo.png``. The external - webserver listening on ``example.com`` must be itself configured to - respond properly to such a request. - See :ref:`static_assets_section` for more information. """ spec = self._make_spec(path) @@ -1858,6 +1856,12 @@ class StaticURLInfo(object): kw['subpath'] = subpath return request.route_url(route_name, **kw) else: + parsed = url_parse(url) + if not parsed.scheme: + # parsed.scheme is readonly, so we have to parse again + # to change the scheme, sigh. + url = urlparse.urlunparse(url_parse( + url, scheme=request.environ['wsgi.url_scheme'])) subpath = url_quote(subpath) return urljoin(url, subpath) @@ -1886,7 +1890,7 @@ class StaticURLInfo(object): # make sure it ends with a slash name = name + '/' - if url_parse(name)[0]: + if url_parse(name).netloc: # it's a URL # url, spec, route_name url = name diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index 4cebdce8a..5388001f6 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -3737,6 +3737,13 @@ class TestStaticURLInfo(unittest.TestCase): expected = [('http://example.com/', 'anotherpackage:path/', None)] self._assertRegistrations(config, expected) + def test_add_url_noscheme(self): + inst = self._makeOne() + config = self._makeConfig() + inst.add(config, '//example.com', 'anotherpackage:path') + expected = [('//example.com/', 'anotherpackage:path/', None)] + self._assertRegistrations(config, expected) + def test_add_viewname(self): from pyramid.security import NO_PERMISSION_REQUIRED from pyramid.static import static_view diff --git a/pyramid/tests/test_url.py b/pyramid/tests/test_url.py index a7a565356..e33eeebfd 100644 --- a/pyramid/tests/test_url.py +++ b/pyramid/tests/test_url.py @@ -583,6 +583,21 @@ class TestURLMethodsMixin(unittest.TestCase): self.assertEqual(result, 'http://example.com:5432/absstatic/test_url.py') + def test_static_url_noscheme_uses_scheme_from_request(self): + import os + from pyramid.interfaces import IStaticURLInfo + from pyramid.config.views import StaticURLInfo + info = StaticURLInfo() + here = os.path.abspath(os.path.dirname(__file__)) + info.add(self.config, '//subdomain.example.com/static', here) + request = self._makeOne({'wsgi.url_scheme': 'https'}) + registry = request.registry + registry.registerUtility(info, IStaticURLInfo) + abspath = os.path.join(here, 'test_url.py') + result = request.static_url(abspath) + self.assertEqual(result, + 'https://subdomain.example.com/static/test_url.py') + def test_static_path_abspath(self): from pyramid.interfaces import IStaticURLInfo request = self._makeOne() |
