Proposed fix for bug #837428.
To test: Create an object without an x-timestamp or x-put-timestamp header and request the object with the X-newest header. Without the patch, the proxy will return a 404 object not found even though the storage nodes return the object to the proxy. With the patch, the proxy will return the first object received unless an object with a newer timestamp header exists.
This commit is contained in:
@@ -645,13 +645,15 @@ class Controller(object):
|
|||||||
possible_source.status in (200, 206)) or \
|
possible_source.status in (200, 206)) or \
|
||||||
200 <= possible_source.status <= 399:
|
200 <= possible_source.status <= 399:
|
||||||
if newest:
|
if newest:
|
||||||
ts = 0
|
|
||||||
if source:
|
if source:
|
||||||
ts = float(source.getheader('x-put-timestamp') or
|
ts = float(source.getheader('x-put-timestamp') or
|
||||||
source.getheader('x-timestamp') or 0)
|
source.getheader('x-timestamp') or 0)
|
||||||
pts = float(possible_source.getheader('x-put-timestamp') or
|
pts = float(
|
||||||
possible_source.getheader('x-timestamp') or 0)
|
possible_source.getheader('x-put-timestamp') or
|
||||||
if pts > ts:
|
possible_source.getheader('x-timestamp') or 0)
|
||||||
|
if pts > ts:
|
||||||
|
source = possible_source
|
||||||
|
else:
|
||||||
source = possible_source
|
source = possible_source
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
|
@@ -182,6 +182,8 @@ def fake_http_connect(*code_iter, **kwargs):
|
|||||||
self.etag or '"68b329da9893e34099c7d8ad5cb9c940"',
|
self.etag or '"68b329da9893e34099c7d8ad5cb9c940"',
|
||||||
'x-works': 'yes',
|
'x-works': 'yes',
|
||||||
}
|
}
|
||||||
|
if not self.timestamp:
|
||||||
|
del headers['x-timestamp']
|
||||||
try:
|
try:
|
||||||
if container_ts_iter.next() is False:
|
if container_ts_iter.next() is False:
|
||||||
headers['x-container-timestamp'] = '1'
|
headers['x-container-timestamp'] = '1'
|
||||||
@@ -321,8 +323,8 @@ def save_globals():
|
|||||||
proxy_server.http_connect = orig_http_connect
|
proxy_server.http_connect = orig_http_connect
|
||||||
proxy_server.Controller.account_info = orig_account_info
|
proxy_server.Controller.account_info = orig_account_info
|
||||||
|
|
||||||
# tests
|
|
||||||
|
|
||||||
|
# tests
|
||||||
class TestController(unittest.TestCase):
|
class TestController(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@@ -355,7 +357,8 @@ class TestController(unittest.TestCase):
|
|||||||
partition, nodes = self.controller.account_info(self.account)
|
partition, nodes = self.controller.account_info(self.account)
|
||||||
proxy_server.http_connect = fake_http_connect(201,
|
proxy_server.http_connect = fake_http_connect(201,
|
||||||
raise_timeout_exc=True)
|
raise_timeout_exc=True)
|
||||||
self.controller._make_request(nodes, partition, 'POST','/','','')
|
self.controller._make_request(nodes, partition, 'POST',
|
||||||
|
'/', '', '')
|
||||||
|
|
||||||
# tests if 200 is cached and used
|
# tests if 200 is cached and used
|
||||||
def test_account_info_200(self):
|
def test_account_info_200(self):
|
||||||
@@ -713,7 +716,6 @@ class TestObjectController(unittest.TestCase):
|
|||||||
object_ring=FakeRing())
|
object_ring=FakeRing())
|
||||||
monkey_patch_mimetools()
|
monkey_patch_mimetools()
|
||||||
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
proxy_server.CONTAINER_LISTING_LIMIT = _orig_container_listing_limit
|
proxy_server.CONTAINER_LISTING_LIMIT = _orig_container_listing_limit
|
||||||
|
|
||||||
@@ -758,6 +760,7 @@ class TestObjectController(unittest.TestCase):
|
|||||||
'text/html', 'text/html']))
|
'text/html', 'text/html']))
|
||||||
test_content_type('test.css', iter(['', '', '', 'text/css',
|
test_content_type('test.css', iter(['', '', '', 'text/css',
|
||||||
'text/css', 'text/css']))
|
'text/css', 'text/css']))
|
||||||
|
|
||||||
def test_custom_mime_types_files(self):
|
def test_custom_mime_types_files(self):
|
||||||
swift_dir = mkdtemp()
|
swift_dir = mkdtemp()
|
||||||
try:
|
try:
|
||||||
@@ -1079,6 +1082,8 @@ class TestObjectController(unittest.TestCase):
|
|||||||
test_status_map((200, 200, 200), 200, ('1', '3', '2'), '3')
|
test_status_map((200, 200, 200), 200, ('1', '3', '2'), '3')
|
||||||
test_status_map((200, 200, 200), 200, ('1', '3', '1'), '3')
|
test_status_map((200, 200, 200), 200, ('1', '3', '1'), '3')
|
||||||
test_status_map((200, 200, 200), 200, ('3', '3', '1'), '3')
|
test_status_map((200, 200, 200), 200, ('3', '3', '1'), '3')
|
||||||
|
test_status_map((200, 200, 200), 200, (None, None, None), None)
|
||||||
|
test_status_map((200, 200, 200), 200, (None, None, '1'), '1')
|
||||||
|
|
||||||
def test_GET_newest(self):
|
def test_GET_newest(self):
|
||||||
with save_globals():
|
with save_globals():
|
||||||
@@ -1102,6 +1107,8 @@ class TestObjectController(unittest.TestCase):
|
|||||||
test_status_map((200, 200, 200), 200, ('1', '3', '2'), '3')
|
test_status_map((200, 200, 200), 200, ('1', '3', '2'), '3')
|
||||||
test_status_map((200, 200, 200), 200, ('1', '3', '1'), '3')
|
test_status_map((200, 200, 200), 200, ('1', '3', '1'), '3')
|
||||||
test_status_map((200, 200, 200), 200, ('3', '3', '1'), '3')
|
test_status_map((200, 200, 200), 200, ('3', '3', '1'), '3')
|
||||||
|
test_status_map((200, 200, 200), 200, (None, None, None), None)
|
||||||
|
test_status_map((200, 200, 200), 200, (None, None, '1'), '1')
|
||||||
|
|
||||||
with save_globals():
|
with save_globals():
|
||||||
controller = proxy_server.ObjectController(self.app, 'account',
|
controller = proxy_server.ObjectController(self.app, 'account',
|
||||||
@@ -1124,6 +1131,7 @@ class TestObjectController(unittest.TestCase):
|
|||||||
test_status_map((200, 200, 200), 200, ('1', '3', '2'), '1')
|
test_status_map((200, 200, 200), 200, ('1', '3', '2'), '1')
|
||||||
test_status_map((200, 200, 200), 200, ('1', '3', '1'), '1')
|
test_status_map((200, 200, 200), 200, ('1', '3', '1'), '1')
|
||||||
test_status_map((200, 200, 200), 200, ('3', '3', '1'), '3')
|
test_status_map((200, 200, 200), 200, ('3', '3', '1'), '3')
|
||||||
|
test_status_map((200, 200, 200), 200, (None, '1', '2'), None)
|
||||||
|
|
||||||
def test_POST_meta_val_len(self):
|
def test_POST_meta_val_len(self):
|
||||||
with save_globals():
|
with save_globals():
|
||||||
|
Reference in New Issue
Block a user