Skip to content

Commit

Permalink
Fix multi-value query values in APIGatewayV2
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-fowler committed Mar 5, 2024
1 parent a36500e commit 59b99fe
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 16 deletions.
20 changes: 19 additions & 1 deletion Sources/HummingbirdLambda/APIGatewayLambda.swift
Expand Up @@ -57,7 +57,25 @@ extension HBLambda where Output == APIGatewayResponse {
}

// conform `APIGatewayRequest` to `APIRequest` so we can use HBRequest.init(context:application:from)
extension APIGatewayRequest: APIRequest {}
extension APIGatewayRequest: APIRequest {
var queryString: String {
func urlPercentEncoded(_ string: String) -> String {
return string.addingPercentEncoding(withAllowedCharacters: .urlQueryComponentAllowed) ?? string
}
var queryParams: [String] = []
var queryStringParameters = self.queryStringParameters ?? [:]
// go through list of multi value query string params first, removing any
// from the single value list if they are found in the multi value list
self.multiValueQueryStringParameters?.forEach { multiValueQuery in
queryStringParameters[multiValueQuery.key] = nil
queryParams += multiValueQuery.value.map { "\(urlPercentEncoded(multiValueQuery.key))=\(urlPercentEncoded($0))" }
}
queryParams += queryStringParameters.map {
"\(urlPercentEncoded($0.key))=\(urlPercentEncoded($0.value))"
}
return queryParams.joined(separator: "&")
}
}

// conform `APIGatewayResponse` to `APIResponse` so we can use HBResponse.apiReponse()
extension APIGatewayResponse: APIResponse {}
1 change: 1 addition & 0 deletions Sources/HummingbirdLambda/APIGatewayV2Lambda.swift
Expand Up @@ -65,6 +65,7 @@ extension APIGatewayV2Request: APIRequest {
var httpMethod: AWSLambdaEvents.HTTPMethod { context.http.method }
var multiValueQueryStringParameters: [String: [String]]? { nil }
var multiValueHeaders: HTTPMultiValueHeaders { [:] }
var queryString: String { self.rawQueryString }
}

// conform `APIGatewayV2Response` to `APIResponse` so we can use HBResponse.apiReponse()
Expand Down
18 changes: 3 additions & 15 deletions Sources/HummingbirdLambda/Request+APIGateway.swift
Expand Up @@ -23,8 +23,7 @@ import NIOCore
protocol APIRequest {
var path: String { get }
var httpMethod: AWSLambdaEvents.HTTPMethod { get }
var queryStringParameters: [String: String]? { get }
var multiValueQueryStringParameters: [String: [String]]? { get }
var queryString: String { get }
var headers: AWSLambdaEvents.HTTPHeaders { get }
var multiValueHeaders: HTTPMultiValueHeaders { get }
var body: String? { get }
Expand All @@ -44,19 +43,8 @@ extension HBRequest {

// construct URI with query parameters
var uri = from.path
var queryParams: [String] = []
var queryStringParameters = from.queryStringParameters ?? [:]
// go through list of multi value query string params first, removing any
// from the single value list if they are found in the multi value list
from.multiValueQueryStringParameters?.forEach { multiValueQuery in
queryStringParameters[multiValueQuery.key] = nil
queryParams += multiValueQuery.value.map { "\(urlPercentEncoded(multiValueQuery.key))=\(urlPercentEncoded($0))" }
}
queryParams += queryStringParameters.map {
"\(urlPercentEncoded($0.key))=\(urlPercentEncoded($0.value))"
}
if queryParams.count > 0 {
uri += "?\(queryParams.joined(separator: "&"))"
if from.queryString.count > 0 {
uri += "?\(from.queryString)"
}
// construct headers
var authority: String?
Expand Down

0 comments on commit 59b99fe

Please sign in to comment.