Merge "Transcribe more headers for responses"
This commit is contained in:
commit
18ca28450d
18
etc/object-server.conf-sample
Normal file
18
etc/object-server.conf-sample
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
|
||||||
|
[pipeline:main]
|
||||||
|
# This is the minimum pipeline for Swift (and Swift3)
|
||||||
|
pipeline = object-server
|
||||||
|
|
||||||
|
[app:object-server]
|
||||||
|
use = egg:swift#object
|
||||||
|
# Comma separated list of headers that can be set in metadata on an object.
|
||||||
|
# This list is in addition to X-Object-Meta-* headers and cannot include
|
||||||
|
# Content-Type, etag, Content-Length, or deleted
|
||||||
|
#
|
||||||
|
# Note that S3 allows more headers than the default Swift object-server
|
||||||
|
# configuration. In particular, You may need to add Cache-Control,
|
||||||
|
# Content-Language, Expires, and X-Robots-Tag
|
||||||
|
allowed_headers = Cache-Control, Content-Disposition, Content-Encoding,
|
||||||
|
Content-Language, Expires, X-Delete-At, X-Object-Manifest, X-Robots-Tag,
|
||||||
|
X-Static-Large-Object
|
@ -102,7 +102,9 @@ class Response(ResponseBase, swob.Response):
|
|||||||
headers['x-amz-meta-' + _key[14:]] = val
|
headers['x-amz-meta-' + _key[14:]] = val
|
||||||
elif _key in ('content-length', 'content-type',
|
elif _key in ('content-length', 'content-type',
|
||||||
'content-range', 'content-encoding',
|
'content-range', 'content-encoding',
|
||||||
'etag', 'last-modified'):
|
'content-disposition', 'content-language',
|
||||||
|
'etag', 'last-modified', 'x-robots-tag',
|
||||||
|
'cache-control', 'expires'):
|
||||||
headers[key] = val
|
headers[key] = val
|
||||||
elif _key == 'x-static-large-object':
|
elif _key == 'x-static-large-object':
|
||||||
# for delete slo
|
# for delete slo
|
||||||
|
@ -12,3 +12,6 @@ pipeline = object-server
|
|||||||
|
|
||||||
[app:object-server]
|
[app:object-server]
|
||||||
use = egg:swift#object
|
use = egg:swift#object
|
||||||
|
allowed_headers = Cache-Control, Content-Disposition, Content-Encoding,
|
||||||
|
Content-Language, Expires, X-Delete-At, X-Object-Manifest, X-Robots-Tag,
|
||||||
|
X-Static-Large-Object
|
||||||
|
@ -278,21 +278,47 @@ class TestSwift3Object(Swift3FunctionalTestCase):
|
|||||||
self.assertCommonResponseHeaders(headers)
|
self.assertCommonResponseHeaders(headers)
|
||||||
self._assertObjectEtag(self.bucket, obj, etag)
|
self._assertObjectEtag(self.bucket, obj, etag)
|
||||||
|
|
||||||
def test_put_object_metadata(self):
|
def _test_put_object_headers(self, req_headers):
|
||||||
obj = 'object'
|
obj = 'object'
|
||||||
content = 'abcdefghij'
|
content = 'abcdefghij'
|
||||||
etag = md5(content).hexdigest()
|
etag = md5(content).hexdigest()
|
||||||
headers = {'X-Amz-Meta-Bar': 'foo', 'X-Amz-Meta-Bar2': 'foo2'}
|
|
||||||
status, headers, body = \
|
status, headers, body = \
|
||||||
self.conn.make_request('PUT', self.bucket, obj, headers, content)
|
self.conn.make_request('PUT', self.bucket, obj,
|
||||||
|
req_headers, content)
|
||||||
self.assertEquals(status, 200)
|
self.assertEquals(status, 200)
|
||||||
status, headers, body = \
|
status, headers, body = \
|
||||||
self.conn.make_request('HEAD', self.bucket, obj)
|
self.conn.make_request('HEAD', self.bucket, obj)
|
||||||
self.assertEquals(headers['x-amz-meta-bar'], 'foo')
|
for header, value in req_headers.items():
|
||||||
self.assertEquals(headers['x-amz-meta-bar2'], 'foo2')
|
self.assertIn(header.lower(), headers)
|
||||||
|
self.assertEquals(headers[header.lower()], value)
|
||||||
self.assertCommonResponseHeaders(headers)
|
self.assertCommonResponseHeaders(headers)
|
||||||
self._assertObjectEtag(self.bucket, obj, etag)
|
self._assertObjectEtag(self.bucket, obj, etag)
|
||||||
|
|
||||||
|
def test_put_object_metadata(self):
|
||||||
|
self._test_put_object_headers({
|
||||||
|
'X-Amz-Meta-Bar': 'foo',
|
||||||
|
'X-Amz-Meta-Bar2': 'foo2'})
|
||||||
|
|
||||||
|
def test_put_object_content_headers(self):
|
||||||
|
self._test_put_object_headers({
|
||||||
|
'Content-Type': 'foo/bar',
|
||||||
|
'Content-Encoding': 'baz',
|
||||||
|
'Content-Disposition': 'attachment',
|
||||||
|
'Content-Language': 'en'})
|
||||||
|
|
||||||
|
def test_put_object_cache_control(self):
|
||||||
|
self._test_put_object_headers({
|
||||||
|
'Cache-Control': 'private, some-extension'})
|
||||||
|
|
||||||
|
def test_put_object_expires(self):
|
||||||
|
self._test_put_object_headers({
|
||||||
|
# We don't validate that the Expires header is a valid date
|
||||||
|
'Expires': 'a valid HTTP-date timestamp'})
|
||||||
|
|
||||||
|
def test_put_object_robots_tag(self):
|
||||||
|
self._test_put_object_headers({
|
||||||
|
'X-Robots-Tag': 'googlebot: noarchive'})
|
||||||
|
|
||||||
def test_put_object_storage_class(self):
|
def test_put_object_storage_class(self):
|
||||||
obj = 'object'
|
obj = 'object'
|
||||||
content = 'abcdefghij'
|
content = 'abcdefghij'
|
||||||
|
@ -60,9 +60,14 @@ class TestSwift3Obj(Swift3TestCase):
|
|||||||
|
|
||||||
self.response_headers = {'Content-Type': 'text/html',
|
self.response_headers = {'Content-Type': 'text/html',
|
||||||
'Content-Length': len(self.object_body),
|
'Content-Length': len(self.object_body),
|
||||||
|
'Content-Disposition': 'inline',
|
||||||
|
'Content-Language': 'en',
|
||||||
'x-object-meta-test': 'swift',
|
'x-object-meta-test': 'swift',
|
||||||
'etag': self.etag,
|
'etag': self.etag,
|
||||||
'last-modified': self.last_modified}
|
'last-modified': self.last_modified,
|
||||||
|
'expires': 'Mon, 21 Sep 2015 12:00:00 GMT',
|
||||||
|
'x-robots-tag': 'nofollow',
|
||||||
|
'cache-control': 'private'}
|
||||||
|
|
||||||
self.swift.register('GET', '/v1/AUTH_test/bucket/object',
|
self.swift.register('GET', '/v1/AUTH_test/bucket/object',
|
||||||
swob.HTTPOk, self.response_headers,
|
swob.HTTPOk, self.response_headers,
|
||||||
@ -81,16 +86,27 @@ class TestSwift3Obj(Swift3TestCase):
|
|||||||
status, headers, body = self.call_swift3(req)
|
status, headers, body = self.call_swift3(req)
|
||||||
self.assertEquals(status.split()[0], '200')
|
self.assertEquals(status.split()[0], '200')
|
||||||
|
|
||||||
|
unexpected_headers = []
|
||||||
for key, val in self.response_headers.iteritems():
|
for key, val in self.response_headers.iteritems():
|
||||||
if key in ('content-length', 'content-type', 'content-encoding',
|
if key in ('Content-Length', 'Content-Type', 'content-encoding',
|
||||||
'last-modified'):
|
'last-modified', 'cache-control', 'Content-Disposition',
|
||||||
self.assertTrue(key in headers)
|
'Content-Language', 'expires', 'x-robots-tag'):
|
||||||
self.assertEquals(headers[key], val)
|
self.assertIn(key, headers)
|
||||||
|
self.assertEquals(headers[key], str(val))
|
||||||
|
|
||||||
|
elif key == 'etag':
|
||||||
|
self.assertEquals(headers[key], '"%s"' % val)
|
||||||
|
|
||||||
elif key.startswith('x-object-meta-'):
|
elif key.startswith('x-object-meta-'):
|
||||||
self.assertTrue('x-amz-meta-' + key[14:] in headers)
|
self.assertIn('x-amz-meta-' + key[14:], headers)
|
||||||
self.assertEquals(headers['x-amz-meta-' + key[14:]], val)
|
self.assertEquals(headers['x-amz-meta-' + key[14:]], val)
|
||||||
|
|
||||||
|
else:
|
||||||
|
unexpected_headers.append((key, val))
|
||||||
|
|
||||||
|
if unexpected_headers:
|
||||||
|
self.fail('unexpected headers: %r' % unexpected_headers)
|
||||||
|
|
||||||
self.assertEquals(headers['etag'],
|
self.assertEquals(headers['etag'],
|
||||||
'"%s"' % self.response_headers['etag'])
|
'"%s"' % self.response_headers['etag'])
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user