Support CORS
Add the new middleware CORS for Zaqar It only supports for WSGI. Websocket doesn't need this feature. Change-Id: Ifc6d2d1c5dde5152cab6e3aa2f3cf9f207481267 Implements: blueprint support-cors
This commit is contained in:
parent
66e90d3b25
commit
e501f4013e
@ -111,6 +111,11 @@ 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
|
||||
|
@ -45,5 +45,7 @@ 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
|
||||
|
125
doc/source/CORS.rst
Normal file
125
doc/source/CORS.rst
Normal file
@ -0,0 +1,125 @@
|
||||
..
|
||||
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.
|
||||
|
||||
==========
|
||||
CORS Guide
|
||||
==========
|
||||
|
||||
Zaqar supports Cross-Origin Resource Sharing (CORS) now. The function is
|
||||
provided by oslo.middleware. Please see `Official Doc`_ and `OpenStack Spec`_
|
||||
for more detail. This guide is mainly tell users how to use it in Zaqar.
|
||||
|
||||
|
||||
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
|
||||
requests "origin" header. Format: "<protocol>://<host>[:<port>]", no trailing
|
||||
slash. Example: https://horizon.example.com'.
|
||||
|
||||
**allow_credentials**
|
||||
|
||||
Indicate that the actual request can include user credentials. The default
|
||||
value is True.
|
||||
|
||||
**expose_headers**
|
||||
|
||||
Indicate which headers are safe to expose to the API. Defaults to HTTP Simple
|
||||
Headers. The default value is [].
|
||||
|
||||
**max_age**
|
||||
|
||||
Maximum cache age of CORS preflight requests. The default value is 3600.
|
||||
|
||||
**allow_methods**
|
||||
|
||||
Indicate which methods can be used during the actual request. The default value
|
||||
is ['OPTIONS', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'PATCH'].
|
||||
|
||||
**allow_headers**
|
||||
|
||||
Indicate which header field names may be used during the actual request. The
|
||||
default value is [].
|
||||
|
||||
|
||||
Request and Response example
|
||||
----------------------------
|
||||
To use CORS, you should make sure that the feature is enabled::
|
||||
|
||||
[cors]
|
||||
enabled = true
|
||||
allowed_origin = http://example
|
||||
allow_methods = GET
|
||||
|
||||
the above example config options mean that Zaqar only receive the GET request
|
||||
from http://example domain. Here are some example request:
|
||||
1. Zaqar will do nothing if the request doesn't contain "Origin" header::
|
||||
|
||||
# curl -I -X GET http://10.229.47.217:8888 -H "Accept: application/json"
|
||||
|
||||
HTTP/1.1 300 Multiple Choices
|
||||
content-length: 668
|
||||
content-type: application/json; charset=UTF-8
|
||||
Connection: close
|
||||
|
||||
2. Zaqar will return nothing in response headers if the "Origin" is not in
|
||||
``allowed_origin``::
|
||||
|
||||
# curl -I -X GET http://10.229.47.217:8888 -H "Accept: application/json" -H "Origin: http://"
|
||||
|
||||
HTTP/1.1 300 Multiple Choices
|
||||
content-length: 668
|
||||
content-type: application/json; charset=UTF-8
|
||||
Connection: close
|
||||
|
||||
In the Zaqar log, we can see a message::
|
||||
|
||||
CORS request from origin 'http://' not permitted.
|
||||
|
||||
3. Zaqar will return CORS information if the "Origin" header is in
|
||||
``allowed_origin``::
|
||||
|
||||
# curl -I -X GET http://10.229.47.217:8888 -H "Accept: application/json" -H "Origin: http://example"
|
||||
|
||||
HTTP/1.1 300 Multiple Choices
|
||||
content-length: 668
|
||||
content-type: application/json; charset=UTF-8
|
||||
Vary: Origin
|
||||
Access-Control-Allow-Origin: http://example
|
||||
Access-Control-Allow-Credentials: true
|
||||
Connection: close
|
||||
|
||||
4. Zaqar will return more information if the request doesn't follow Zaqar's\
|
||||
CORS rule::
|
||||
|
||||
# curl -I -X PUT http://10.229.47.217:8888 -H "Accept: application/json" -H "Origin: http://example"
|
||||
HTTP/1.1 405 Method Not Allowed
|
||||
content-length: 0
|
||||
content-type: application/json; charset=UTF-8
|
||||
allow: GET, OPTIONS
|
||||
Vary: Origin
|
||||
Access-Control-Allow-Origin: http://example
|
||||
Access-Control-Allow-Credentials: true
|
||||
Connection: close
|
||||
|
||||
.. _Official Doc: http://docs.openstack.org/developer/osprofiler/background.html
|
||||
.. _OpenStack Spec: http://specs.openstack.org/openstack/openstack-specs/specs/cors-support.html
|
@ -16,7 +16,7 @@ OSprofiler Guide
|
||||
================
|
||||
|
||||
OSprofiler is a library from oslo. It's used for performance analysis. Please
|
||||
see `Office Doc`_ for more detail.
|
||||
see `Official Doc`_ for more detail.
|
||||
|
||||
Preparation
|
||||
-----------
|
||||
@ -121,4 +121,4 @@ Then you can open the file "list_test" to get the result.
|
||||
.. note:: If you used MQ for data transfer, the "--connection-string" here
|
||||
could be ignored or set it to your Ceilometer endpoint.
|
||||
|
||||
.. _Office Doc: http://docs.openstack.org/developer/osprofiler/background.html
|
||||
.. _Official Doc: http://docs.openstack.org/developer/osprofiler/background.html
|
||||
|
@ -189,6 +189,7 @@ Feature Guide
|
||||
|
||||
subscription_confirm
|
||||
OSprofiler
|
||||
CORS
|
||||
|
||||
Other resources
|
||||
===============
|
||||
|
@ -15,5 +15,6 @@ namespace = zaqar.transport.validation
|
||||
namespace = keystonemiddleware.auth_token
|
||||
namespace = oslo.cache
|
||||
namespace = oslo.messaging
|
||||
namespace = oslo.middleware.cors
|
||||
namespace = osprofiler
|
||||
namespace = oslo.reports
|
||||
|
4
releasenotes/notes/support-cors-af8349382a44aa0d.yaml
Normal file
4
releasenotes/notes/support-cors-af8349382a44aa0d.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
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.
|
@ -104,6 +104,7 @@ _NOTIFICATION_OPTIONS = (
|
||||
|
||||
_NOTIFICATION_GROUP = 'notification'
|
||||
|
||||
|
||||
_PROFILER_OPTIONS = [
|
||||
cfg.BoolOpt("trace_wsgi_transport", default=False,
|
||||
help="If False doesn't trace any transport requests."
|
||||
@ -117,9 +118,19 @@ _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)]
|
||||
(_PROFILER_GROUP, _PROFILER_OPTIONS),
|
||||
(_CORS_GROUP, _CORS_OPTIONS)]
|
||||
|
55
zaqar/transport/middleware/cors.py
Normal file
55
zaqar/transport/middleware/cors.py
Normal file
@ -0,0 +1,55 @@
|
||||
# Copyright 2017 OpenStack, Inc.
|
||||
# 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.
|
||||
|
||||
from oslo_log import log
|
||||
from oslo_middleware import cors
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class CORSMiddleware(object):
|
||||
|
||||
@classmethod
|
||||
def install(cls, app, conf):
|
||||
|
||||
LOG.debug(u'Installing CORS middleware.')
|
||||
cors.set_defaults(
|
||||
allow_headers=['X-Auth-Token',
|
||||
'X-Identity-Status',
|
||||
'X-Roles',
|
||||
'X-Service-Catalog',
|
||||
'X-User-Id',
|
||||
'X-Tenant-Id',
|
||||
'X-OpenStack-Request-ID',
|
||||
'X-Trace-Info',
|
||||
'X-Trace-HMAC',
|
||||
'Client-id'],
|
||||
expose_headers=['X-Auth-Token',
|
||||
'X-Subject-Token',
|
||||
'X-Service-Token',
|
||||
'X-OpenStack-Request-ID'],
|
||||
allow_methods=['GET',
|
||||
'PUT',
|
||||
'POST',
|
||||
'DELETE',
|
||||
'PATCH',
|
||||
'HEAD']
|
||||
)
|
||||
|
||||
return cors.CORS(app, conf)
|
||||
|
||||
|
||||
def install_cors(app, conf):
|
||||
return CORSMiddleware.install(app, conf)
|
@ -29,6 +29,7 @@ from zaqar.i18n import _
|
||||
from zaqar import transport
|
||||
from zaqar.transport import acl
|
||||
from zaqar.transport.middleware import auth
|
||||
from zaqar.transport.middleware import cors
|
||||
from zaqar.transport.middleware import profile
|
||||
from zaqar.transport import validation
|
||||
from zaqar.transport.wsgi import v1_0
|
||||
@ -153,6 +154,11 @@ class Driver(transport.DriverBase):
|
||||
|
||||
self.app = auth.SignedHeadersAuth(self.app, auth_app)
|
||||
|
||||
# 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)
|
||||
|
||||
acl.setup_policy(self._conf)
|
||||
|
||||
def _error_handler(self, exc, request, response, params):
|
||||
|
Loading…
Reference in New Issue
Block a user