summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--oslo_middleware/base.py14
-rw-r--r--oslo_middleware/cors.py10
-rw-r--r--oslo_middleware/healthcheck/__main__.py69
-rw-r--r--oslo_middleware/http_proxy_to_wsgi.py2
-rw-r--r--oslo_middleware/opts.py29
-rw-r--r--oslo_middleware/tests/test_base.py11
-rw-r--r--oslo_middleware/tests/test_healthcheck.py24
-rw-r--r--requirements.txt8
-rw-r--r--setup.cfg1
-rw-r--r--test-requirements.txt6
10 files changed, 156 insertions, 18 deletions
diff --git a/oslo_middleware/base.py b/oslo_middleware/base.py
index a98a058..27689a1 100644
--- a/oslo_middleware/base.py
+++ b/oslo_middleware/base.py
@@ -17,10 +17,22 @@
from inspect import getargspec
import webob.dec
+import webob.request
+import webob.response
from oslo_config import cfg
+class NoContentTypeResponse(webob.response.Response):
+
+ default_content_type = None # prevents webob assigning content type
+
+
+class NoContentTypeRequest(webob.request.Request):
+
+ ResponseClass = NoContentTypeResponse
+
+
class ConfigurableMiddleware(object):
"""Base WSGI middleware wrapper.
@@ -106,7 +118,7 @@ class ConfigurableMiddleware(object):
"""Do whatever you'd like to the response."""
return response
- @webob.dec.wsgify
+ @webob.dec.wsgify(RequestClass=NoContentTypeRequest)
def __call__(self, req):
response = self.process_request(req)
if response:
diff --git a/oslo_middleware/cors.py b/oslo_middleware/cors.py
index 8857afc..8e8422d 100644
--- a/oslo_middleware/cors.py
+++ b/oslo_middleware/cors.py
@@ -19,9 +19,8 @@ import debtcollector
from oslo_config import cfg
from oslo_middleware import base
import six
-import webob.dec
import webob.exc
-import webob.response
+
LOG = logging.getLogger(__name__)
@@ -99,11 +98,6 @@ class InvalidOriginError(Exception):
'CORS request from origin \'%s\' not permitted.' % origin)
-class _NoContentTypeResponse(webob.response.Response):
-
- default_content_type = None # prevents webob assigning content type
-
-
class CORS(base.ConfigurableMiddleware):
"""CORS Middleware.
@@ -334,7 +328,7 @@ class CORS(base.ConfigurableMiddleware):
# underlying middleware's response content needs to be persisted.
# Otherwise, create a new response.
if 200 > response.status_code or response.status_code >= 300:
- response = _NoContentTypeResponse(status=webob.exc.HTTPOk.code)
+ response = base.NoContentTypeResponse(status=webob.exc.HTTPOk.code)
# Does the request have an origin header? (Section 6.2.1)
if 'Origin' not in request.headers:
diff --git a/oslo_middleware/healthcheck/__main__.py b/oslo_middleware/healthcheck/__main__.py
new file mode 100644
index 0000000..217fff6
--- /dev/null
+++ b/oslo_middleware/healthcheck/__main__.py
@@ -0,0 +1,69 @@
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import argparse
+
+from six.moves import SimpleHTTPServer # noqa
+from six.moves import socketserver
+import webob
+
+from oslo_middleware import healthcheck
+
+
+class HttpHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
+ def do_GET(self):
+ @webob.dec.wsgify
+ def dummy_application(req):
+ return 'test'
+ app = healthcheck.Healthcheck(dummy_application, {'detailed': True})
+ req = webob.Request.blank("/healthcheck", accept='text/html',
+ method='GET')
+ res = req.get_response(app)
+ self.send_response(res.status_code)
+ for header_name, header_value in res.headerlist:
+ self.send_header(header_name, header_value)
+ self.end_headers()
+ self.wfile.write(res.body)
+ self.wfile.close()
+
+
+def positive_int(blob):
+ value = int(blob)
+ if value < 0:
+ msg = "%r is not a positive integer" % blob
+ raise argparse.ArgumentTypeError(msg)
+ return value
+
+
+def create_server(port=0):
+ handler = HttpHandler
+ server = socketserver.TCPServer(("", port), handler)
+ return server
+
+
+def main(args=None):
+ """Runs a basic http server to show healthcheck functionality."""
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-p", "--port",
+ help="Unused port to run the tiny"
+ " http server on (or zero to select a"
+ " random unused port)",
+ type=positive_int, required=True)
+ args = parser.parse_args(args=args)
+ server = create_server(args.port)
+ print("Serving at port: %s" % server.server_address[1])
+ server.serve_forever()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/oslo_middleware/http_proxy_to_wsgi.py b/oslo_middleware/http_proxy_to_wsgi.py
index ad61401..84bc32b 100644
--- a/oslo_middleware/http_proxy_to_wsgi.py
+++ b/oslo_middleware/http_proxy_to_wsgi.py
@@ -19,7 +19,7 @@ from oslo_middleware import base
OPTS = [
cfg.BoolOpt('enable_proxy_headers_parsing',
default=False,
- help="Wether the application is behind a proxy or not. "
+ help="Whether the application is behind a proxy or not. "
"This determines if the middleware should parse the "
"headers or not.")
]
diff --git a/oslo_middleware/opts.py b/oslo_middleware/opts.py
index 1fe8c89..e66e723 100644
--- a/oslo_middleware/opts.py
+++ b/oslo_middleware/opts.py
@@ -17,7 +17,8 @@ __all__ = [
'list_opts',
'list_opts_sizelimit',
'list_opts_ssl',
- 'list_opts_cors'
+ 'list_opts_cors',
+ 'list_opts_http_proxy_to_wsgi',
]
@@ -25,6 +26,7 @@ import copy
import itertools
from oslo_middleware import cors
+from oslo_middleware import http_proxy_to_wsgi
from oslo_middleware import sizelimit
from oslo_middleware import ssl
@@ -53,6 +55,7 @@ def list_opts():
list_opts_sizelimit(),
list_opts_ssl(),
list_opts_cors(),
+ list_opts_http_proxy_to_wsgi(),
)
)
@@ -128,3 +131,27 @@ def list_opts_cors():
('cors', copy.deepcopy(cors.CORS_OPTS)),
('cors.subdomain', copy.deepcopy(cors.CORS_OPTS))
]
+
+
+def list_opts_http_proxy_to_wsgi():
+ """Return a list of oslo.config options for http_proxy_to_wsgi.
+
+ The returned list includes all oslo.config options which may be registered
+ at runtime by the library.
+
+ Each element of the list is a tuple. The first element is the name of the
+ group under which the list of elements in the second element will be
+ registered. A group name of None corresponds to the [DEFAULT] group in
+ config files.
+
+ This function is also discoverable via the 'oslo.middleware' entry point
+ under the 'oslo.config.opts' namespace.
+
+ The purpose of this is to allow tools like the Oslo sample config file
+ generator to discover the options exposed to users by this library.
+
+ :returns: a list of (group_name, opts) tuples
+ """
+ return [
+ ('oslo_middleware', copy.deepcopy(http_proxy_to_wsgi.OPTS)),
+ ]
diff --git a/oslo_middleware/tests/test_base.py b/oslo_middleware/tests/test_base.py
index ad48da5..425ff9a 100644
--- a/oslo_middleware/tests/test_base.py
+++ b/oslo_middleware/tests/test_base.py
@@ -58,6 +58,17 @@ class TestBase(BaseTestCase):
self.assertTrue(self.application.called_without_request)
+ def test_no_content_type_added(self):
+ class TestMiddleware(Middleware):
+ @staticmethod
+ def process_request(req):
+ return "foobar"
+
+ m = TestMiddleware(None)
+ request = webob.Request({}, method='GET')
+ response = request.get_response(m)
+ self.assertNotIn('Content-Type', response.headers)
+
def test_paste_deploy_legacy(self):
app = LegacyMiddlewareTest.factory(
{'global': True}, local=True)(application)
diff --git a/oslo_middleware/tests/test_healthcheck.py b/oslo_middleware/tests/test_healthcheck.py
index 3ffb03f..19fc63a 100644
--- a/oslo_middleware/tests/test_healthcheck.py
+++ b/oslo_middleware/tests/test_healthcheck.py
@@ -13,12 +13,36 @@
# License for the specific language governing permissions and limitations
# under the License.
+import threading
+import time
+
import mock
from oslotest import base as test_base
+import requests
import webob.dec
import webob.exc
from oslo_middleware import healthcheck
+from oslo_middleware.healthcheck import __main__
+
+
+class HealthcheckMainTests(test_base.BaseTestCase):
+
+ def test_startup_response(self):
+ server = __main__.create_server(0)
+ th = threading.Thread(target=server.serve_forever)
+ th.start()
+ self.addCleanup(server.shutdown)
+ while True:
+ try:
+ r = requests.get("http://%s:%s" % (server.server_address[0],
+ server.server_address[1]))
+ except requests.ConnectionError:
+ # Server hasn't started up yet, try again in a few.
+ time.sleep(1)
+ else:
+ self.assertEqual(200, r.status_code)
+ break
class HealthcheckTests(test_base.BaseTestCase):
diff --git a/requirements.txt b/requirements.txt
index f03122f..b80e5c6 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,11 +4,11 @@
pbr>=1.6 # Apache-2.0
Jinja2>=2.8 # BSD License (3 clause)
-oslo.config>=3.9.0 # Apache-2.0
-oslo.context>=2.2.0 # Apache-2.0
+oslo.config>=3.12.0 # Apache-2.0
+oslo.context>=2.4.0 # Apache-2.0
oslo.i18n>=2.1.0 # Apache-2.0
-oslo.utils>=3.5.0 # Apache-2.0
+oslo.utils>=3.15.0 # Apache-2.0
six>=1.9.0 # MIT
-stevedore>=1.9.0 # Apache-2.0
+stevedore>=1.10.0 # Apache-2.0
WebOb>=1.2.3 # MIT
debtcollector>=1.2.0 # Apache-2.0
diff --git a/setup.cfg b/setup.cfg
index 87be3b2..d2a7686 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -28,6 +28,7 @@ oslo.config.opts =
oslo.middleware.cors = oslo_middleware.opts:list_opts_cors
oslo.middleware.sizelimit = oslo_middleware.opts:list_opts_sizelimit
oslo.middleware.ssl = oslo_middleware.opts:list_opts_ssl
+ oslo.middleware.http_proxy_to_wsgi = oslo_middleware.opts:list_opts_http_proxy_to_wsgi
oslo.middleware.healthcheck =
disable_by_file = oslo_middleware.healthcheck.disable_by_file:DisableByFileHealthcheck
diff --git a/test-requirements.txt b/test-requirements.txt
index fc60e42..5f53419 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -2,11 +2,11 @@
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
-fixtures<2.0,>=1.3.1 # Apache-2.0/BSD
+fixtures>=3.0.0 # Apache-2.0/BSD
hacking<0.11,>=0.10.0
-mock>=1.2 # BSD
+mock>=2.0 # BSD
oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
oslotest>=1.10.0 # Apache-2.0
-sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
+sphinx!=1.3b1,<1.3,>=1.2.1 # BSD
testtools>=1.4.0 # MIT
coverage>=3.6 # Apache-2.0