Allow a configurable set of TempURL methods

Folks have actually been asking for this. I think they're sending a
DELETE TempURL to someone way ahead of time and the someone issues it
when they're ready. Honestly, I'm not entirely sure of the use case,
but having the set of methods configurable wouldn't hurt.

Change-Id: Ibdb48f8a72077b045eeedddfae4c0a1f56098d7a
This commit is contained in:
gholt 2013-04-04 16:44:22 +00:00
parent 2927dcc967
commit 1cb952a958
4 changed files with 26 additions and 8 deletions

View File

@ -13,8 +13,7 @@ if __name__ == '__main__':
print 'Syntax: %s <method> <seconds> <path> <key>' % prog
print
print 'Where:'
print ' <method> The method to allow, GET or PUT.'
print ' Note: HEAD will also be allowed.'
print ' <method> The method to allow; GET for example.'
print ' <seconds> The number of seconds from now to allow requests.'
print ' <path> The full path to the resource.'
print ' Example: /v1/AUTH_account/c/o'
@ -35,9 +34,6 @@ if __name__ == '__main__':
'temp_url_expires=1323482948'
exit(1)
method, seconds, path, key = argv[1:]
if method not in ('GET', 'PUT'):
print 'Please use either the GET or PUT method.'
exit(1)
try:
expires = int(time() + int(seconds))
except ValueError:

View File

@ -282,6 +282,8 @@ use = egg:swift#staticweb
# Note: Put tempurl just before your auth filter(s) in the pipeline
[filter:tempurl]
use = egg:swift#tempurl
# The methods allowed with Temp URLs.
# methods = GET HEAD PUT
#
# The headers to remove from incoming requests. Simply a whitespace delimited
# list of header names and names can optionally end with '*' to indicate a

View File

@ -173,6 +173,9 @@ class TempURL(object):
#: The filter configuration dict.
self.conf = conf
#: The methods allowed with Temp URLs.
self.methods = conf.get('methods', 'GET HEAD PUT').split()
headers = DEFAULT_INCOMING_REMOVE_HEADERS
if 'incoming_remove_headers' in conf:
headers = conf['incoming_remove_headers']
@ -290,14 +293,15 @@ class TempURL(object):
def _get_account(self, env):
"""
Returns just the account for the request, if it's an object GET, PUT,
or HEAD request; otherwise, None is returned.
Returns just the account for the request, if it's an object
request and one of the configured methods; otherwise, None is
returned.
:param env: The WSGI environment for the request.
:returns: Account str or None.
"""
account = None
if env['REQUEST_METHOD'] in ('GET', 'PUT', 'HEAD'):
if env['REQUEST_METHOD'] in self.methods:
parts = env['PATH_INFO'].split('/', 4)
# Must be five parts, ['', 'v1', 'a', 'c', 'o'], must be a v1
# request, have account, container, and object values, and the

View File

@ -336,6 +336,22 @@ class TestTempURL(unittest.TestCase):
self.assertEquals(resp.status_int, 401)
self.assertTrue('Temp URL invalid' in resp.body)
def test_delete_allowed_with_conf(self):
self.tempurl.methods.append('DELETE')
method = 'DELETE'
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,
environ={'REQUEST_METHOD': 'DELETE',
'QUERY_STRING':
'temp_url_sig=%s&temp_url_expires=%s' % (sig, expires)})
req.environ['swift.cache'].set('temp-url-key/a', key)
resp = req.get_response(self.tempurl)
self.assertEquals(resp.status_int, 404)
def test_unknown_not_allowed(self):
method = 'UNKNOWN'
expires = int(time() + 86400)