Skip to content

Commit

Permalink
Apparently Data.withContiguousStorageIfAvailable() doesn't work
Browse files Browse the repository at this point in the history
Use withUnsafeBytes instead.
Added a test to ensure we get the same signature from string, data and byteBuffer.
Also added '+' as a character to be percent encoded.
  • Loading branch information
adam-fowler committed Aug 30, 2019
1 parent 28f9603 commit 8cd6b1a
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
6 changes: 3 additions & 3 deletions Sources/AWSSigner/signer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ public class AWSSigner {
case .string(let string):
hash = sha256(string)
case .data(let data):
hash = data.withContiguousStorageIfAvailable { bytes in

This comment has been minimized.

Copy link
@lhunath

lhunath Jan 6, 2020

Can someone explain why this is necessary / why withContiguousStorageIfAvailable fails?

This comment has been minimized.

Copy link
@adam-fowler

adam-fowler Jan 6, 2020

Author Owner

From Apple documentation If the collection does not support an internal representation in a form of contiguous storage, body is not called and nil is returned. I'm guessing Data doesn't always support returning a contiguous buffer

return sha256(bytes)
hash = data.withUnsafeBytes { bytes in
return sha256(bytes.bindMemory(to: UInt8.self))
}
case .byteBuffer(let byteBuffer):
let byteBufferView = byteBuffer.readableBytesView
Expand Down Expand Up @@ -220,5 +220,5 @@ public class AWSSigner {
return formatter.string(from: date)
}

static let queryAllowedCharacters = CharacterSet(charactersIn:"/;").inverted
static let queryAllowedCharacters = CharacterSet(charactersIn:"/;+").inverted
}
18 changes: 18 additions & 0 deletions Tests/AWSSignerTests/AWSSignerTests.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import XCTest
import AsyncHTTPClient
import NIO
@testable import AWSSigner

final class AWSSignerTests: XCTestCase {
Expand Down Expand Up @@ -28,6 +29,23 @@ final class AWSSignerTests: XCTestCase {
let url = signer.signURL(url: URL(string: "https://test-bucket.s3.amazonaws.com/test-put.txt")!, method: .PUT, body: .string("Testing signed URLs"), date:Date(timeIntervalSinceReferenceDate: 100000))
XCTAssertEqual(url.absoluteString, "https://test-bucket.s3.amazonaws.com/test-put.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=MYACCESSKEY%2F20010102%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Date=20010102T034640Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=13d665549a6ea5eb6a1615ede83440eaed3e0ee25c964e62d188c896d916d96f")
}

func testBodyData() {
let string = "testing, testing, 1,2,1,2"
let data = string.data(using: .utf8)!
var buffer = ByteBufferAllocator().buffer(capacity: data.count)
buffer.writeBytes(data)

let signer = AWSSigner(credentials: credentials, name: "sns", region:"eu-west-1")
let headers1 = signer.signHeaders(url: URL(string: "https://sns.eu-west-1.amazonaws.com/")!, method: .POST, body: .string(string), date: Date(timeIntervalSinceReferenceDate: 0))
let headers2 = signer.signHeaders(url: URL(string: "https://sns.eu-west-1.amazonaws.com/")!, method: .POST, body: .data(data), date: Date(timeIntervalSinceReferenceDate: 0))
let headers3 = signer.signHeaders(url: URL(string: "https://sns.eu-west-1.amazonaws.com/")!, method: .POST, body: .byteBuffer(buffer), date: Date(timeIntervalSinceReferenceDate: 0))

XCTAssertNotNil(headers1["Authorization"].first)
XCTAssertEqual(headers1["Authorization"].first, headers2["Authorization"].first)
XCTAssertEqual(headers2["Authorization"].first, headers3["Authorization"].first)
}

static var allTests = [
("testSignGetHeaders", testSignGetHeaders),
("testSignPutHeaders", testSignPutHeaders),
Expand Down

0 comments on commit 8cd6b1a

Please sign in to comment.