Fix HEAD tempurls

HEAD-only tempurls didn't work; tempurl only allowed a HEAD request if
the tempurl was generated for GET or PUT (that is, the method in the
HMAC-signed string was "GET" or "PUT").

The intent of the code was to allow a user with a GET or a PUT tempurl
to also perform a HEAD request; I think the breaking of HEAD tempurls
is just a bug.

Change-Id: I621ddaac03e0d058dd9e7c7c374cb5c4b6386d36
This commit is contained in:
Samuel Merritt 2013-11-21 17:39:56 -08:00
parent a11c068080
commit d18b6d8d5d
2 changed files with 28 additions and 9 deletions

View File

@ -267,17 +267,16 @@ class TempURL(object):
if not keys:
return self._invalid(env, start_response)
if env['REQUEST_METHOD'] == 'HEAD':
hmac_vals = self._get_hmacs(env, temp_url_expires, keys,
request_method='GET')
if temp_url_sig not in hmac_vals:
hmac_vals = self._get_hmacs(env, temp_url_expires, keys,
request_method='PUT')
if temp_url_sig not in hmac_vals:
return self._invalid(env, start_response)
hmac_vals = (
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='PUT'))
else:
hmac_vals = self._get_hmacs(env, temp_url_expires, keys)
if temp_url_sig not in hmac_vals:
return self._invalid(env, start_response)
if temp_url_sig not in hmac_vals:
return self._invalid(env, start_response)
self._clean_incoming_headers(env)
env['swift.authorize'] = lambda req: None
env['swift.authorize_override'] = True
@ -387,6 +386,11 @@ class TempURL(object):
expires.
:param keys: Key strings, from the X-Account-Meta-Temp-URL-Key[-2] of
the account.
:param request_method: Optional override of the request in
the WSGI env. For example, if a HEAD
does not match, you may wish to
override with GET to still allow the
HEAD.
"""
if not request_method:
request_method = env['REQUEST_METHOD']

View File

@ -146,6 +146,21 @@ class TestTempURL(unittest.TestCase):
self.assertEquals(req.environ['swift.authorize_override'], True)
self.assertEquals(req.environ['REMOTE_USER'], '.wsgi.tempurl')
def test_head_valid(self):
method = 'HEAD'
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)})
self.tempurl.app = FakeApp(iter([('200 Ok', (), '123')]))
resp = req.get_response(self.tempurl)
self.assertEquals(resp.status_int, 200)
def test_get_valid_with_filename_and_inline(self):
method = 'GET'
expires = int(time() + 86400)