diff --git a/cinder/api/middleware/auth.py b/cinder/api/middleware/auth.py index 66e44a13ff7..9789e1b146a 100644 --- a/cinder/api/middleware/auth.py +++ b/cinder/api/middleware/auth.py @@ -22,6 +22,7 @@ import os from oslo_config import cfg from oslo_log import log as logging +from oslo_middleware import request_id from oslo_serialization import jsonutils import webob.dec import webob.exc @@ -29,7 +30,6 @@ import webob.exc from cinder.api.openstack import wsgi from cinder import context from cinder.i18n import _ -from cinder.openstack.common.middleware import request_id from cinder import wsgi as base_wsgi diff --git a/cinder/api/middleware/sizelimit.py b/cinder/api/middleware/sizelimit.py index 97a4d125f6d..671945d395b 100644 --- a/cinder/api/middleware/sizelimit.py +++ b/cinder/api/middleware/sizelimit.py @@ -13,17 +13,14 @@ # under the License. """ Request Body limiting middleware. - +Compatibility shim for Kilo, while operators migrate to oslo.middleware. """ from oslo_config import cfg -from oslo_log import log as logging -import webob.dec -import webob.exc +from oslo_middleware import sizelimit -from cinder.i18n import _ -from cinder import wsgi +from cinder.openstack.common import versionutils # Default request size is 112k @@ -34,52 +31,9 @@ max_request_body_size_opt = cfg.IntOpt('osapi_max_request_body_size', CONF = cfg.CONF CONF.register_opt(max_request_body_size_opt) -LOG = logging.getLogger(__name__) - -class LimitingReader(object): - """Reader to limit the size of an incoming request.""" - def __init__(self, data, limit): - """Initialize LimitingReader. - - :param data: Underlying data object - :param limit: maximum number of bytes the reader should allow - """ - self.data = data - self.limit = limit - self.bytes_read = 0 - - def __iter__(self): - for chunk in self.data: - self.bytes_read += len(chunk) - if self.bytes_read > self.limit: - msg = _("Request is too large.") - raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg) - else: - yield chunk - - def read(self, i=None): - result = self.data.read(i) - self.bytes_read += len(result) - if self.bytes_read > self.limit: - msg = _("Request is too large.") - raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg) - return result - - -class RequestBodySizeLimiter(wsgi.Middleware): +@versionutils.deprecated(as_of=versionutils.deprecated.KILO, + in_favor_of='oslo_middleware.RequestBodySizeLimiter') +class RequestBodySizeLimiter(sizelimit.RequestBodySizeLimiter): """Add a 'cinder.context' to WSGI environ.""" - - def __init__(self, *args, **kwargs): - super(RequestBodySizeLimiter, self).__init__(*args, **kwargs) - - @webob.dec.wsgify(RequestClass=wsgi.Request) - def __call__(self, req): - if req.content_length > CONF.osapi_max_request_body_size: - msg = _("Request is too large.") - raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg) - if req.content_length is None and req.is_body_readable: - limiter = LimitingReader(req.body_file, - CONF.osapi_max_request_body_size) - req.body_file = limiter - return self.application + pass diff --git a/cinder/openstack/common/middleware/base.py b/cinder/openstack/common/middleware/base.py deleted file mode 100644 index 464a1ccd72e..00000000000 --- a/cinder/openstack/common/middleware/base.py +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2011 OpenStack Foundation. -# All Rights Reserved. -# -# 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. - -"""Base class(es) for WSGI Middleware.""" - -import webob.dec - - -class Middleware(object): - """Base WSGI middleware wrapper. - - These classes require an application to be initialized that will be called - next. By default the middleware will simply call its wrapped app, or you - can override __call__ to customize its behavior. - """ - - @classmethod - def factory(cls, global_conf, **local_conf): - """Factory method for paste.deploy.""" - return cls - - def __init__(self, application): - self.application = application - - def process_request(self, req): - """Called on each request. - - If this returns None, the next application down the stack will be - executed. If it returns a response then that response will be returned - and execution will stop here. - """ - return None - - def process_response(self, response): - """Do whatever you'd like to the response.""" - return response - - @webob.dec.wsgify - def __call__(self, req): - response = self.process_request(req) - if response: - return response - response = req.get_response(self.application) - return self.process_response(response) diff --git a/cinder/openstack/common/middleware/catch_errors.py b/cinder/openstack/common/middleware/catch_errors.py index 727372bf1c2..db5356c9740 100644 --- a/cinder/openstack/common/middleware/catch_errors.py +++ b/cinder/openstack/common/middleware/catch_errors.py @@ -12,12 +12,12 @@ """Compatibility shim for Kilo, while operators migrate to oslo.middleware.""" -from oslo.middleware import catch_errors +from oslo_middleware import catch_errors from cinder.openstack.common import versionutils @versionutils.deprecated(as_of=versionutils.deprecated.KILO, - in_favor_of='oslo.middleware.CatchErrors') + in_favor_of='oslo_middleware.CatchErrors') class CatchErrorsMiddleware(catch_errors.CatchErrors): pass diff --git a/cinder/openstack/common/middleware/request_id.py b/cinder/openstack/common/middleware/request_id.py index d5d0bfc4c92..8c6c11c47a4 100644 --- a/cinder/openstack/common/middleware/request_id.py +++ b/cinder/openstack/common/middleware/request_id.py @@ -12,7 +12,7 @@ """Compatibility shim for Kilo, while operators migrate to oslo.middleware.""" -from oslo.middleware import request_id +from oslo_middleware import request_id from cinder.openstack.common import versionutils @@ -22,6 +22,6 @@ HTTP_RESP_HEADER_REQUEST_ID = 'x-openstack-request-id' @versionutils.deprecated(as_of=versionutils.deprecated.KILO, - in_favor_of='oslo.middleware.RequestId') + in_favor_of='oslo_middleware.RequestId') class RequestIdMiddleware(request_id.RequestId): pass diff --git a/cinder/tests/api/middleware/test_auth.py b/cinder/tests/api/middleware/test_auth.py index bf602d7d4c9..fbcde10191f 100644 --- a/cinder/tests/api/middleware/test_auth.py +++ b/cinder/tests/api/middleware/test_auth.py @@ -12,10 +12,10 @@ # License for the specific language governing permissions and limitations # under the License. +from oslo_middleware import request_id import webob import cinder.api.middleware.auth -from cinder.openstack.common.middleware import request_id from cinder import test diff --git a/cinder/tests/api/middleware/test_sizelimit.py b/cinder/tests/api/middleware/test_sizelimit.py deleted file mode 100644 index 3b0a778f782..00000000000 --- a/cinder/tests/api/middleware/test_sizelimit.py +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation -# -# 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. - -from oslo_config import cfg -import six -import webob - -from cinder.api.middleware import sizelimit -from cinder import test - - -CONF = cfg.CONF - -MAX_REQUEST_BODY_SIZE = CONF.osapi_max_request_body_size - - -class TestLimitingReader(test.TestCase): - - def test_limiting_reader(self): - BYTES = 1024 - bytes_read = 0 - data = six.StringIO("*" * BYTES) - for chunk in sizelimit.LimitingReader(data, BYTES): - bytes_read += len(chunk) - - self.assertEqual(bytes_read, BYTES) - - bytes_read = 0 - data = six.StringIO("*" * BYTES) - reader = sizelimit.LimitingReader(data, BYTES) - byte = reader.read(1) - while len(byte) != 0: - bytes_read += 1 - byte = reader.read(1) - - self.assertEqual(bytes_read, BYTES) - - def test_limiting_reader_fails(self): - BYTES = 1024 - - def _consume_all_iter(): - bytes_read = 0 - data = six.StringIO("*" * BYTES) - for chunk in sizelimit.LimitingReader(data, BYTES - 1): - bytes_read += len(chunk) - - self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, - _consume_all_iter) - - def _consume_all_read(): - bytes_read = 0 - data = six.StringIO("*" * BYTES) - reader = sizelimit.LimitingReader(data, BYTES - 1) - byte = reader.read(1) - while len(byte) != 0: - bytes_read += 1 - byte = reader.read(1) - - self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, - _consume_all_read) - - -class TestRequestBodySizeLimiter(test.TestCase): - - def setUp(self): - super(TestRequestBodySizeLimiter, self).setUp() - - @webob.dec.wsgify() - def fake_app(req): - return webob.Response(req.body) - - self.middleware = sizelimit.RequestBodySizeLimiter(fake_app) - self.request = webob.Request.blank('/', method='POST') - - def test_content_length_acceptable(self): - self.request.headers['Content-Length'] = MAX_REQUEST_BODY_SIZE - self.request.body = "0" * MAX_REQUEST_BODY_SIZE - response = self.request.get_response(self.middleware) - self.assertEqual(response.status_int, 200) - - def test_content_length_too_large(self): - self.request.headers['Content-Length'] = MAX_REQUEST_BODY_SIZE + 1 - self.request.body = "0" * (MAX_REQUEST_BODY_SIZE + 1) - response = self.request.get_response(self.middleware) - self.assertEqual(response.status_int, 413) - - def test_request_too_large_no_content_length(self): - self.request.body = "0" * (MAX_REQUEST_BODY_SIZE + 1) - self.request.headers['Content-Length'] = None - response = self.request.get_response(self.middleware) - self.assertEqual(response.status_int, 413) diff --git a/etc/cinder/api-paste.ini b/etc/cinder/api-paste.ini index ba922d5f814..b2822b044db 100644 --- a/etc/cinder/api-paste.ini +++ b/etc/cinder/api-paste.ini @@ -21,7 +21,7 @@ keystone = request_id faultwrap sizelimit osprofiler authtoken keystonecontext a keystone_nolimit = request_id faultwrap sizelimit osprofiler authtoken keystonecontext apiv2 [filter:request_id] -paste.filter_factory = cinder.openstack.common.middleware.request_id:RequestIdMiddleware.factory +paste.filter_factory = oslo_middleware.request_id:RequestId.factory [filter:faultwrap] paste.filter_factory = cinder.api.middleware.fault:FaultWrapper.factory diff --git a/requirements.txt b/requirements.txt index 607349893a8..c426d3aa80d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,6 +18,7 @@ oslo.context>=0.1.0 oslo.db>=1.4.1 # Apache-2.0 oslo.log>=0.4.0 # Apache-2.0 oslo.messaging>=1.6.0 # Apache-2.0 +oslo.middleware>=0.3.0 # Apache-2.0 oslo.rootwrap>=1.5.0 # Apache-2.0 oslo.serialization>=1.2.0 # Apache-2.0 oslo.utils>=1.2.0 # Apache-2.0 diff --git a/setup.cfg b/setup.cfg index f6f0bf6aba9..36b6f18b080 100644 --- a/setup.cfg +++ b/setup.cfg @@ -59,6 +59,10 @@ oslo_messaging.notify.drivers = cinder.openstack.common.notifier.rpc_notifier2 = oslo_messaging.notify._impl_messaging:MessagingV2Driver cinder.openstack.common.notifier.rpc_notifier = oslo_messaging.notify._impl_messaging:MessagingDriver cinder.openstack.common.notifier.test_notifier = oslo_messaging.notify._impl_test:TestDriver +# These are for backwards compatibility with Juno middleware configurations +oslo_middleware = + cinder.api.middleware.sizelimit = oslo_middleware.sizelimit + cinder.openstack.common.middleware.request_id = oslo_middleware.request_id cinder.database.migration_backend = sqlalchemy = oslo_db.sqlalchemy.migration