Enable cluster-wide CORS Expose-Headers setting
An operator proposing a web UX to its customers might want to allow web browser to access some headers by default (eg: X-Storage-Policy, X-Container-Read, ...). This commit adds a new setting to the proxy-server to allow some headers to be added cluster-wide to the CORS header Access-Control-Expose-Headers. Change-Id: I5ca90a052f27c98a514a96ee2299bfa1b6d46334
This commit is contained in:
parent
40fefd2087
commit
9b47de3095
@ -143,6 +143,8 @@ This is very useful when one is managing more than one swift cluster.
|
||||
Use a comma separated list of full URL (http://foo.bar:1234,https://foo.bar)
|
||||
.IP \fBstrict_cors_mode\fR
|
||||
The default is true.
|
||||
.IP \fBcors_expose_headers\fR
|
||||
Comma separated list of headers to expose through Access-Control-Expose-Headers
|
||||
.IP \fBnice_priority\fR
|
||||
Modify scheduling priority of server processes. Niceness values range from -20
|
||||
(most favorable to the process) to 19 (least favorable to the process).
|
||||
|
@ -1573,6 +1573,11 @@ cors_allow_origin This is a list o
|
||||
header in addition to what
|
||||
the container has set.
|
||||
strict_cors_mode True
|
||||
cors_expose_headers This is a list of headers that
|
||||
are included in the header
|
||||
Access-Control-Expose-Headers
|
||||
in addition to what the container
|
||||
has set.
|
||||
client_timeout 60
|
||||
trans_id_suffix This optional suffix (default is empty)
|
||||
that would be appended to the swift
|
||||
|
@ -73,6 +73,9 @@ bind_port = 8080
|
||||
# cors_allow_origin =
|
||||
# strict_cors_mode = True
|
||||
#
|
||||
# Comma separated list of headers to expose through Access-Control-Expose-Headers
|
||||
# cors_expose_headers =
|
||||
#
|
||||
# client_timeout = 60
|
||||
# eventlet_debug = false
|
||||
#
|
||||
|
@ -232,6 +232,7 @@ def cors_validation(func):
|
||||
# - simple response headers,
|
||||
# http://www.w3.org/TR/cors/#simple-response-header
|
||||
# - swift specific: etag, x-timestamp, x-trans-id
|
||||
# - headers provided by the operator in cors_expose_headers
|
||||
# - user metadata headers
|
||||
# - headers provided by the user in
|
||||
# x-container-meta-access-control-expose-headers
|
||||
@ -240,6 +241,7 @@ def cors_validation(func):
|
||||
'cache-control', 'content-language', 'content-type',
|
||||
'expires', 'last-modified', 'pragma', 'etag',
|
||||
'x-timestamp', 'x-trans-id', 'x-openstack-request-id'])
|
||||
expose_headers.update(controller.app.cors_expose_headers)
|
||||
for header in resp.headers:
|
||||
if header.startswith('X-Container-Meta') or \
|
||||
header.startswith('X-Object-Meta'):
|
||||
|
@ -147,6 +147,10 @@ class Application(object):
|
||||
a.strip()
|
||||
for a in conf.get('cors_allow_origin', '').split(',')
|
||||
if a.strip()]
|
||||
self.cors_expose_headers = [
|
||||
a.strip()
|
||||
for a in conf.get('cors_expose_headers', '').split(',')
|
||||
if a.strip()]
|
||||
self.strict_cors_mode = config_true_value(
|
||||
conf.get('strict_cors_mode', 't'))
|
||||
self.node_timings = {}
|
||||
|
@ -5319,6 +5319,76 @@ class TestObjectController(unittest.TestCase):
|
||||
self.assertEqual('x-trans-id',
|
||||
resp.headers['access-control-expose-headers'])
|
||||
|
||||
def test_CORS_expose_headers(self):
|
||||
default_expected_exposed = set([
|
||||
'cache-control', 'content-language', 'content-type', 'expires',
|
||||
'last-modified', 'pragma', 'etag', 'x-timestamp', 'x-trans-id',
|
||||
'x-openstack-request-id'])
|
||||
|
||||
def objectGET(controller, req):
|
||||
return Response(headers={
|
||||
'X-Custom-Operator': 'hush',
|
||||
'X-Custom-User': 'hush',
|
||||
})
|
||||
|
||||
# test default expose_headers
|
||||
self.app.cors_expose_headers = []
|
||||
container_cors = {'allow_origin': 'http://foo.bar'}
|
||||
resp = self._get_CORS_response(container_cors=container_cors,
|
||||
strict_mode=False, object_get=objectGET)
|
||||
|
||||
self.assertEqual(200, resp.status_int)
|
||||
self.assertIn('access-control-expose-headers', resp.headers)
|
||||
exposed = set(
|
||||
h.strip() for h in
|
||||
resp.headers['access-control-expose-headers'].split(','))
|
||||
self.assertEqual(default_expected_exposed, exposed)
|
||||
|
||||
# test operator expose_headers
|
||||
self.app.cors_expose_headers = ['x-custom-operator', ]
|
||||
container_cors = {'allow_origin': 'http://foo.bar'}
|
||||
resp = self._get_CORS_response(container_cors=container_cors,
|
||||
strict_mode=False, object_get=objectGET)
|
||||
|
||||
self.assertEqual(200, resp.status_int)
|
||||
self.assertIn('access-control-expose-headers', resp.headers)
|
||||
exposed = set(
|
||||
h.strip() for h in
|
||||
resp.headers['access-control-expose-headers'].split(','))
|
||||
self.assertEqual(default_expected_exposed | set(['x-custom-operator']),
|
||||
exposed)
|
||||
|
||||
# test user expose_headers
|
||||
self.app.cors_expose_headers = []
|
||||
container_cors = {'allow_origin': 'http://foo.bar',
|
||||
'expose_headers': 'x-custom-user'}
|
||||
resp = self._get_CORS_response(container_cors=container_cors,
|
||||
strict_mode=False, object_get=objectGET)
|
||||
|
||||
self.assertEqual(200, resp.status_int)
|
||||
self.assertIn('access-control-expose-headers', resp.headers)
|
||||
exposed = set(
|
||||
h.strip() for h in
|
||||
resp.headers['access-control-expose-headers'].split(','))
|
||||
self.assertEqual(default_expected_exposed | set(['x-custom-user']),
|
||||
exposed)
|
||||
|
||||
# test user and operator expose_headers
|
||||
self.app.cors_expose_headers = ['x-custom-operator', ]
|
||||
container_cors = {'allow_origin': 'http://foo.bar',
|
||||
'expose_headers': 'x-custom-user'}
|
||||
resp = self._get_CORS_response(container_cors=container_cors,
|
||||
strict_mode=False, object_get=objectGET)
|
||||
|
||||
self.assertEqual(200, resp.status_int)
|
||||
self.assertIn('access-control-expose-headers', resp.headers)
|
||||
exposed = set(
|
||||
h.strip() for h in
|
||||
resp.headers['access-control-expose-headers'].split(','))
|
||||
self.assertEqual(default_expected_exposed | set(['x-custom-user',
|
||||
'x-custom-operator']),
|
||||
exposed)
|
||||
|
||||
def _gather_x_container_headers(self, controller_call, req, *connect_args,
|
||||
**kwargs):
|
||||
header_list = kwargs.pop('header_list', ['X-Container-Device',
|
||||
|
Loading…
x
Reference in New Issue
Block a user