Skip to content

Commit 6f15864

Browse files
authored
The authorization header was being calculated incorrectly due to incorrect sorting on amz headers when there existed a header that started with an underscore. The http.Header implementation automatically camel cases headers. We were sorting the header keys before lower casing them when calculating the authorization header. Since underscore sorts differently when compared to upper and lower cased alpha characters, this created an incorrect sort order in the stringToSign. Fixed sorting to take place after lower casing header keys. Also fixed two stale tests that were failing due to unrelated issues. (#122)
1 parent eb72495 commit 6f15864

File tree

4 files changed

+31
-17
lines changed

4 files changed

+31
-17
lines changed

ds3/networking/canonicalHeaders.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package networking
2+
3+
// Used to correctly sort headers when creating the stringToSign for the authorization header.
4+
type CanonicalHeader struct{
5+
key string // key is assumed to be lower cased
6+
values []string
7+
}
8+
type CanonicalHeaders []CanonicalHeader
9+
10+
func (p CanonicalHeaders) Len() int { return len(p) }
11+
func (p CanonicalHeaders) Less(i, j int) bool { return p[i].key < p[j].key }
12+
func (p CanonicalHeaders) Swap(i, j int) { p[i], p[j] = p[j], p[i] }

ds3/networking/headers_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
)
1818

1919
func TestBuildAuthHeaderValue(t *testing.T) {
20-
expected := "AWS access:1JbBTxv5KRFKbvju7w27c2J6bKk="
20+
expected := "AWS access:gmW4yg/tw02UYleIqGn5ebvKbr8="
2121

2222
fields := signatureFields{
2323
Verb:"PUT",

ds3/networking/httpRequestBuilder.go

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -207,33 +207,31 @@ func (builder *HttpRequestBuilder) maybeAddSignatureQueryParams() {
207207
}
208208

209209
func (builder *HttpRequestBuilder) maybeAddAmazonCanonicalHeaders() {
210-
headerKeys := make([]string, 0)
210+
var canonicalHeaders CanonicalHeaders
211211

212212
for key, value := range *builder.headers {
213213
lowerCaseKey := strings.ToLower(key)
214214
if strings.HasPrefix(lowerCaseKey, models.AMZ_META_HEADER) && len(value) > 0 {
215-
headerKeys = append(headerKeys, key)
215+
canonicalHeaders = append(canonicalHeaders, CanonicalHeader{
216+
key: lowerCaseKey,
217+
values: value,
218+
})
216219
}
217220
}
218221

219-
if len(headerKeys) == 0 {
222+
if len(canonicalHeaders) == 0 {
220223
return
221224
}
222225

223-
sort.Strings(headerKeys)
226+
sort.Sort(canonicalHeaders)
224227

225228
var stringBuilder strings.Builder
226229

227-
var httpHeaders map[string][]string = *builder.headers
228-
229-
for _, headerKey := range headerKeys {
230-
lowerCaseKey := strings.ToLower(headerKey)
231-
headerValue := httpHeaders[headerKey]
232-
233-
if len(headerValue) > 0 {
234-
stringBuilder.WriteString(lowerCaseKey)
230+
for _, header := range canonicalHeaders {
231+
if len(header.values) > 0 {
232+
stringBuilder.WriteString(header.key)
235233
stringBuilder.WriteString(":")
236-
stringBuilder.WriteString(strings.Join(headerValue, ","))
234+
stringBuilder.WriteString(strings.Join(header.values, ","))
237235
stringBuilder.WriteString("\n")
238236
}
239237
}

ds3_integration/smoke_test.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ func TestDeleteBucketNonEmpty(t *testing.T) {
176176
putObjErr := testutils.PutObjectLogError(t, client, bucketName, beowulf, book)
177177
ds3Testing.AssertNilError(t, putObjErr)
178178

179-
//Attempt to delete non-empty bucket
180-
deleteErr := testutils.DeleteBucket(client, bucketName)
179+
//Attempt to delete non-empty bucket without force
180+
_, deleteErr := client.DeleteBucketSpectraS3(models.NewDeleteBucketSpectraS3Request(bucketName))
181181
ds3Testing.AssertBadStatusCodeError(t, 409, deleteErr)
182182
}
183183

@@ -544,7 +544,11 @@ func TestPuttingZeroLengthObject(t *testing.T) {
544544

545545
zeroBytes := make([]byte, 0)
546546

547-
putObjectRequest := models.NewPutObjectRequest(bucketName, objectName, ds3.BuildByteReaderWithSizeDecorator(zeroBytes))
547+
putObjectRequest := models.NewPutObjectRequest(bucketName, objectName, ds3.BuildByteReaderWithSizeDecorator(zeroBytes)).
548+
WithMetaData("_c", "C").
549+
WithMetaData("d", "D").
550+
WithMetaData("_a", "A").
551+
WithMetaData("b", "B")
548552

549553
_, err = client.PutObject(putObjectRequest)
550554

0 commit comments

Comments
 (0)