aboutsummaryrefslogtreecommitdiff
path: root/object.go
diff options
context:
space:
mode:
Diffstat (limited to 'object.go')
-rw-r--r--object.go50
1 files changed, 50 insertions, 0 deletions
diff --git a/object.go b/object.go
index e2cea84..960a3a6 100644
--- a/object.go
+++ b/object.go
@@ -20,7 +20,9 @@ package schwift
import (
"bytes"
+ "crypto/hmac"
"crypto/md5"
+ "crypto/sha1"
"encoding/hex"
"fmt"
"hash"
@@ -28,6 +30,7 @@ import (
"net/http"
"net/url"
"strings"
+ "time"
)
//Object represents a Swift object. Instances are usually obtained by
@@ -590,3 +593,50 @@ func (o *Object) URL() (string, error) {
ObjectName: o.name,
}.URL(o.c.a.backend, nil)
}
+
+//TempURL is like Object.URL, but includes a token with a limited lifetime (as
+//specified by the `expires` argument) that permits anonymous access to this
+//object using the given HTTP method. This works only when the tempurl
+//middleware is set up on the server, and if the given `key` matches one of the
+//tempurl keys for this object's container or account.
+//
+//For example, if the ReadACL both on the account and container do not permit
+//anonymous read access (which is the default behavior):
+//
+// var o *schwift.Object
+// ...
+// resp, err := http.Get(o.URL())
+// //After this, resp.StatusCode == 401 (Unauthorized)
+// //because anonymous access is forbidden.
+//
+// //But if the container or account has a tempurl key...
+// key := "supersecretkey"
+// hdr := NewContainerHeaders()
+// hdr.TempURLKey().Set(key)
+// c := o.Container()
+// err := c.Update(hdr, nil)
+//
+// //...we can use it to generate temporary URLs.
+// url := o.TempURL(key, "GET", time.Now().Add(10 * time.Minute))
+// resp, err := http.Get(url)
+// //This time, resp.StatusCode == 200 because the URL includes a token.
+//
+func (o *Object) TempURL(key, method string, expires time.Time) (string, error) {
+ urlStr, err := o.URL()
+ if err != nil {
+ return "", err
+ }
+ u, err := url.Parse(urlStr)
+ if err != nil {
+ return "", err
+ }
+
+ payload := fmt.Sprintf("%s\n%d\n%s", method, expires.Unix(), u.Path)
+ mac := hmac.New(sha1.New, []byte(key))
+ mac.Write([]byte(payload))
+ signature := hex.EncodeToString(mac.Sum(nil))
+
+ u.RawQuery = fmt.Sprintf("temp_url_sig=%s&temp_url_expires=%d",
+ signature, expires.Unix())
+ return u.String(), nil
+}