Merge "Make DELETE requests to expired objects return 404."

This commit is contained in:
Jenkins 2012-11-09 20:17:15 +00:00 committed by Gerrit Code Review
commit ee42e6fc72
2 changed files with 37 additions and 14 deletions

View File

@ -264,6 +264,15 @@ class DiskFile(object):
"""
return not self.data_file or 'deleted' in self.metadata
def is_expired(self):
"""
Check if the file is expired.
:returns: True if the file has an X-Delete-At in the past
"""
return ('X-Delete-At' in self.metadata and
int(self.metadata['X-Delete-At']) <= time.time())
@contextmanager
def mkstemp(self):
"""Contextmanager to make a temporary file."""
@ -534,13 +543,8 @@ class ObjectController(object):
file = DiskFile(self.devices, device, partition, account, container,
obj, self.logger, disk_chunk_size=self.disk_chunk_size)
if 'X-Delete-At' in file.metadata and \
int(file.metadata['X-Delete-At']) <= time.time():
if file.is_deleted() or file.is_expired():
return HTTPNotFound(request=request)
if file.is_deleted():
response_class = HTTPNotFound
else:
response_class = HTTPAccepted
try:
file_size = file.get_data_file_size()
except (DiskFileError, DiskFileNotExist):
@ -563,7 +567,7 @@ class ObjectController(object):
container, obj, request.headers, device)
with file.mkstemp() as (fd, tmppath):
file.put(fd, tmppath, metadata, extension='.meta')
return response_class(request=request)
return HTTPAccepted(request=request)
@public
@timing_stats
@ -682,9 +686,7 @@ class ObjectController(object):
obj, self.logger, keep_data_fp=True,
disk_chunk_size=self.disk_chunk_size,
iter_hook=sleep)
if file.is_deleted() or \
('X-Delete-At' in file.metadata and
int(file.metadata['X-Delete-At']) <= time.time()):
if file.is_deleted() or file.is_expired():
if request.headers.get('if-match') == '*':
return HTTPPreconditionFailed(request=request)
else:
@ -764,9 +766,7 @@ class ObjectController(object):
return HTTPInsufficientStorage(drive=device, request=request)
file = DiskFile(self.devices, device, partition, account, container,
obj, self.logger, disk_chunk_size=self.disk_chunk_size)
if file.is_deleted() or \
('X-Delete-At' in file.metadata and
int(file.metadata['X-Delete-At']) <= time.time()):
if file.is_deleted() or file.is_expired():
return HTTPNotFound(request=request)
try:
file_size = file.get_data_file_size()
@ -816,7 +816,7 @@ class ObjectController(object):
request=request,
body='X-If-Delete-At and X-Delete-At do not match')
orig_timestamp = file.metadata.get('X-Timestamp')
if file.is_deleted():
if file.is_deleted() or file.is_expired():
response_class = HTTPNotFound
metadata = {
'X-Timestamp': request.headers['X-Timestamp'], 'deleted': True,

View File

@ -2061,6 +2061,29 @@ class TestObjectController(unittest.TestCase):
finally:
object_server.time.time = orig_time
def test_DELETE_but_expired(self):
test_time = time() + 10000
req = Request.blank('/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
headers={'X-Timestamp': normalize_timestamp(test_time - 2000),
'X-Delete-At': str(int(test_time + 100)),
'Content-Length': '4',
'Content-Type': 'application/octet-stream'})
req.body = 'TEST'
resp = self.object_controller.PUT(req)
self.assertEquals(resp.status_int, 201)
orig_time = object_server.time.time
try:
t = test_time + 100
object_server.time.time = lambda: float(t)
req = Request.blank('/sda1/p/a/c/o',
environ={'REQUEST_METHOD': 'DELETE'},
headers={'X-Timestamp': normalize_timestamp(time())})
resp = self.object_controller.DELETE(req)
self.assertEquals(resp.status_int, 404)
finally:
object_server.time.time = orig_time
def test_DELETE_if_delete_at(self):
test_time = time() + 10000
req = Request.blank('/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},