Merge "Handle SSL termination proxies for version list"
This commit is contained in:
commit
500fb35e69
|
@ -139,7 +139,13 @@ FILE_OPTIONS = {
|
|||
'exceeds the maximum length, the operation will fail '
|
||||
'with an HTTP 403 Forbidden error. If set to false, '
|
||||
'passwords are automatically truncated to the '
|
||||
'maximum length.')],
|
||||
'maximum length.'),
|
||||
cfg.StrOpt('secure_proxy_ssl_header',
|
||||
help='The HTTP header used to determine the scheme for the '
|
||||
'original request, even if it was removed by an SSL '
|
||||
'terminating proxy. Typical value is '
|
||||
'"HTTP_X_FORWARDED_PROTO".'),
|
||||
],
|
||||
'identity': [
|
||||
cfg.StrOpt('default_domain_id', default='default',
|
||||
help='This references the domain to use for all '
|
||||
|
|
|
@ -196,6 +196,16 @@ class Application(BaseApplication):
|
|||
context['query_string'] = dict(six.iteritems(req.params))
|
||||
context['headers'] = dict(six.iteritems(req.headers))
|
||||
context['path'] = req.environ['PATH_INFO']
|
||||
scheme = (None if not CONF.secure_proxy_ssl_header
|
||||
else req.environ.get(CONF.secure_proxy_ssl_header))
|
||||
if scheme:
|
||||
# NOTE(andrey-mp): "wsgi.url_scheme" contains the protocol used
|
||||
# before the proxy removed it ('https' usually). So if
|
||||
# the webob.Request instance is modified in order to use this
|
||||
# scheme instead of the one defined by API, the call to
|
||||
# webob.Request.relative_url() will return a URL with the correct
|
||||
# scheme.
|
||||
req.environ['wsgi.url_scheme'] = scheme
|
||||
context['host_url'] = req.host_url
|
||||
params = req.environ.get(PARAMS_ENV, {})
|
||||
# authentication and authorization attributes are set as environment
|
||||
|
|
|
@ -741,3 +741,52 @@ class VersionInheritEnabledTestCase(tests.TestCase):
|
|||
|
||||
self.assertThat(jsonutils.loads(resp.body),
|
||||
tt_matchers.Equals(exp_json_home_data))
|
||||
|
||||
|
||||
class VersionBehindSslTestCase(tests.TestCase):
|
||||
def setUp(self):
|
||||
super(VersionBehindSslTestCase, self).setUp()
|
||||
self.load_backends()
|
||||
self.public_app = self.loadapp('keystone', 'main')
|
||||
|
||||
def config_overrides(self):
|
||||
super(VersionBehindSslTestCase, self).config_overrides()
|
||||
self.config_fixture.config(
|
||||
secure_proxy_ssl_header='HTTP_X_FORWARDED_PROTO')
|
||||
|
||||
def _paste_in_port(self, response, port):
|
||||
for link in response['links']:
|
||||
if link['rel'] == 'self':
|
||||
link['href'] = port
|
||||
|
||||
def _get_expected(self, host):
|
||||
expected = VERSIONS_RESPONSE
|
||||
for version in expected['versions']['values']:
|
||||
if version['id'] == 'v3.0':
|
||||
self._paste_in_port(version, host + 'v3/')
|
||||
elif version['id'] == 'v2.0':
|
||||
self._paste_in_port(version, host + 'v2.0/')
|
||||
return expected
|
||||
|
||||
def test_versions_without_headers(self):
|
||||
client = self.client(self.public_app)
|
||||
host_name = 'host-%d' % random.randint(10, 30)
|
||||
host_port = random.randint(10000, 30000)
|
||||
host = 'http://%s:%s/' % (host_name, host_port)
|
||||
resp = client.get(host)
|
||||
self.assertEqual(300, resp.status_int)
|
||||
data = jsonutils.loads(resp.body)
|
||||
expected = self._get_expected(host)
|
||||
self.assertEqual(expected, data)
|
||||
|
||||
def test_versions_with_header(self):
|
||||
client = self.client(self.public_app)
|
||||
host_name = 'host-%d' % random.randint(10, 30)
|
||||
host_port = random.randint(10000, 30000)
|
||||
resp = client.get('http://%s:%s/' % (host_name, host_port),
|
||||
headers={'X-Forwarded-Proto': 'https'})
|
||||
self.assertEqual(300, resp.status_int)
|
||||
data = jsonutils.loads(resp.body)
|
||||
expected = self._get_expected('https://%s:%s/' % (host_name,
|
||||
host_port))
|
||||
self.assertEqual(expected, data)
|
||||
|
|
Loading…
Reference in New Issue