Add flag to stop swob from always using absolute location.

This is a backport of commit 89deaf5f3c

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: I28dcbd779d2aa4a6e636c956b058670b8e4b2fd7
This commit is contained in:
David Goetz 2014-01-22 13:03:51 -08:00 committed by John Dickinson
parent f538006bbf
commit 78704010cc
3 changed files with 44 additions and 2 deletions

View File

@ -33,6 +33,16 @@ Utils
:members:
:show-inheritance:
.. _swob:
Swob
====
.. automodule:: swift.common.swob
:members:
:show-inheritance:
:special-members: __call__
.. _common_tempauth:
TempAuth
@ -51,7 +61,6 @@ KeystoneAuth
:members:
:show-inheritance:
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