diff --git a/devstack/plugin.sh b/devstack/plugin.sh index aefe676e0..a7cd9f73f 100755 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -111,11 +111,6 @@ function configure_zaqar { iniset $ZAQAR_CONF DEFAULT pooling True iniset $ZAQAR_CONF 'pooling:catalog' enable_virtual_pool True - if [ "CORS_ENABLED" == 'true'] ; then - iniset $ZAQAR_CONF cors - iniset $ZAQAR_CONF 'cors' enabled True - fi - # NOTE(flaper87): Configure mongodb regardless so we can use it as a pool # in tests. configure_mongodb diff --git a/devstack/settings b/devstack/settings index d115bec5a..fd5f98f6b 100644 --- a/devstack/settings +++ b/devstack/settings @@ -45,7 +45,4 @@ ZAQAR_TRUSTEE_DOMAIN=${ZAQAR_TRUSTEE_DOMAIN:-default} # Tell Tempest this project is present TEMPEST_SERVICES+=,zaqar -# CORS -CORS_ENABLED=${CORS_ENABLED:-false} - enable_service zaqar-websocket zaqar-wsgi diff --git a/doc/source/CORS.rst b/doc/source/CORS.rst index 9a6b601c3..c0cfaaab8 100644 --- a/doc/source/CORS.rst +++ b/doc/source/CORS.rst @@ -25,11 +25,6 @@ New Config Options There are some new config options. -**enabled** - -Enables CORS functions for Zaqar. The default value is "False" at this moment. -It will be turn to "True" in the future once it's stable enough. - **allowed_origin** Indicate whether this resource may be shared with the domain received in the diff --git a/releasenotes/notes/support-cors-af8349382a44aa0d.yaml b/releasenotes/notes/support-cors-af8349382a44aa0d.yaml index 1ba4d49f8..d4663153d 100644 --- a/releasenotes/notes/support-cors-af8349382a44aa0d.yaml +++ b/releasenotes/notes/support-cors-af8349382a44aa0d.yaml @@ -1,4 +1,3 @@ --- features: - - Zaqar now supports Cross-Origin Resource Sharing (CORS). It turns off by - default. Use "enable=True" in [cors] section from zaqar.conf to use it. \ No newline at end of file + - Zaqar now supports Cross-Origin Resource Sharing (CORS). \ No newline at end of file diff --git a/zaqar/common/configs.py b/zaqar/common/configs.py index 5e366e4d7..5fcbdf82b 100644 --- a/zaqar/common/configs.py +++ b/zaqar/common/configs.py @@ -118,19 +118,9 @@ _PROFILER_OPTIONS = [ _PROFILER_GROUP = "profiler" -_CORS_OPTIONS = [ - cfg.BoolOpt("enabled", default=False, - help="Whether enable Cross Origin Resource Sharing(CORS) " - "function from oslo.middleware"), -] - -_CORS_GROUP = "cors" - - def _config_options(): return [(None, _GENERAL_OPTIONS), (_DRIVER_GROUP, _DRIVER_OPTIONS), (_SIGNED_URL_GROUP, _SIGNED_URL_OPTIONS), (_NOTIFICATION_GROUP, _NOTIFICATION_OPTIONS), - (_PROFILER_GROUP, _PROFILER_OPTIONS), - (_CORS_GROUP, _CORS_OPTIONS)] + (_PROFILER_GROUP, _PROFILER_OPTIONS)] diff --git a/zaqar/transport/middleware/cors.py b/zaqar/transport/middleware/cors.py index 66c342850..b48254a7f 100644 --- a/zaqar/transport/middleware/cors.py +++ b/zaqar/transport/middleware/cors.py @@ -12,6 +12,8 @@ # 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 six.moves.urllib.parse as urlparse +import webob from oslo_log import log from oslo_middleware import cors @@ -19,10 +21,59 @@ from oslo_middleware import cors LOG = log.getLogger(__name__) +class Response(webob.Response): + + def __call__(self, environ, start_response): + """WSGI application interface""" + + if self.conditional_response: + return self.conditional_response_app(environ, start_response) + headerlist = self._abs_headerlist(environ) + start_response(self.status, headerlist) + if environ['REQUEST_METHOD'] == 'HEAD': + # Special case here... + # NOTE(wangxiyuan): webob.response.Response always return + # EmptyResponse here. This behavior breaks backward-compatibility. + # so we need to 'fix' it here manually. + return [] + return self._app_iter + + def _abs_headerlist(self, *args, **kwargs): + headerlist = super(Response, self)._abs_headerlist(*args, **kwargs) + + # NOTE(wangxiyuan): webob.response.Response always convert relative + # path to absolute path given the request environ on location field in + # the header of response. This behavior breaks backward-compatibility. + # so we need to 'fix' it here manually. + for i, (name, value) in enumerate(headerlist): + if name.lower() == 'location': + loc = urlparse.urlparse(value) + relative_path = value[value.index(loc.path):] + headerlist[i] = (name, relative_path) + break + + return headerlist + + +class Request(webob.Request): + + ResponseClass = Response + + class CORSMiddleware(object): + def __init__(self, app, auth_app, conf): + self._app = cors.CORS(app, conf) + + # We don't auth here. It's just used for keeping consistence. + self._auth_app = auth_app + + @webob.dec.wsgify(RequestClass=Request) + def __call__(self, request): + return self._app(request) + @classmethod - def install(cls, app, conf): + def install(cls, app, auth_app, conf): LOG.debug(u'Installing CORS middleware.') cors.set_defaults( @@ -47,9 +98,8 @@ class CORSMiddleware(object): 'PATCH', 'HEAD'] ) - - return cors.CORS(app, conf) + return CORSMiddleware(app, auth_app, conf) -def install_cors(app, conf): - return CORSMiddleware.install(app, conf) +def install_cors(app, auth_app, conf): + return CORSMiddleware.install(app, auth_app, conf) diff --git a/zaqar/transport/wsgi/driver.py b/zaqar/transport/wsgi/driver.py index 5b29a0cdc..4541a8416 100644 --- a/zaqar/transport/wsgi/driver.py +++ b/zaqar/transport/wsgi/driver.py @@ -156,8 +156,7 @@ class Driver(transport.DriverBase): # NOTE(wangxiyuan): Install CORS, this middleware should be called # before Keystone auth. - if self._conf.cors.enabled: - self.app = cors.install_cors(self.app, self._conf) + self.app = cors.install_cors(self.app, auth_app, self._conf) acl.setup_policy(self._conf)