Add flag to stop swob from always using absolute location.

This is needed for SOS (along with patch
https://github.com/dpgoetz/sos/pull/37)
to work with swift 1.12 . By spec you should always use the absolute
location but this causes a problem with staticweb over a cdn using a
cname. Basically you want to be able to forward the browser to a
relative location instead of whatever full url the proxy server
thinks you are using.

Change-Id: I3fa1d415bf9b566be069458b838f7e65db0c4f39
This commit is contained in:
David Goetz 2014-01-22 13:03:51 -08:00 committed by Samuel Merritt
parent 9b3c86fb70
commit 89deaf5f3c
3 changed files with 44 additions and 1 deletions

View File

@ -33,6 +33,16 @@ Utils
:members:
:show-inheritance:
.. _swob:
Swob
====
.. automodule:: swift.common.swob
:members:
:show-inheritance:
:special-members: __call__
.. _acls:
ACLs

View File

@ -1186,11 +1186,31 @@ class Response(object):
return self.status_int // 100 == 2
def __call__(self, env, start_response):
"""
Respond to the WSGI request.
.. warning::
This will translate any relative Location header value to an
absolute URL using the WSGI environment's HOST_URL as a
prefix, as RFC 2616 specifies.
However, it is quite common to use relative redirects,
especially when it is difficult to know the exact HOST_URL
the browser would have used when behind several CNAMEs, CDN
services, etc. All modern browsers support relative
redirects.
To skip over RFC enforcement of the Location header value,
you may set ``env['swift.leave_relative_location'] = True``
in the WSGI environment.
"""
if not self.request:
self.request = Request(env)
self.environ = env
app_iter = self._response_iter(self.app_iter, self._body)
if 'location' in self.headers:
if 'location' in self.headers and \
not env.get('swift.leave_relative_location'):
self.location = self.absolute_location()
start_response(self.status, self.headers.items())
return app_iter

View File

@ -1034,6 +1034,19 @@ class TestResponse(unittest.TestCase):
''.join(resp(req.environ, start_response))
self.assertEquals(resp.location, 'http://www.google.com/')
def test_location_no_rewrite_when_told_not_to(self):
def start_response(env, headers):
pass
req = swift.common.swob.Request.blank(
'/', environ={'SERVER_NAME': 'local', 'SERVER_PORT': 81,
'swift.leave_relative_location': True})
del req.environ['HTTP_HOST']
resp = self._get_response()
resp.location = '/something'
# read response
''.join(resp(req.environ, start_response))
self.assertEquals(resp.location, '/something')
def test_app_iter(self):
def start_response(env, headers):
pass