-
Notifications
You must be signed in to change notification settings - Fork 34
Add (API Gateway) WebSockets Support to Swift for AWS Lambda Events #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c1af9de
1fe651a
e1ecc13
1dea37e
638bad1
324fbc9
10ffcab
b255966
a658fd9
a050d03
3ddb1b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file is part of the SwiftAWSLambdaRuntime open source project | ||
// | ||
// Copyright (c) YEARS Apple Inc. and the SwiftAWSLambdaRuntime project authors | ||
// Licensed under Apache License v2.0 | ||
// | ||
// See LICENSE.txt for license information | ||
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
/// `APIGatewayWebSocketRequest` is a variation of the`APIGatewayV2Request` | ||
/// and contains data coming from the WebSockets API Gateway. | ||
public struct APIGatewayWebSocketRequest: Codable { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can any of this vibe shared with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh sure ... much of it can be. I just wasn't sure what the correct approach should be. I kind of aimed for a "what's the minimum to make it work" approach. :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. probably some shared struct they can both include as the underlying implementation There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it would be helpful, I would be happy to look at the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it would be helpful, I would be happy to look at the |
||
/// `Context` contains information to identify the AWS account and resources invoking the Lambda function. | ||
public struct Context: Codable { | ||
public struct Identity: Codable { | ||
public let sourceIp: String | ||
} | ||
|
||
public let routeKey: String | ||
public let eventType: String | ||
public let extendedRequestId: String | ||
/// The request time in format: 23/Apr/2020:11:08:18 +0000 | ||
public let requestTime: String | ||
public let messageDirection: String | ||
public let stage: String | ||
public let connectedAt: UInt64 | ||
public let requestTimeEpoch: UInt64 | ||
public let identity: Identity | ||
public let requestId: String | ||
public let domainName: String | ||
public let connectionId: String | ||
public let apiId: String | ||
} | ||
|
||
public let headers: HTTPHeaders? | ||
public let multiValueHeaders: HTTPMultiValueHeaders? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also see
come through on a CONNECT event type |
||
public let context: Context | ||
public let body: String? | ||
public let isBase64Encoded: Bool? | ||
|
||
enum CodingKeys: String, CodingKey { | ||
case headers | ||
case multiValueHeaders | ||
case context = "requestContext" | ||
case body | ||
case isBase64Encoded | ||
} | ||
} | ||
|
||
/// `APIGatewayWebSocketResponse` is a type alias for `APIGatewayV2Request`. | ||
/// Typically, lambda WebSockets servers send clients data via | ||
/// the ApiGatewayManagementApi mechanism. However, APIGateway does require | ||
/// lambda servers to return some kind of status when APIGateway invokes them. | ||
/// This can be as simple as always returning a 200 "OK" response for all | ||
/// WebSockets requests (the ApiGatewayManagementApi can return any errors to | ||
/// WebSockets clients). | ||
public typealias APIGatewayWebSocketResponse = APIGatewayV2Response | ||
|
||
#if swift(>=5.6) | ||
extension APIGatewayWebSocketRequest: Sendable {} | ||
extension APIGatewayWebSocketRequest.Context: Sendable {} | ||
extension APIGatewayWebSocketRequest.Context.Identity: Sendable {} | ||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file is part of the SwiftAWSLambdaRuntime open source project | ||
// | ||
// Copyright (c) YEARS Apple Inc. and the SwiftAWSLambdaRuntime project authors | ||
sebsto marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Licensed under Apache License v2.0 | ||
// | ||
// See LICENSE.txt for license information | ||
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
import Foundation | ||
import Testing | ||
|
||
@testable import AWSLambdaEvents | ||
|
||
@Suite | ||
class APIGatewayWebSocketsTests { | ||
static let exampleConnectEventBody = """ | ||
{ | ||
"headers": { | ||
"Host": "lqrlmblaa2.execute-api.us-east-1.amazonaws.com", | ||
"Origin": "wss://lqrlmblaa2.execute-api.us-east-1.amazonaws.com", | ||
"Sec-WebSocket-Extensions": "", | ||
"Sec-WebSocket-Key": "am5ubWVpbHd3bmNyYXF0ag==", | ||
"Sec-WebSocket-Version": "13", | ||
"X-Amzn-Trace-Id": "Root=1-64b83950-42de8e247b4c2b43091ef67c", | ||
"X-Forwarded-For": "24.148.42.16", | ||
"X-Forwarded-Port": "443", | ||
"X-Forwarded-Proto": "https" | ||
}, | ||
"multiValueHeaders": { | ||
"Host": [ "lqrlmblaa2.execute-api.us-east-1.amazonaws.com" ], | ||
"Origin": [ "wss://lqrlmblaa2.execute-api.us-east-1.amazonaws.com" ], | ||
"Sec-WebSocket-Extensions": [ | ||
"permessage-deflate; client_max_window_bits; server_max_window_bits=15" | ||
], | ||
"Sec-WebSocket-Key": [ "am5ubWVpbHd3bmNyYXF0ag==" ], | ||
"Sec-WebSocket-Version": [ "13" ], | ||
"X-Amzn-Trace-Id": [ "Root=1-64b83950-42de8e247b4c2b43091ef67c" ], | ||
"X-Forwarded-For": [ "24.148.42.16" ], | ||
"X-Forwarded-Port": [ "443" ], | ||
"X-Forwarded-Proto": [ "https" ] | ||
}, | ||
"requestContext": { | ||
"routeKey": "$connect", | ||
"eventType": "CONNECT", | ||
"extendedRequestId": "IU3kkGyEoAMFwZQ=", | ||
"requestTime": "19/Jul/2023:19:28:16 +0000", | ||
"messageDirection": "IN", | ||
"stage": "dev", | ||
"connectedAt": 1689794896145, | ||
"requestTimeEpoch": 1689794896162, | ||
"identity": { "sourceIp": "24.148.42.16" }, | ||
"requestId": "IU3kkGyEoAMFwZQ=", | ||
"domainName": "lqrlmblaa2.execute-api.us-east-1.amazonaws.com", | ||
"connectionId": "IU3kkeN4IAMCJwA=", | ||
"apiId": "lqrlmblaa2" | ||
}, | ||
"isBase64Encoded": false | ||
} | ||
""" | ||
|
||
// MARK: - Request - | ||
|
||
// MARK: Decoding | ||
@Test func testRequestDecodingExampleConnectRequest() async throws { | ||
let data = APIGatewayWebSocketsTests.exampleConnectEventBody.data(using: .utf8)! | ||
let req = try JSONDecoder().decode(APIGatewayWebSocketRequest.self, from: data) | ||
|
||
#expect(req.context.routeKey == "$connect") | ||
#expect(req.context.connectionId == "IU3kkeN4IAMCJwA=") | ||
#expect(req.body == nil) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.