Skip to content

Commit cc83875

Browse files
committed
Content-Digest header
1 parent 6b81211 commit cc83875

File tree

5 files changed

+99
-5
lines changed

5 files changed

+99
-5
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ Below is what a basic client-side integration looks like:
1515
// Create a signer and a wrapped HTTP client
1616
signer, _ := httpsign.NewRSAPSSSigner("key1", *prvKey,
1717
httpsign.NewSignConfig(),
18-
httpsign.Headers("@request-target"))
19-
client := httpsign.NewDefaultClient("sig1", signer, nil, nil) // sign requests, don't verify responses
18+
httpsign.Headers("@request-target", "Content-Digest")) // The Content-Digest header will be auto-generated
19+
client := httpsign.NewDefaultClient(httpsign.NewClientConfig().SetSignatureName("sig1").SetSigner(signer)) // sign requests, don't verify responses
2020
2121
// Send an HTTP POST, get response -- signing and verification happen behind the scenes
2222
body := `{"hello": "world"}`

client_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ package httpsign
33
import (
44
"bytes"
55
"fmt"
6+
"github.com/stretchr/testify/assert"
67
"log"
78
"net/http"
89
"net/http/httptest"
10+
"net/url"
911
"reflect"
12+
"sort"
1013
"testing"
1114
)
1215

@@ -239,3 +242,63 @@ func TestClient_Head(t *testing.T) {
239242
})
240243
}
241244
}
245+
246+
func TestClient_PostForm(t *testing.T) {
247+
type fields struct {
248+
config ClientConfig
249+
client http.Client
250+
}
251+
type args struct {
252+
url string
253+
data url.Values
254+
}
255+
256+
ts := makeTestServer()
257+
defer ts.Close()
258+
259+
tests := []struct {
260+
name string
261+
fields fields
262+
args args
263+
wantRespHeaders []string
264+
wantErr assert.ErrorAssertionFunc
265+
}{
266+
{
267+
name: "happy path",
268+
fields: fields{
269+
config: *NewClientConfig(),
270+
client: *http.DefaultClient,
271+
},
272+
args: args{
273+
url: ts.URL,
274+
data: func() url.Values {
275+
var v url.Values = url.Values{}
276+
v.Add("k1", "v1")
277+
v.Set("k2", "v2")
278+
return v
279+
}(),
280+
},
281+
wantRespHeaders: []string{"Content-Length", "Content-Type", "Date"},
282+
wantErr: assert.NoError,
283+
},
284+
}
285+
286+
for _, tt := range tests {
287+
t.Run(tt.name, func(t *testing.T) {
288+
c := &Client{
289+
config: tt.fields.config,
290+
client: tt.fields.client,
291+
}
292+
gotResp, err := c.PostForm(tt.args.url, tt.args.data)
293+
if !tt.wantErr(t, err, fmt.Sprintf("PostForm(%v, %v)", tt.args.url, tt.args.data)) {
294+
return
295+
}
296+
headers := []string{}
297+
for k, _ := range gotResp.Header {
298+
headers = append(headers, k)
299+
}
300+
sort.Strings(headers)
301+
assert.Equalf(t, tt.wantRespHeaders, headers, "PostForm(%v, %v)", tt.args.url, tt.args.data)
302+
})
303+
}
304+
}

clientex_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func TestClientUsage(t *testing.T) {
109109
// Create a signer and a wrapped HTTP client
110110
signer, _ := httpsign.NewRSAPSSSigner("key1", *prvKey,
111111
httpsign.NewSignConfig(),
112-
httpsign.Headers("@request-target", "Content-Digest"))
112+
httpsign.Headers("@request-target", "Content-Digest")) // The Content-Digest header will be auto-generated
113113
client := httpsign.NewDefaultClient(httpsign.NewClientConfig().SetSignatureName("sig1").SetSigner(signer)) // sign requests, don't verify responses
114114

115115
// Send an HTTP POST, get response -- signing and verification happen behind the scenes

digest_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,20 @@ Content-Digest: sha-256=:Wqdirjg/u3J688ejbUlApbjECpiUUtIwT8lY/z81Tno=:
2020
2121
"hello"`
2222

23+
var resdigest3 = `HTTP/1.1 206 Partial Content
24+
Content-Type: application/json
25+
Content-Range: bytes 1-7/18
26+
Content-Digest: sha-256=:Wqdirjg/u3J688ejbUlApbjECpiUUtIwT8lY/z81Tno=:
27+
28+
"hello!!"`
29+
30+
var resdigest5 = `HTTP/1.1 206 Partial Content
31+
Content-Type: application/json
32+
Content-Range: bytes 1-7/18
33+
Content-Digest: sha-512=:A8pplr4vsk4xdLkJruCXWp6+i+dy/3pSW5HW5ke1jDWS70Dv6Fstf1jS+XEcLqEVhW3i925IPlf/4tnpnvAQDw==:
34+
35+
"hello"`
36+
2337
func TestMessages(t *testing.T) {
2438
res1 := readResponse(resdigest1)
2539
d, err := GenerateContentDigest(&res1.Body, DigestSha256)
@@ -33,4 +47,20 @@ func TestMessages(t *testing.T) {
3347
assert.NoError(t, err, "should not fail to generate digest")
3448
h = res2.Header.Get("Content-Digest")
3549
assert.Equal(t, h, d)
50+
51+
res3 := readResponse(resdigest3)
52+
d, err = GenerateContentDigest(&res3.Body, DigestSha256)
53+
assert.NoError(t, err, "should not fail to generate digest")
54+
h = res3.Header.Get("Content-Digest")
55+
assert.NotEqual(t, h, d)
56+
57+
res4 := readResponse(resdigest3)
58+
d, err = GenerateContentDigest(&res4.Body, "sha-999")
59+
assert.Error(t, err, "bad digest scheme")
60+
61+
res5 := readResponse(resdigest5)
62+
d, err = GenerateContentDigest(&res5.Body, DigestSha512)
63+
assert.NoError(t, err, "should not fail to generate digest")
64+
h = res5.Header.Get("Content-Digest")
65+
assert.Equal(t, h, d)
3666
}

handler_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"log"
99
"net/http"
1010
"net/http/httptest"
11+
"strings"
1112
"testing"
1213
)
1314

@@ -38,13 +39,13 @@ func Test_WrapHandler(t *testing.T) {
3839
defer ts.Close()
3940

4041
signer, err := NewHMACSHA256Signer("key", bytes.Repeat([]byte{1}, 64), nil,
41-
Headers("@method"))
42+
Headers("@method", "content-digest"))
4243
assert.NoError(t, err)
4344

4445
verifier, err := NewHMACSHA256Verifier("key", bytes.Repeat([]byte{0}, 64), NewVerifyConfig(), *NewFields())
4546
assert.NoError(t, err)
4647
client := NewDefaultClient(NewClientConfig().SetSignatureName("sig1").SetSigner(signer).SetVerifier(verifier).SetDigestScheme(DigestSha256))
47-
res, err := client.Get(ts.URL)
48+
res, err := client.Post(ts.URL, "text/plain", strings.NewReader("Message body here"))
4849
assert.NoError(t, err)
4950
if res != nil {
5051
_, err = io.ReadAll(res.Body)

0 commit comments

Comments
 (0)