forked from willnorris/imageproxy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
84 lines (71 loc) · 1.95 KB
/
main.go
File metadata and controls
84 lines (71 loc) · 1.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// The imageproxy-sign tool creates signature values for a provided URL and
// signing key.
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"flag"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
"strings"
"willnorris.com/go/imageproxy"
)
var key = flag.String("key", "@/etc/imageproxy.key", "signing key, or file containing key prefixed with '@'")
var urlOnly = flag.Bool("url", false, "only sign the URL value, do not include options")
func main() {
flag.Parse()
if flag.NArg() < 1 {
fmt.Println("imageproxy-sign url [key]")
os.Exit(1)
}
u := parseURL(flag.Arg(0))
if u == nil {
fmt.Printf("unable to parse URL: %v\n", flag.Arg(0))
os.Exit(1)
}
if *urlOnly {
u.Fragment = ""
}
k, err := parseKey(*key)
if err != nil {
fmt.Printf("error parsing key: %v", err)
os.Exit(1)
}
mac := hmac.New(sha256.New, []byte(k))
mac.Write([]byte(u.String()))
sig := mac.Sum(nil)
fmt.Printf("url: %v\n", u)
fmt.Printf("signature: %v\n", base64.URLEncoding.EncodeToString(sig))
}
func parseKey(s string) ([]byte, error) {
if strings.HasPrefix(s, "@") {
return ioutil.ReadFile(s[1:])
}
return []byte(s), nil
}
// parseURL parses s as either an imageproxy request URL or a remote URL with
// options in the URL fragment. Any existing signature values are stripped,
// and the final remote URL returned with remaining options in the fragment.
func parseURL(s string) *url.URL {
u, err := url.Parse(s)
if s == "" || err != nil {
return nil
}
// first try to parse this as an imageproxy URL, containing
// transformation options and the remote URL embedded
if r, err := imageproxy.NewRequest(&http.Request{URL: u}, nil); err == nil {
r.Options.Signature = ""
r.URL.Fragment = r.Options.String()
return r.URL
}
// second, we assume that this is the remote URL itself. If a fragment
// is present, treat it as an option string.
opt := imageproxy.ParseOptions(u.Fragment)
opt.Signature = ""
u.Fragment = opt.String()
return u
}