From 0c505d4456057ca3d401e519916748ed4c9ee822 Mon Sep 17 00:00:00 2001 From: Samuel Merritt Date: Mon, 26 Aug 2013 19:00:46 -0700 Subject: [PATCH] Fix setdefault() for swob's HeaderKeyDict. You'd think this would just work, given that HeaderKeyDict inherits from dict and overrides the usual __thingy__ methods, but it doesn't. It would work if you title-cased the key, but the whole point of HeaderKeyDict is to do that for you. Change-Id: If5c22df0690a245d1dd02fa3a52fa135235fe60d --- swift/common/swob.py | 5 +++++ swift/proxy/controllers/base.py | 3 +-- test/unit/common/test_swob.py | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/swift/common/swob.py b/swift/common/swob.py index 9ec57a026e..916fc667cf 100644 --- a/swift/common/swob.py +++ b/swift/common/swob.py @@ -281,6 +281,11 @@ class HeaderKeyDict(dict): def get(self, key, default=None): return dict.get(self, key.title(), default) + def setdefault(self, key, value=None): + if key not in self: + self[key] = value + return self[key] + def _resp_status_property(): """ diff --git a/swift/proxy/controllers/base.py b/swift/proxy/controllers/base.py index 39f61c3d49..a8dc534b05 100644 --- a/swift/proxy/controllers/base.py +++ b/swift/proxy/controllers/base.py @@ -473,8 +473,7 @@ class Controller(object): headers = HeaderKeyDict(additional) if additional else HeaderKeyDict() if transfer: self.transfer_headers(orig_req.headers, headers) - if 'x-timestamp' not in headers: - headers['x-timestamp'] = normalize_timestamp(time.time()) + headers.setdefault('x-timestamp', normalize_timestamp(time.time())) if orig_req: referer = orig_req.as_referer() else: diff --git a/test/unit/common/test_swob.py b/test/unit/common/test_swob.py index e4ff0ff980..fd461ac261 100644 --- a/test/unit/common/test_swob.py +++ b/test/unit/common/test_swob.py @@ -81,6 +81,23 @@ class TestHeaderKeyDict(unittest.TestCase): self.assertEquals(headers['content-length'], '20') self.assertEquals(headers['CONTENT-LENGTH'], '20') + def test_setdefault(self): + headers = swift.common.swob.HeaderKeyDict() + + # it gets set + headers.setdefault('x-rubber-ducky', 'the one') + self.assertEquals(headers['X-Rubber-Ducky'], 'the one') + + # it has the right return value + ret = headers.setdefault('x-boat', 'dinghy') + self.assertEquals(ret, 'dinghy') + + ret = headers.setdefault('x-boat', 'yacht') + self.assertEquals(ret, 'dinghy') + + # shouldn't crash + headers.setdefault('x-sir-not-appearing-in-this-request', None) + def test_del_contains(self): headers = swift.common.swob.HeaderKeyDict() headers['Content-Length'] = 0