From d1da7a1dfe1ca2d2731622c91c094019c4dcb488 Mon Sep 17 00:00:00 2001 From: Enol Fernandez Date: Tue, 28 Mar 2017 13:11:54 +0100 Subject: [PATCH] Add option to handle SSL termination proxies ooi needs to return URLs of objects matching the URL scheme used for serving the application even if ooi is behind a SSL termination proxy. A new configuration variable "ooi_secure_proxy_ssl_header" that defines the HTTP header that can be used to update the wsgi.url_scheme environment variable. Typical value for this variable is 'HTTP_X_FORWARDED_PROTO'. Change-Id: I7ce7583f64778f667a7ea310d493390d9e19f1e2 Closes-Bug: #1676844 --- ooi/tests/unit/test_wsgi.py | 7 +++++++ ooi/wsgi/__init__.py | 13 +++++++++++++ 2 files changed, 20 insertions(+) diff --git a/ooi/tests/unit/test_wsgi.py b/ooi/tests/unit/test_wsgi.py index 423ef98..b00ac76 100644 --- a/ooi/tests/unit/test_wsgi.py +++ b/ooi/tests/unit/test_wsgi.py @@ -16,6 +16,7 @@ import webob import webob.dec import webob.exc +from ooi import config from ooi.tests import base from ooi import wsgi @@ -160,6 +161,12 @@ class TestMiddleware(base.TestCase): result = req.get_response(self.app) self.assertEqual(404, result.status_code) + def test_ssl_middleware(self): + config.cfg.CONF.set_override('ooi_secure_proxy_ssl_header', 'bar') + request = wsgi.Request.blank("/foos", method="GET", + environ={'bar': 'baz'}) + self.assertEqual('baz', request.environ['wsgi.url_scheme']) + class TestOCCIMiddleware(base.TestCase): def setUp(self): diff --git a/ooi/wsgi/__init__.py b/ooi/wsgi/__init__.py index be1055d..14451f6 100644 --- a/ooi/wsgi/__init__.py +++ b/ooi/wsgi/__init__.py @@ -48,6 +48,12 @@ occi_opts = [ help='Number of workers for OCCI (ooi) API service. ' 'The default will be equal to the number of CPUs ' 'available.'), + config.cfg.StrOpt('ooi_secure_proxy_ssl_header', + default=None, + 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".'), # NEUTRON config.cfg.StrOpt('neutron_ooi_endpoint', default=None, @@ -60,6 +66,13 @@ CONF.register_opts(occi_opts) class Request(webob.Request): + def __init__(self, environ, *args, **kwargs): + if CONF.ooi_secure_proxy_ssl_header: + scheme = environ.get(CONF.ooi_secure_proxy_ssl_header) + if scheme: + environ['wsgi.url_scheme'] = scheme + super(Request, self).__init__(environ, *args, **kwargs) + def should_have_body(self): return self.method in ("POST", "PUT")