From 25c98b771a26ffed3772e2fe4d2547afaa011834 Mon Sep 17 00:00:00 2001 From: Samuel Merritt Date: Fri, 11 Jul 2014 12:03:30 -0700 Subject: [PATCH] Allow HEAD for POST tempurls HEAD requests are already allowed for GET and PUT tempurls; this commit adds that for POST tempurls. Since POST replaces all the object's metadata, it's quite useful to be able to HEAD the object in order to fetch the old metadata and do a client-side merge of the new metadata (like with normal, token-authenticated POST requests). Change-Id: I603c7822cd27f0e304fd27024f83f95114eb0aef --- swift/common/middleware/tempurl.py | 10 ++++++---- test/unit/common/middleware/test_tempurl.py | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/swift/common/middleware/tempurl.py b/swift/common/middleware/tempurl.py index 15b6bca74e..517bb332d7 100644 --- a/swift/common/middleware/tempurl.py +++ b/swift/common/middleware/tempurl.py @@ -46,9 +46,9 @@ limited to the expiration time set when the website created the link. To create such temporary URLs, first an X-Account-Meta-Temp-URL-Key header must be set on the Swift account. Then, an HMAC-SHA1 (RFC 2104) -signature is generated using the HTTP method to allow (GET or PUT), -the Unix timestamp the access should be allowed until, the full path -to the object, and the key set on the account. +signature is generated using the HTTP method to allow (GET, PUT, +DELETE, etc.), the Unix timestamp the access should be allowed until, +the full path to the object, and the key set on the account. For example, here is code generating the signature for a GET for 60 seconds on /v1/AUTH_account/container/object:: @@ -75,7 +75,7 @@ da39a3ee5e6b4b0d3255bfef95601890afd80709 and expires ends up Any alteration of the resource path or query arguments would result in 401 Unauthorized. Similary, a PUT where GET was the allowed method -would 401. HEAD is allowed if GET or PUT is allowed. +would 401. HEAD is allowed if GET, PUT, or POST is allowed. Using this in combination with browser form post translation middleware could also allow direct-from-browser uploads to specific @@ -300,6 +300,8 @@ class TempURL(object): self._get_hmacs(env, temp_url_expires, keys) + self._get_hmacs(env, temp_url_expires, keys, request_method='GET') + + self._get_hmacs(env, temp_url_expires, keys, + request_method='POST') + self._get_hmacs(env, temp_url_expires, keys, request_method='PUT')) else: diff --git a/test/unit/common/middleware/test_tempurl.py b/test/unit/common/middleware/test_tempurl.py index 3a48bfe8bf..bb73993731 100644 --- a/test/unit/common/middleware/test_tempurl.py +++ b/test/unit/common/middleware/test_tempurl.py @@ -451,6 +451,23 @@ class TestTempURL(unittest.TestCase): self.assertEquals(req.environ['swift.authorize_override'], True) self.assertEquals(req.environ['REMOTE_USER'], '.wsgi.tempurl') + def test_head_allowed_by_post(self): + method = 'POST' + expires = int(time() + 86400) + path = '/v1/a/c/o' + key = 'abc' + hmac_body = '%s\n%s\n%s' % (method, expires, path) + sig = hmac.new(key, hmac_body, sha1).hexdigest() + req = self._make_request( + path, keys=[key], + environ={'REQUEST_METHOD': 'HEAD', + 'QUERY_STRING': 'temp_url_sig=%s&temp_url_expires=%s' % ( + sig, expires)}) + resp = req.get_response(self.tempurl) + self.assertEquals(resp.status_int, 404) + self.assertEquals(req.environ['swift.authorize_override'], True) + self.assertEquals(req.environ['REMOTE_USER'], '.wsgi.tempurl') + def test_head_otherwise_not_allowed(self): method = 'PUT' expires = int(time() + 86400)