Created
December 3, 2013 17:13
-
-
Save portante/7773228 to your computer and use it in GitHub Desktop.
An alternative patch for https://bugs.launchpad.net/swift/+bug/1257330 (see https://gist.github.com/gholt/7771150).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/swift/common/exceptions.py b/swift/common/exceptions.py | |
| index 5943f89..e0361cf 100644 | |
| --- a/swift/common/exceptions.py | |
| +++ b/swift/common/exceptions.py | |
| @@ -54,6 +54,10 @@ class DiskFileDeleted(DiskFileNotExist): | |
| pass | |
| +class DiskFileExpired(DiskFileNotExist): | |
| + pass | |
| + | |
| + | |
| class DiskFileNoSpace(DiskFileError): | |
| pass | |
| diff --git a/swift/obj/diskfile.py b/swift/obj/diskfile.py | |
| index ffdcafd..82fa311 100644 | |
| --- a/swift/obj/diskfile.py | |
| +++ b/swift/obj/diskfile.py | |
| @@ -56,7 +56,7 @@ from swift.common.utils import mkdirs, normalize_timestamp, \ | |
| from swift.common.exceptions import DiskFileQuarantined, DiskFileNotExist, \ | |
| DiskFileCollision, DiskFileNoSpace, DiskFileDeviceUnavailable, \ | |
| DiskFileDeleted, DiskFileError, DiskFileNotOpen, PathNotDir, \ | |
| - ReplicationLockTimeout | |
| + ReplicationLockTimeout, DiskFileExpired | |
| from swift.common.swob import multi_range_iterator | |
| @@ -1165,7 +1165,10 @@ class DiskFile(object): | |
| self._metadata['X-Delete-At'])) | |
| else: | |
| if x_delete_at <= time.time(): | |
| - raise DiskFileNotExist('Expired') | |
| + exc = DiskFileExpired() | |
| + exc.x_delete_at = x_delete_at | |
| + exc.timestamp = self._metadata['X-Timestamp'] | |
| + raise exc | |
| try: | |
| metadata_size = int(self._metadata['Content-Length']) | |
| except KeyError: | |
| diff --git a/swift/obj/server.py b/swift/obj/server.py | |
| index cfb7695..cb4ce07 100644 | |
| --- a/swift/obj/server.py | |
| +++ b/swift/obj/server.py | |
| @@ -34,7 +34,7 @@ from swift.common.constraints import check_object_creation, \ | |
| check_float, check_utf8 | |
| from swift.common.exceptions import ConnectionTimeout, DiskFileQuarantined, \ | |
| DiskFileNotExist, DiskFileCollision, DiskFileNoSpace, DiskFileDeleted, \ | |
| - DiskFileDeviceUnavailable | |
| + DiskFileDeviceUnavailable, DiskFileExpired | |
| from swift.obj import ssync_receiver | |
| from swift.common.http import is_success | |
| from swift.common.request_helpers import split_and_validate_path | |
| @@ -584,11 +584,15 @@ class ObjectController(object): | |
| orig_metadata = disk_file.read_metadata() | |
| except DiskFileDeleted as e: | |
| orig_timestamp = e.timestamp | |
| - orig_metadata = {} | |
| + orig_delete_at = 0 | |
| + response_class = HTTPNotFound | |
| + except DiskFileExpired as e: | |
| + orig_timestamp = e.timestamp | |
| + orig_delete_at = e.x_delete_at | |
| response_class = HTTPNotFound | |
| except (DiskFileNotExist, DiskFileQuarantined): | |
| orig_timestamp = 0 | |
| - orig_metadata = {} | |
| + orig_delete_at = 0 | |
| response_class = HTTPNotFound | |
| else: | |
| orig_timestamp = orig_metadata.get('X-Timestamp', 0) | |
| @@ -596,13 +600,23 @@ class ObjectController(object): | |
| response_class = HTTPNoContent | |
| else: | |
| response_class = HTTPConflict | |
| - if 'x-if-delete-at' in request.headers and \ | |
| - int(request.headers['x-if-delete-at']) != \ | |
| - int(orig_metadata.get('X-Delete-At') or 0): | |
| - return HTTPPreconditionFailed( | |
| - request=request, | |
| - body='X-If-Delete-At and X-Delete-At do not match') | |
| - orig_delete_at = int(orig_metadata.get('X-Delete-At') or 0) | |
| + orig_delete_at = int(orig_metadata.get('X-Delete-At') or 0) | |
| + try: | |
| + req_if_delete_at = request.headers['x-if-delete-at'] | |
| + except KeyError: | |
| + pass | |
| + else: | |
| + try: | |
| + req_if_delete_at = int(req_if_delete_at) | |
| + except ValueError: | |
| + return HTTPBadRequest(body='Missing timestamp', | |
| + request=request, | |
| + content_type='text/plain') | |
| + else: | |
| + if orig_delete_at != req_if_delete_at: | |
| + return HTTPPreconditionFailed( | |
| + request=request, | |
| + body='X-If-Delete-At and X-Delete-At do not match') | |
| if orig_delete_at: | |
| self.delete_at_update('DELETE', orig_delete_at, account, | |
| container, obj, request, device) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment