Consolidate Container-Update-Override headers

Related-Change-Id: I179ea6180d31146bb947061c69b1807c59529ac8
Related-Change-Id: I056edc68aee8c0db2a2c4a5b9e3d242a895975b3

Change-Id: I84bd29ae48ff1b0826794a8fdf9aa87670ad4aa4
This commit is contained in:
Clay Gerrard 2019-08-08 14:16:00 -05:00
parent 8d3d21e668
commit 996aa4547f
8 changed files with 35 additions and 17 deletions

View File

@ -123,7 +123,7 @@ from swift.common.http import HTTP_MULTIPLE_CHOICES, is_success, HTTP_OK
from swift.common.constraints import check_account_format, MAX_FILE_SIZE
from swift.common.request_helpers import copy_header_subset, remove_items, \
is_sys_meta, is_sys_or_user_meta, is_object_transient_sysmeta, \
check_path_header
check_path_header, OBJECT_SYSMETA_CONTAINER_UPDATE_OVERRIDE_PREFIX
from swift.common.wsgi import WSGIContext, make_subrequest
@ -405,7 +405,7 @@ class ServerSideCopyMiddleware(object):
# since we're not copying the source etag, make sure that any
# container update override values are not copied.
remove_items(sink_req.headers, lambda k: k.startswith(
'X-Object-Sysmeta-Container-Update-Override-'))
OBJECT_SYSMETA_CONTAINER_UPDATE_OVERRIDE_PREFIX.title()))
# We no longer need these headers
sink_req.headers.pop('X-Copy-From', None)

View File

@ -23,7 +23,8 @@ from swift.common.middleware.crypto.crypto_utils import CryptoWSGIContext, \
load_crypto_meta, extract_crypto_meta, Crypto
from swift.common.exceptions import EncryptionException, UnknownSecretIdError
from swift.common.request_helpers import get_object_transient_sysmeta, \
get_sys_meta_prefix, get_user_meta_prefix
get_sys_meta_prefix, get_user_meta_prefix, \
get_container_update_override_key
from swift.common.swob import Request, HTTPException, \
HTTPInternalServerError, wsgi_to_bytes, bytes_to_wsgi
from swift.common.utils import get_logger, config_true_value, \
@ -220,7 +221,7 @@ class DecrypterObjContext(BaseDecrypterContext):
required=True)
mod_hdr_pairs.append(('Etag', decrypted_etag))
etag_header = 'X-Object-Sysmeta-Container-Update-Override-Etag'
etag_header = get_container_update_override_key('etag')
encrypted_etag = self._response_header_value(etag_header)
if encrypted_etag:
decrypted_etag = self._decrypt_header(

View File

@ -22,7 +22,8 @@ from swift.common.http import is_success
from swift.common.middleware.crypto.crypto_utils import CryptoWSGIContext, \
dump_crypto_meta, append_crypto_meta, Crypto
from swift.common.request_helpers import get_object_transient_sysmeta, \
strip_user_meta_prefix, is_user_meta, update_etag_is_at_header
strip_user_meta_prefix, is_user_meta, update_etag_is_at_header, \
get_container_update_override_key
from swift.common.swob import Request, Match, HTTPException, \
HTTPUnprocessableEntity, wsgi_to_bytes, bytes_to_wsgi
from swift.common.utils import get_logger, config_true_value, \
@ -100,8 +101,8 @@ class EncInputWrapper(object):
# remove any Etag from headers, it won't be valid for ciphertext and
# we'll send the ciphertext Etag later in footer metadata
client_etag = req.headers.pop('etag', None)
container_listing_etag_header = req.headers.get(
'X-Object-Sysmeta-Container-Update-Override-Etag')
override_header = get_container_update_override_key('etag')
container_listing_etag_header = req.headers.get(override_header)
def footers_callback(footers):
if inner_callback:
@ -152,8 +153,7 @@ class EncInputWrapper(object):
# This may be None if no override was set and no data was read. An
# override value of '' will be passed on.
container_listing_etag = footers.get(
'X-Object-Sysmeta-Container-Update-Override-Etag',
container_listing_etag_header)
override_header, container_listing_etag_header)
if container_listing_etag is None:
container_listing_etag = plaintext_etag
@ -174,7 +174,7 @@ class EncInputWrapper(object):
self.crypto, container_listing_etag,
self.keys['container'])
crypto_meta['key_id'] = self.keys['id']
footers['X-Object-Sysmeta-Container-Update-Override-Etag'] = \
footers[override_header] = \
append_crypto_meta(val, crypto_meta)
# else: no override was set and no data was read

View File

@ -70,6 +70,7 @@ import six
from swift.common.swob import Range, bytes_to_wsgi
from swift.common.utils import json, public, reiterate
from swift.common.db import utf8encode
from swift.common.request_helpers import get_container_update_override_key
from six.moves.urllib.parse import quote, urlparse
@ -182,7 +183,7 @@ class PartController(Controller):
'X-Object-Sysmeta-Swift3-Etag': '', # for legacy data
'X-Object-Sysmeta-Slo-Etag': '',
'X-Object-Sysmeta-Slo-Size': '',
'X-Object-Sysmeta-Container-Update-Override-Etag': '',
get_container_update_override_key('etag'): '',
})
resp = req.get_response(self.app)
@ -634,7 +635,7 @@ class UploadController(Controller):
headers[sysmeta_header('object', 'etag')] = s3_etag
# Leave base header value blank; SLO will populate
c_etag = '; s3_etag=%s' % s3_etag
headers['X-Object-Sysmeta-Container-Update-Override-Etag'] = c_etag
headers[get_container_update_override_key('etag')] = c_etag
too_small_message = ('s3api requires that each segment be at least '
'%d bytes' % self.conf.min_segment_size)

View File

@ -339,7 +339,8 @@ from swift.common.utils import get_logger, config_true_value, \
closing_if_possible, LRUCache, StreamingPile, strict_b64decode, \
Timestamp
from swift.common.request_helpers import SegmentedIterable, \
get_sys_meta_prefix, update_etag_is_at_header, resolve_etag_is_at_header
get_sys_meta_prefix, update_etag_is_at_header, resolve_etag_is_at_header, \
get_container_update_override_key
from swift.common.constraints import check_utf8, MAX_BUFFERED_SLO_SEGMENTS
from swift.common.http import HTTP_NOT_FOUND, HTTP_UNAUTHORIZED, is_success
from swift.common.wsgi import WSGIContext, make_subrequest
@ -1354,7 +1355,7 @@ class StaticLargeObject(object):
# Ensure container listings have both etags. However, if any
# middleware to the left of us touched the base value, trust them.
override_header = 'X-Object-Sysmeta-Container-Update-Override-Etag'
override_header = get_container_update_override_key('etag')
val, sep, params = req.headers.get(
override_header, '').partition(';')
req.headers[override_header] = '%s; slo_etag=%s' % (

View File

@ -164,7 +164,7 @@ from swift.common.utils import get_logger, register_swift_info, split_path, \
from swift.common.constraints import check_account_format
from swift.common.wsgi import WSGIContext, make_subrequest
from swift.common.request_helpers import get_sys_meta_prefix, \
check_path_header
check_path_header, get_container_update_override_key
from swift.common.swob import Request, HTTPBadRequest, HTTPTemporaryRedirect, \
HTTPException, HTTPConflict, HTTPPreconditionFailed, wsgi_quote, \
wsgi_unquote
@ -455,7 +455,7 @@ class SymlinkObjectContext(WSGIContext):
etag_override.append(
'symlink_target_account=%s' %
req.headers[TGT_ACCT_SYSMETA_SYMLINK_HDR])
req.headers['X-Object-Sysmeta-Container-Update-Override-Etag'] = \
req.headers[get_container_update_override_key('etag')] = \
'; '.join(etag_override)
return self._app_call(req.environ)

View File

@ -44,6 +44,8 @@ from swift.common.wsgi import make_subrequest
OBJECT_TRANSIENT_SYSMETA_PREFIX = 'x-object-transient-sysmeta-'
OBJECT_SYSMETA_CONTAINER_UPDATE_OVERRIDE_PREFIX = \
'x-object-sysmeta-container-update-override-'
def get_param(req, name, default=None):
@ -260,6 +262,17 @@ def get_object_transient_sysmeta(key):
return '%s%s' % (OBJECT_TRANSIENT_SYSMETA_PREFIX, key)
def get_container_update_override_key(key):
"""
Returns the full X-Object-Sysmeta-Container-Update-Override-* header key.
:param key: the key you want to override in the container update
:returns: the full header key
"""
header = '%s%s' % (OBJECT_SYSMETA_CONTAINER_UPDATE_OVERRIDE_PREFIX, key)
return header.title()
def remove_items(headers, condition):
"""
Removes items from a dict whose keys satisfy

View File

@ -43,6 +43,8 @@ from swift.common.exceptions import ConnectionTimeout, DiskFileQuarantined, \
DiskFileNotExist, DiskFileCollision, DiskFileNoSpace, DiskFileDeleted, \
DiskFileDeviceUnavailable, DiskFileExpired, ChunkReadTimeout, \
ChunkReadError, DiskFileXattrNotSupported
from swift.common.request_helpers import \
OBJECT_SYSMETA_CONTAINER_UPDATE_OVERRIDE_PREFIX
from swift.obj import ssync_receiver
from swift.common.http import is_success, HTTP_MOVED_PERMANENTLY
from swift.common.base_storage_server import BaseStorageServer
@ -583,7 +585,7 @@ class ObjectController(BaseStorageServer):
# x-object-sysmeta-container-update-override-* headers take precedence
# over x-backend-container-update-override-* headers
override_prefixes = ['x-backend-container-update-override-',
'x-object-sysmeta-container-update-override-']
OBJECT_SYSMETA_CONTAINER_UPDATE_OVERRIDE_PREFIX]
for override_prefix in override_prefixes:
for key, val in metadata.items():
if key.lower().startswith(override_prefix):