Merge "Allow clients to send quoted ETags for static links"
This commit is contained in:
commit
2b7e80217d
@ -211,7 +211,7 @@ from swift.common.request_helpers import get_sys_meta_prefix, \
|
||||
update_ignore_range_header
|
||||
from swift.common.swob import Request, HTTPBadRequest, HTTPTemporaryRedirect, \
|
||||
HTTPException, HTTPConflict, HTTPPreconditionFailed, wsgi_quote, \
|
||||
wsgi_unquote, status_map
|
||||
wsgi_unquote, status_map, normalize_etag
|
||||
from swift.common.http import is_success, HTTP_NOT_FOUND
|
||||
from swift.common.exceptions import LinkIterError
|
||||
from swift.common.header_key_dict import HeaderKeyDict
|
||||
@ -285,7 +285,7 @@ def _validate_and_prep_request_headers(req):
|
||||
raise HTTPBadRequest(
|
||||
body='Symlink cannot target itself',
|
||||
request=req, content_type='text/plain')
|
||||
etag = req.headers.get(TGT_ETAG_SYMLINK_HDR, None)
|
||||
etag = normalize_etag(req.headers.get(TGT_ETAG_SYMLINK_HDR, None))
|
||||
if etag and any(c in etag for c in ';"\\'):
|
||||
# See cgi.parse_header for why the above chars are problematic
|
||||
raise HTTPBadRequest(
|
||||
|
@ -1562,7 +1562,7 @@ class TestSymlinkSlo(Base):
|
||||
self.env.container2.name, 'manifest-abcde'),
|
||||
'X-Symlink-Target-Etag': slo_etag,
|
||||
})
|
||||
self.assert_status(400) # no quotes allowed!
|
||||
self.assert_status(409) # quotes OK, but doesn't match
|
||||
|
||||
# try the slo etag w/o the quotes
|
||||
slo_etag = slo_etag.strip('"')
|
||||
@ -1571,7 +1571,7 @@ class TestSymlinkSlo(Base):
|
||||
self.env.container2.name, 'manifest-abcde'),
|
||||
'X-Symlink-Target-Etag': slo_etag,
|
||||
})
|
||||
self.assert_status(409) # that just doesn't match
|
||||
self.assert_status(409) # that still doesn't match
|
||||
|
||||
def test_static_link_target_symlink_to_slo_manifest(self):
|
||||
# write symlink
|
||||
|
@ -144,6 +144,33 @@ class TestSymlinkMiddleware(TestSymlinkMiddlewareBase):
|
||||
self.assertEqual('application/foo',
|
||||
self.app._calls[-1].headers['Content-Type'])
|
||||
|
||||
def test_symlink_simple_put_with_quoted_etag(self):
|
||||
self.app.register('HEAD', '/v1/a/c1/o', swob.HTTPOk, {
|
||||
'Etag': 'tgt-etag', 'Content-Length': 42,
|
||||
'Content-Type': 'application/foo'})
|
||||
self.app.register('PUT', '/v1/a/c/symlink', swob.HTTPCreated, {})
|
||||
req = Request.blank('/v1/a/c/symlink', method='PUT',
|
||||
headers={
|
||||
'X-Symlink-Target': 'c1/o',
|
||||
'X-Symlink-Target-Etag': '"tgt-etag"',
|
||||
}, body='')
|
||||
status, headers, body = self.call_sym(req)
|
||||
self.assertEqual(status, '201 Created')
|
||||
method, path, hdrs = self.app.calls_with_headers[1]
|
||||
val = hdrs.get('X-Object-Sysmeta-Symlink-Target')
|
||||
self.assertEqual(val, 'c1/o')
|
||||
self.assertNotIn('X-Object-Sysmeta-Symlink-Target-Account', hdrs)
|
||||
val = hdrs.get('X-Object-Sysmeta-Container-Update-Override-Etag')
|
||||
self.assertEqual(val, '%s; symlink_target=c1/o; '
|
||||
'symlink_target_etag=tgt-etag; '
|
||||
'symlink_target_bytes=42' % MD5_OF_EMPTY_STRING)
|
||||
self.assertEqual([
|
||||
('HEAD', '/v1/a/c1/o'),
|
||||
('PUT', '/v1/a/c/symlink'),
|
||||
], self.app.calls)
|
||||
self.assertEqual('application/foo',
|
||||
self.app._calls[-1].headers['Content-Type'])
|
||||
|
||||
def test_symlink_simple_put_with_etag_target_missing_content_type(self):
|
||||
self.app.register('HEAD', '/v1/a/c1/o', swob.HTTPOk, {
|
||||
'Etag': 'tgt-etag', 'Content-Length': 42})
|
||||
@ -1094,15 +1121,14 @@ class SymlinkCopyingTestCase(TestSymlinkMiddlewareBase):
|
||||
}, body='')
|
||||
status, headers, body = self.call_sym(req)
|
||||
self.assertEqual(status, '409 Conflict')
|
||||
# the quoted slo-etag is just straight up invalid
|
||||
# the quoted slo-etag is tolerated, but still doesn't match
|
||||
req = Request.blank('/v1/a/c/symlink', method='PUT',
|
||||
headers={
|
||||
'X-Symlink-Target': 'c1/o',
|
||||
'X-Symlink-Target-Etag': '"slo-etag"',
|
||||
}, body='')
|
||||
status, headers, body = self.call_sym(req)
|
||||
self.assertEqual(status, '400 Bad Request')
|
||||
self.assertEqual(b'Bad X-Symlink-Target-Etag format', body)
|
||||
self.assertEqual(status, '409 Conflict')
|
||||
|
||||
|
||||
class SymlinkVersioningTestCase(TestSymlinkMiddlewareBase):
|
||||
|
Loading…
x
Reference in New Issue
Block a user