Skip to content

Commit 9e77f46

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "fix when deleting a versioned object when the version target container is missing"
2 parents 9115bbb + 7540bea commit 9e77f46

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

swift/proxy/server.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,19 +1397,18 @@ def DELETE(self, req):
13971397
lcontainer = object_versions.split('/')[0]
13981398
prefix_len = '%03x' % len(self.object_name)
13991399
lprefix = prefix_len + self.object_name + '/'
1400+
last_item = None
14001401
try:
1401-
raw_listing = self._listing_iter(lcontainer, lprefix,
1402-
req.environ)
1402+
for last_item in self._listing_iter(lcontainer, lprefix,
1403+
req.environ):
1404+
pass
14031405
except ListingIterNotFound:
1404-
# set raw_listing so that the actual object is deleted
1405-
raw_listing = []
1406+
# no worries, last_item is None
1407+
pass
14061408
except ListingIterNotAuthorized, err:
14071409
return err.aresp
14081410
except ListingIterError:
14091411
return HTTPServerError(request=req)
1410-
last_item = None
1411-
for item in raw_listing: # find the last item
1412-
last_item = item
14131412
if last_item:
14141413
# there are older versions so copy the previous version to the
14151414
# current object and delete the previous version

test/unit/proxy/test_server.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2635,6 +2635,46 @@ def test_version_manifest(self):
26352635
versions = [x for x in body.split('\n') if x]
26362636
self.assertEquals(len(versions), 1)
26372637

2638+
# Check for when the versions target container doesn't exist
2639+
sock = connect_tcp(('localhost', prolis.getsockname()[1]))
2640+
fd = sock.makefile()
2641+
fd.write('PUT /v1/a/whoops HTTP/1.1\r\nHost: localhost\r\n'
2642+
'Connection: close\r\nX-Storage-Token: t\r\n'
2643+
'Content-Length: 0\r\nX-Versions-Location: none\r\n\r\n')
2644+
fd.flush()
2645+
headers = readuntil2crlfs(fd)
2646+
exp = 'HTTP/1.1 201'
2647+
self.assertEquals(headers[:len(exp)], exp)
2648+
# Create the versioned file
2649+
sock = connect_tcp(('localhost', prolis.getsockname()[1]))
2650+
fd = sock.makefile()
2651+
fd.write('PUT /v1/a/whoops/foo HTTP/1.1\r\nHost: '
2652+
'localhost\r\nConnection: close\r\nX-Storage-Token: '
2653+
't\r\nContent-Length: 5\r\n\r\n00000\r\n')
2654+
fd.flush()
2655+
headers = readuntil2crlfs(fd)
2656+
exp = 'HTTP/1.1 201'
2657+
self.assertEquals(headers[:len(exp)], exp)
2658+
# Create another version
2659+
sock = connect_tcp(('localhost', prolis.getsockname()[1]))
2660+
fd = sock.makefile()
2661+
fd.write('PUT /v1/a/whoops/foo HTTP/1.1\r\nHost: '
2662+
'localhost\r\nConnection: close\r\nX-Storage-Token: '
2663+
't\r\nContent-Length: 5\r\n\r\n00001\r\n')
2664+
fd.flush()
2665+
headers = readuntil2crlfs(fd)
2666+
exp = 'HTTP/1.1 412'
2667+
self.assertEquals(headers[:len(exp)], exp)
2668+
# Delete the object
2669+
sock = connect_tcp(('localhost', prolis.getsockname()[1]))
2670+
fd = sock.makefile()
2671+
fd.write('DELETE /v1/a/whoops/foo HTTP/1.1\r\nHost: '
2672+
'localhost\r\nConnection: close\r\nX-Storage-Token: t\r\n\r\n')
2673+
fd.flush()
2674+
headers = readuntil2crlfs(fd)
2675+
exp = 'HTTP/1.1 2' # 2xx response
2676+
self.assertEquals(headers[:len(exp)], exp)
2677+
26382678
def test_chunked_put_lobjects(self):
26392679
# Create a container for our segmented/manifest object testing
26402680
(prolis, acc1lis, acc2lis, con2lis, con2lis, obj1lis, obj2lis) = \

0 commit comments

Comments
 (0)