Skip to content

Commit 286773f

Browse files
authored
Merge pull request #64 from SpectraLogic/authorization_digest
Authorization digest
2 parents b9128f9 + 7233310 commit 286773f

File tree

2 files changed

+78
-2
lines changed

2 files changed

+78
-2
lines changed

ds3/networking/httpRequestBuilder.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ import (
66
"net/url"
77
"strings"
88
"spectra/ds3_go_sdk/ds3/models"
9+
"sort"
910
)
1011

12+
const AmazonMetadataPrefix = "x-amz-meta-"
13+
1114
type HttpRequestBuilder struct {
1215
reader io.Reader
1316
contentLength *int64
@@ -116,19 +119,60 @@ func (builder *HttpRequestBuilder) Build(conn *ConnectionInfo) (*http.Request, e
116119

117120
builder.signatureFields.Date = getCurrentTime()
118121

122+
builder.maybeAddAmazonCanonicalHeaders()
123+
119124
authHeaderVal := builder.signatureFields.BuildAuthHeaderValue(conn.Credentials)
120125

121126
// Set the http request headers such as authorization and date.
122127
return builder.addHttpRequestHeaders(httpRequest, authHeaderVal)
123128
}
124129

125130
func (builder *HttpRequestBuilder) buildUrl(conn *ConnectionInfo) string {
126-
var httpUrl url.URL = *conn.Endpoint
131+
var httpUrl = *conn.Endpoint
127132
httpUrl.Path = builder.signatureFields.Path
128133
httpUrl.RawQuery = encodeQueryParams(builder.queryParams)
129134
return httpUrl.String()
130135
}
131136

137+
func (builder *HttpRequestBuilder) maybeAddAmazonCanonicalHeaders() {
138+
headerKeys := make([]string, 0)
139+
140+
for key, value := range *builder.headers {
141+
lowerCaseKey := strings.ToLower(key)
142+
if strings.HasPrefix(lowerCaseKey, models.AMZ_META_HEADER) && len(value) > 0 {
143+
headerKeys = append(headerKeys, key)
144+
}
145+
}
146+
147+
if len(headerKeys) == 0 {
148+
return
149+
}
150+
151+
sort.Strings(headerKeys)
152+
153+
var stringBuilder strings.Builder
154+
155+
var httpHeaders map[string][]string = *builder.headers
156+
157+
for _, headerKey := range headerKeys {
158+
lowerCaseKey := strings.ToLower(headerKey)
159+
headerValue := httpHeaders[headerKey]
160+
161+
if len(headerValue) > 0 {
162+
stringBuilder.WriteString(lowerCaseKey)
163+
stringBuilder.WriteString(":")
164+
stringBuilder.WriteString(strings.Join(headerValue, ","))
165+
stringBuilder.WriteString("\n")
166+
}
167+
}
168+
169+
canonicalAmazonHeaders := stringBuilder.String()
170+
171+
if len(canonicalAmazonHeaders) > 0 {
172+
builder.signatureFields.CanonicalizedAmzHeaders = stringBuilder.String()
173+
}
174+
}
175+
132176
func (builder *HttpRequestBuilder) addHttpRequestHeaders(httpRequest *http.Request, authHeader string) (*http.Request, error) {
133177
httpRequest.Header.Add("Date", builder.signatureFields.Date)
134178
httpRequest.Header.Add("Authorization", authHeader)
@@ -155,3 +199,4 @@ func encodeQueryParams(queryParams *url.Values) string {
155199
// with percent encoding for spaces (%20)
156200
return strings.Replace(queryParams.Encode(), "+", "%20", -1)
157201
}
202+

ds3/networking/networking_test.go

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"testing"
1616
"net/url"
1717
"spectra/ds3_go_sdk/ds3_utils/ds3Testing"
18+
"strings"
1819
)
1920

2021
func TestEncodeQueryParams(t *testing.T) {
@@ -28,4 +29,34 @@ func TestEncodeQueryParams(t *testing.T) {
2829
result := encodeQueryParams(queryParams)
2930

3031
ds3Testing.AssertString(t, "Encoded Query Params", expected, result)
31-
}
32+
}
33+
34+
func TestBuildingAuthorizationDigestWithMetadata(t *testing.T) {
35+
httpRequestBuilder := NewHttpRequestBuilder()
36+
37+
endpointUrl, err := url.Parse("https://google.com")
38+
ds3Testing.AssertNilError(t, err)
39+
40+
const gracie = "Gracie"
41+
const eskimo = "Eskimo"
42+
const shasta = "Shasta"
43+
const samoyed = "Samoyed"
44+
45+
connectionInfo := ConnectionInfo{
46+
Endpoint: endpointUrl,
47+
Credentials: &Credentials{AccessId: gracie, Key: eskimo},
48+
Proxy: nil}
49+
50+
httpRequestBuilder.
51+
WithHeader(AmazonMetadataPrefix + shasta, samoyed).
52+
WithHeader(AmazonMetadataPrefix + gracie, eskimo).
53+
Build(&connectionInfo)
54+
55+
amazonHeaders := httpRequestBuilder.signatureFields.CanonicalizedAmzHeaders
56+
57+
ds3Testing.AssertBool(t, "expected amazonHeader to have something in it", true, len(amazonHeaders) > 0)
58+
59+
expected := AmazonMetadataPrefix + strings.ToLower(gracie) + ":" + eskimo + "\n" + AmazonMetadataPrefix + strings.ToLower(shasta) + ":" + samoyed + "\n"
60+
ds3Testing.AssertBool(t, "amazonHeader string isn't what we expected", true, strings.Compare(amazonHeaders, expected) == 0)
61+
}
62+

0 commit comments

Comments
 (0)