Skip to content
This repository was archived by the owner on Apr 20, 2024. It is now read-only.

Commit 51ef14d

Browse files
authored
Merge pull request #8 from nodes-vapor/percent-encoder
Percent Encoder
2 parents c1ac522 + c72e672 commit 51ef14d

File tree

2 files changed

+39
-14
lines changed

2 files changed

+39
-14
lines changed

Sources/Driver/Authentication/Authentication.swift

+2-14
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,6 @@ struct Authentication {
2323

2424
//used for unit tests
2525
var unitTestDate: Date?
26-
27-
static let awsQueryAllowed = CharacterSet(
28-
charactersIn: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-._~="
29-
)
30-
31-
static let awsPathAllowed = CharacterSet(
32-
charactersIn: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-._~/"
33-
)
3426

3527
var amzDate: String {
3628
let dateFormatter = DateFormatter()
@@ -54,14 +46,10 @@ struct Authentication {
5446
self.host = host
5547
self.region = region
5648
//TODO(Brett): Proper encoding and error handling.
57-
self.baseURL = baseURL.addingPercentEncoding(
58-
withAllowedCharacters: Authentication.awsPathAllowed
59-
)!
49+
self.baseURL = try! baseURL.percentEncode(allowing: Byte.awsPathAllowed)
6050
self.key = key
6151
self.secret = secret
62-
self.requestParam = requestParam?.addingPercentEncoding(
63-
withAllowedCharacters: Authentication.awsQueryAllowed
64-
)
52+
self.requestParam = try! requestParam?.percentEncode(allowing: Byte.awsQueryAllowed)
6553
}
6654

6755
func getSignature(stringToSign: String) throws -> String {

Sources/Driver/PercentEncoder.swift

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import Core
2+
3+
extension Byte {
4+
static let awsQueryAllowed = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-._~=".bytes
5+
6+
static let awsPathAllowed = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-._~/".bytes
7+
}
8+
9+
extension String {
10+
func percentEncode(allowing allowed: Bytes) throws -> String {
11+
let bytes = self.bytes
12+
let encodedBytes = try percentEncodedUppercase(bytes, shouldEncode: {
13+
return !allowed.contains($0)
14+
})
15+
return encodedBytes.string
16+
}
17+
}
18+
19+
func percentEncodedUppercase(
20+
_ input: [Byte],
21+
shouldEncode: (Byte) throws -> Bool = { _ in true }
22+
) throws -> [Byte] {
23+
var group: [Byte] = []
24+
try input.forEach { byte in
25+
if try shouldEncode(byte) {
26+
let hex = String(byte, radix: 16).uppercased().utf8
27+
group.append(.percent)
28+
if hex.count == 1 {
29+
group.append(.zero)
30+
}
31+
group.append(contentsOf: hex)
32+
} else {
33+
group.append(byte)
34+
}
35+
}
36+
return group
37+
}

0 commit comments

Comments
 (0)