One of the many amazing features of Swift, OpenStack's object storage component, is how it creates URLs to provide temporary public access to objects. Thanks to the middleware component called tempurl. For example, imagine a website wants to provide a link to a media file stored in Swift for HTML5 playback. Instead of needing a Swift account with public access, and all the problems that would bring, Swift can generate a URL with limited access time to the resource. This way the browser can access the object directly instead of needing the website to act as a proxy and objects can selectively be made publicly accessible without compromising the rest or using expensive copies between private to public accounts. If the link is accidentally leaked, the access is time limited until the expiration time set.
So how do you use this temporary urls? Glad you asked.
Let's assume you have the following Swift installation:
The first thing we need to do is add temporary URL secret keys to the Swift account. Since tempurl will look at the Temp-URL-Key and Temp-URL-Key-2 metas when an object is requested through a temporary URL to decide if access is allowed. Only one key is neccessary, but a second one is useful to rotate through keys while keeping existing temporary urls validated. Any arbitrary string can serve as a secret key.
We add the temporary urls secret keys with the command:
Once we have the keys we can allow public access to objects. The easiest way is to use the tool swift-temp-url which returns a temporary URL. The arguments it needs are; HTTP method, availability period in seconds, object path and one temp-url-key. For example to GET the object we mentioned above:
Now you can retrieve the file via this temporary URL, you just need to add the hostname to have the full URL.
Eventhough you probably already guessed it, let's note the format of the temporary URL. Typical object path, plus temp_url_sig, and temp_url_expires.
In this example:
There you have it. Notice we set it up for a GET method. You could do the same with a PUT method to allow a user to push data to a specified path. Perhaps using this in combination with browser form post translation middleware to allow direct-from-browser uploads to specific locations in Swift. Besides GET and PUSH, you can use HEAD to retrieve the header of the object.
At this stage you must be happy to see how easy and convenient this is, but wondering how you can integrate it with your code. You can replicate swift-temp-url with the following block of Python code:
Have in mind that any alteration of the resource path or query arguments results in a 401 Unauthorized error. Similarly, a PUT where GET was the allowed method returns a 401. HEAD is allowed if GET or PUT is allowed. Changing the X-Account-Meta-Temp-URL-Key invalidates any previously generated temporary URLs within 60 seconds (the memcache time for the key).
That's all for now. What else would you like to learn regarding Swift?
So how do you use this temporary urls? Glad you asked.
Let's assume you have the following Swift installation:
http://192.168.1.42:8080
Account: AUTH_data
Container: media
Object: example_obj
The first thing we need to do is add temporary URL secret keys to the Swift account. Since tempurl will look at the Temp-URL-Key and Temp-URL-Key-2 metas when an object is requested through a temporary URL to decide if access is allowed. Only one key is neccessary, but a second one is useful to rotate through keys while keeping existing temporary urls validated. Any arbitrary string can serve as a secret key.
We add the temporary urls secret keys with the command:
$ swift post -m "Temp-URL-Key:secrete_key_a"
$ swift post -m "Temp-URL-Key-2:secrete_key_b"
Once we have the keys we can allow public access to objects. The easiest way is to use the tool swift-temp-url which returns a temporary URL. The arguments it needs are; HTTP method, availability period in seconds, object path and one temp-url-key. For example to GET the object we mentioned above:
$ swift-temp-url GET 60 /v1/AUTH_data/media/example_obj secret_key_a
/v1/AUTH_data/media/example_Obj?temp_url_sig=b9746f2e38313635257877abdb8340c48ebd622c&temp_url_expires=1392925673
Now you can retrieve the file via this temporary URL, you just need to add the hostname to have the full URL.
$ curl http://192.168.1.42:8080/v1/AUTH_data/media/example_Obj?temp_url_sig=b9746f2e38313635257877abdb8340c48ebd622c&temp_url_expires=1392925673
Eventhough you probably already guessed it, let's note the format of the temporary URL. Typical object path, plus temp_url_sig, and temp_url_expires.
In this example:
http://192.168.1.42:8080/v1/AUTH_data/media/example_Obj?
temp_url_sig=b9746f2e38313635257877abdb8340c48ebd622c&
temp_url_expires=1392925673
There you have it. Notice we set it up for a GET method. You could do the same with a PUT method to allow a user to push data to a specified path. Perhaps using this in combination with browser form post translation middleware to allow direct-from-browser uploads to specific locations in Swift. Besides GET and PUSH, you can use HEAD to retrieve the header of the object.
At this stage you must be happy to see how easy and convenient this is, but wondering how you can integrate it with your code. You can replicate swift-temp-url with the following block of Python code:
import hmac
from hashlib import sha1
from time import time
# Get a temporary public url for the object
method = 'GET'
duration_in_seconds = 60*60*3
expires = int(time() + duration_in_seconds)
path = '/v1/AUTH_test/%s/%s' % (self.container, track)
key = self.temp_url_key
hmac_body = '%s\n%s\n%s' % (method, expires, path)
sig = hmac.new(key, hmac_body, sha1).hexdigest()
s = 'https://{host}/{path}?temp_url_sig={sig}&temp_url_expires={expires}'
url = s.format(host=self.url, path=path, sig=sig, expires=expires)
Have in mind that any alteration of the resource path or query arguments results in a 401 Unauthorized error. Similarly, a PUT where GET was the allowed method returns a 401. HEAD is allowed if GET or PUT is allowed. Changing the X-Account-Meta-Temp-URL-Key invalidates any previously generated temporary URLs within 60 seconds (the memcache time for the key).
That's all for now. What else would you like to learn regarding Swift?