Skip to content

Commit

Permalink
Merge branch 'pull.922'
Browse files Browse the repository at this point in the history
  • Loading branch information
mmerickel committed Mar 19, 2013
2 parents 3fda611 + cfbfdff commit 5491a8e
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 10 deletions.
4 changes: 4 additions & 0 deletions CHANGES.txt
Expand Up @@ -11,6 +11,10 @@ Features
a dynamic property. It is recommended to define a dynamic ACL as a callable 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. 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 Bug Fixes
--------- ---------


Expand Down
24 changes: 14 additions & 10 deletions pyramid/config/views.py
Expand Up @@ -1793,6 +1793,10 @@ def add_static_view(self, name, path, **kw):
qualified URL (e.g. starts with ``http://`` or similar). In this qualified URL (e.g. starts with ``http://`` or similar). In this
mode, the ``name`` is used as the prefix of the full URL when mode, the ``name`` is used as the prefix of the full URL when
generating a URL using :meth:`pyramid.request.Request.static_url`. 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: For example, if ``add_static_view`` is called like so:
.. code-block:: python .. code-block:: python
Expand All @@ -1801,20 +1805,14 @@ def add_static_view(self, name, path, **kw):
Subsequently, the URLs generated by Subsequently, the URLs generated by
:meth:`pyramid.request.Request.static_url` for that static view will :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 .. code-block:: python
static_url('mypackage:images/logo.png', request) 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. See :ref:`static_assets_section` for more information.
""" """
spec = self._make_spec(path) spec = self._make_spec(path)
Expand Down Expand Up @@ -1858,6 +1856,12 @@ def generate(self, path, request, **kw):
kw['subpath'] = subpath kw['subpath'] = subpath
return request.route_url(route_name, **kw) return request.route_url(route_name, **kw)
else: 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) subpath = url_quote(subpath)
return urljoin(url, subpath) return urljoin(url, subpath)


Expand Down Expand Up @@ -1886,7 +1890,7 @@ def add(self, config, name, spec, **extra):
# make sure it ends with a slash # make sure it ends with a slash
name = name + '/' name = name + '/'


if url_parse(name)[0]: if url_parse(name).netloc:
# it's a URL # it's a URL
# url, spec, route_name # url, spec, route_name
url = name url = name
Expand Down
7 changes: 7 additions & 0 deletions pyramid/tests/test_config/test_views.py
Expand Up @@ -3737,6 +3737,13 @@ def test_add_url_noendslash(self):
expected = [('http://example.com/', 'anotherpackage:path/', None)] expected = [('http://example.com/', 'anotherpackage:path/', None)]
self._assertRegistrations(config, expected) 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): def test_add_viewname(self):
from pyramid.security import NO_PERMISSION_REQUIRED from pyramid.security import NO_PERMISSION_REQUIRED
from pyramid.static import static_view from pyramid.static import static_view
Expand Down
15 changes: 15 additions & 0 deletions pyramid/tests/test_url.py
Expand Up @@ -583,6 +583,21 @@ def test_static_url_abspath_integration_with_staticurlinfo(self):
self.assertEqual(result, self.assertEqual(result,
'http://example.com:5432/absstatic/test_url.py') '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): def test_static_path_abspath(self):
from pyramid.interfaces import IStaticURLInfo from pyramid.interfaces import IStaticURLInfo
request = self._makeOne() request = self._makeOne()
Expand Down

0 comments on commit 5491a8e

Please sign in to comment.