Skip to content

Commit

Permalink
Fix encoding of dates in Query
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-fowler committed Jan 1, 2025
1 parent 2614aa4 commit 7ee4691
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
4 changes: 4 additions & 0 deletions Sources/SotoCore/Encoder/CodableProperties/DateCoders.swift
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,8 @@ public struct UnixEpochDateCoder: CustomDecoder, CustomEncoder {
var container = encoder.singleValueContainer()
try container.encode(value.timeIntervalSince1970)
}

public static func string(from value: Date) -> String? {
Int(value.timeIntervalSince1970).description
}
}
28 changes: 26 additions & 2 deletions Sources/SotoCore/Encoder/RequestContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public class RequestEncodingContainer {
if queryParams.count > 0 {
let urlQueryString =
queryParams
.map { (key: $0.key, value: "\($0.value)") }
.map { (key: $0.key, value: $0.value) }
.sorted {
// sort by key. if key are equal then sort by value
if $0.key < $1.key { return true }
Expand Down Expand Up @@ -113,12 +113,20 @@ public class RequestEncodingContainer {
}
}

/// Write dictionary key value pairs to headers with prefix added to the keys
/// Write date to headers
@inlinable
public func encodeHeader(_ value: Date, key: String) {
self.encodeHeader(HTTPHeaderDateCoder.string(from: value), key: key)
}

/// Write date to headers
@inlinable
public func encodeHeader(_ value: Date?, key: String) {
if let value {
self.encodeHeader(value, key: key)
}
}

/// Write dictionary key value pairs to headers with prefix added to the keys
@inlinable
public func encodeHeader(_ value: [String: some Any], key prefix: String) {
Expand Down Expand Up @@ -167,6 +175,20 @@ public class RequestEncodingContainer {
}
}

/// Write date to query
@inlinable
public func encodeQuery(_ value: Date, key: String) {
self.encodeQuery(UnixEpochDateCoder.string(from: value), key: key)
}

/// Write optional date to query
@inlinable
public func encodeQuery(_ value: Date?, key: String) {
if let value {
self.encodeQuery(value, key: key)
}
}

/// Write array as a series of query values
@inlinable
public func encodeQuery(_ value: [some Any], key: String) {
Expand Down Expand Up @@ -199,6 +221,8 @@ public class RequestEncodingContainer {
}
}

// MARK: Path encoding

/// Write value into URI path
@inlinable
public func encodePath(_ value: some Any, key: String) {
Expand Down
18 changes: 18 additions & 0 deletions Tests/SotoCoreTests/AWSRequestTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,24 @@ class AWSRequestTests: XCTestCase {
XCTAssertEqual(request?.url.absoluteString, "https://myservice.us-east-2.amazonaws.com/?one=1&two=2")
}

func testQueryDate() {
struct Input: AWSEncodableShape {
let d: Date?
func encode(to encoder: Encoder) throws {
_ = encoder.container(keyedBy: CodingKeys.self)
let requestContainer = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
requestContainer.encodeQuery(self.d, key: "d")
}

private enum CodingKeys: CodingKey {}
}
let input = Input(d: Date(timeIntervalSince1970: 1_000_000))
let config = createServiceConfig(region: .useast2, service: "myservice")
var request: AWSHTTPRequest?
XCTAssertNoThrow(request = try AWSHTTPRequest(operation: "Test", path: "/", method: .GET, input: input, configuration: config))
XCTAssertEqual(request?.url.absoluteString, "https://myservice.us-east-2.amazonaws.com/?d=1000000")
}

func testQueryInPath() {
struct Input: AWSEncodableShape {
let q: String
Expand Down

0 comments on commit 7ee4691

Please sign in to comment.