Skip to content

Commit 7f687b8

Browse files
committed
Add somewhat flakey example test
1 parent 6c795c2 commit 7f687b8

File tree

3 files changed

+64
-6
lines changed

3 files changed

+64
-6
lines changed

example_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package httpsig_test
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"net/http"
7+
8+
"github.com/jbowes/httpsig"
9+
)
10+
11+
const secret = "support-your-local-cat-bonnet-store"
12+
13+
func Example_Round_Trip() {
14+
h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
15+
w.Header().Set("Content-Type", "text/plain")
16+
io.WriteString(w, "Your request has a valid signature!")
17+
})
18+
19+
middleware := httpsig.NewVerifyMiddleware(httpsig.WithHmacSha256("key1", []byte(secret)))
20+
http.Handle("/", middleware(h))
21+
go func() { http.ListenAndServe("127.0.0.1:1234", http.DefaultServeMux) }()
22+
23+
client := http.Client{
24+
// Wrap the transport:
25+
Transport: httpsig.NewSignTransport(http.DefaultTransport,
26+
httpsig.WithHmacSha256("key1", []byte(secret))),
27+
}
28+
29+
resp, err := client.Get("http://127.0.0.1:1234/")
30+
if err != nil {
31+
fmt.Println("got err: ", err)
32+
return
33+
}
34+
defer resp.Body.Close()
35+
36+
fmt.Println(resp.Status)
37+
38+
// Output:
39+
// 200 OK
40+
}

httpsig.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"crypto/rsa"
1111
"io/ioutil"
1212
"net/http"
13+
"time"
1314
)
1415

1516
var defaultHeaders = []string{"content-type", "content-length", "host"} // also request path and digest
@@ -32,7 +33,10 @@ func sliceHas(haystack []string, needle string) bool {
3233
// included on each request. Multiple included signatures allow you to gracefully introduce stronger
3334
// algorithms, rotate keys, etc.
3435
func NewSignTransport(transport http.RoundTripper, opts ...signOption) http.RoundTripper {
35-
s := signer{}
36+
s := signer{
37+
keys: map[string]sigHolder{},
38+
nowFunc: time.Now,
39+
}
3640

3741
for _, o := range opts {
3842
o.configureSign(&s)
@@ -45,8 +49,8 @@ func NewSignTransport(transport http.RoundTripper, opts ...signOption) http.Roun
4549
// TODO: normalize headers? lowercase & de-dupe
4650

4751
// request path first, for aesthetics
48-
if !sliceHas(s.headers, "@request-path") {
49-
s.headers = append([]string{"@request-path"}, s.headers...)
52+
if !sliceHas(s.headers, "@request-target") {
53+
s.headers = append([]string{"@request-target"}, s.headers...)
5054
}
5155

5256
if !sliceHas(s.headers, "digest") {
@@ -84,7 +88,7 @@ func NewSignTransport(transport http.RoundTripper, opts ...signOption) http.Roun
8488
nr.Header[k] = v
8589
}
8690

87-
return transport.RoundTrip(r)
91+
return transport.RoundTrip(nr)
8892
})
8993
}
9094

@@ -104,7 +108,10 @@ func (r rt) RoundTrip(req *http.Request) (*http.Response, error) { return r(req)
104108
func NewVerifyMiddleware(opts ...verifyOption) func(http.Handler) http.Handler {
105109

106110
// TODO: form and multipart support
107-
v := verifier{}
111+
v := verifier{
112+
keys: make(map[string]verHolder),
113+
nowFunc: time.Now,
114+
}
108115

109116
for _, o := range opts {
110117
o.configureVerify(&v)

sign.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ type signer struct {
4141
func (s *signer) Sign(msg *message) (http.Header, error) {
4242
var b bytes.Buffer
4343

44+
var items []string
45+
4446
// canonicalize headers
4547
for _, h := range s.headers {
4648
// optionally canonicalize request path via magic string
@@ -49,13 +51,22 @@ func (s *signer) Sign(msg *message) (http.Header, error) {
4951
if err != nil {
5052
return nil, err
5153
}
54+
55+
items = append(items, h)
56+
continue
57+
}
58+
59+
// Skip unset headers
60+
if len(msg.Header.Values(h)) == 0 {
5261
continue
5362
}
5463

5564
err := canonicalizeHeader(&b, h, msg.Header)
5665
if err != nil {
5766
return nil, err
5867
}
68+
69+
items = append(items, h)
5970
}
6071

6172
now := s.nowFunc()
@@ -65,7 +76,7 @@ func (s *signer) Sign(msg *message) (http.Header, error) {
6576
i := 1 // 1 indexed icky
6677
for k, si := range s.keys {
6778
sp := &signatureParams{
68-
items: s.headers,
79+
items: items,
6980
keyID: k,
7081
created: now,
7182
alg: si.alg,

0 commit comments

Comments
 (0)