Skip to content

Commit c1af9de

Browse files
committed
Add WebSockets event types (and tests)
1 parent 63176f5 commit c1af9de

File tree

2 files changed

+145
-0
lines changed

2 files changed

+145
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftAWSLambdaRuntime open source project
4+
//
5+
// Copyright (c) YEARS Apple Inc. and the SwiftAWSLambdaRuntime project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
/// `APIGatewayWebSocketRequest` is a variation of the`APIGatewayV2Request`
16+
/// and contains data coming from the WebSockets API Gateway.
17+
public struct APIGatewayWebSocketRequest: Codable {
18+
/// `Context` contains information to identify the AWS account and resources invoking the Lambda function.
19+
public struct Context: Codable {
20+
public struct Identity: Codable {
21+
let sourceIp: String
22+
}
23+
24+
let routeKey: String
25+
let eventType: String
26+
let extendedRequestId: String
27+
/// The request time in format: 23/Apr/2020:11:08:18 +0000
28+
let requestTime: String
29+
let messageDirection: String
30+
let stage: String
31+
let connectedAt: UInt64
32+
let requestTimeEpoch: UInt64
33+
let identity: Identity
34+
let requestId: String
35+
let domainName: String
36+
let connectionId: String
37+
let apiId: String
38+
}
39+
40+
public let headers: HTTPHeaders?
41+
public let multiValueHeaders: HTTPMultiValueHeaders?
42+
public let context: Context
43+
public let body: String?
44+
public let isBase64Encoded: Bool?
45+
46+
enum CodingKeys: String, CodingKey {
47+
case headers
48+
case multiValueHeaders
49+
case context = "requestContext"
50+
case body
51+
case isBase64Encoded
52+
}
53+
}
54+
55+
/// `APIGatewayWebSocketResponse` is a type alias for `APIGatewayV2Request`.
56+
/// Typically, lambda WebSockets servers send clients data via
57+
/// the ApiGatewayManagementApi mechanism. However, APIGateway does require
58+
/// lambda servers to return some kind of status when APIGateway invokes them.
59+
/// This can be as simple as always returning a 200 "OK" response for all
60+
/// WebSockets requests (the ApiGatewayManagementApi can return any errors to
61+
/// WebSockets clients).
62+
public typealias APIGatewayWebSocketResponse = APIGatewayV2Response
63+
64+
#if swift(>=5.6)
65+
extension APIGatewayWebSocketRequest: Sendable {}
66+
extension APIGatewayWebSocketRequest.Context: Sendable {}
67+
extension APIGatewayWebSocketRequest.Context.Identity: Sendable {}
68+
#endif
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftAWSLambdaRuntime open source project
4+
//
5+
// Copyright (c) YEARS Apple Inc. and the SwiftAWSLambdaRuntime project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
@testable import AWSLambdaEvents
16+
import XCTest
17+
18+
class APIGatewayWebSocketsTests: XCTestCase {
19+
static let exampleConnectEventBody = """
20+
{
21+
"headers": {
22+
"Host": "lqrlmblaa2.execute-api.us-east-1.amazonaws.com",
23+
"Origin": "wss://lqrlmblaa2.execute-api.us-east-1.amazonaws.com",
24+
"Sec-WebSocket-Extensions": "permessage-deflate; client_max_window_bits; server_max_window_bits=15",
25+
"Sec-WebSocket-Key": "am5ubWVpbHd3bmNyYXF0ag==",
26+
"Sec-WebSocket-Version": "13",
27+
"X-Amzn-Trace-Id": "Root=1-64b83950-42de8e247b4c2b43091ef67c",
28+
"X-Forwarded-For": "24.148.42.16",
29+
"X-Forwarded-Port": "443",
30+
"X-Forwarded-Proto": "https"
31+
},
32+
"multiValueHeaders": {
33+
"Host": [ "lqrlmblaa2.execute-api.us-east-1.amazonaws.com" ],
34+
"Origin": [ "wss://lqrlmblaa2.execute-api.us-east-1.amazonaws.com" ],
35+
"Sec-WebSocket-Extensions": [
36+
"permessage-deflate; client_max_window_bits; server_max_window_bits=15"
37+
],
38+
"Sec-WebSocket-Key": [ "am5ubWVpbHd3bmNyYXF0ag==" ],
39+
"Sec-WebSocket-Version": [ "13" ],
40+
"X-Amzn-Trace-Id": [ "Root=1-64b83950-42de8e247b4c2b43091ef67c" ],
41+
"X-Forwarded-For": [ "24.148.42.16" ],
42+
"X-Forwarded-Port": [ "443" ],
43+
"X-Forwarded-Proto": [ "https" ]
44+
},
45+
"requestContext": {
46+
"routeKey": "$connect",
47+
"eventType": "CONNECT",
48+
"extendedRequestId": "IU3kkGyEoAMFwZQ=",
49+
"requestTime": "19/Jul/2023:19:28:16 +0000",
50+
"messageDirection": "IN",
51+
"stage": "dev",
52+
"connectedAt": 1689794896145,
53+
"requestTimeEpoch": 1689794896162,
54+
"identity": { "sourceIp": "24.148.42.16" },
55+
"requestId": "IU3kkGyEoAMFwZQ=",
56+
"domainName": "lqrlmblaa2.execute-api.us-east-1.amazonaws.com",
57+
"connectionId": "IU3kkeN4IAMCJwA=",
58+
"apiId": "lqrlmblaa2"
59+
},
60+
"isBase64Encoded": false
61+
}
62+
"""
63+
64+
// MARK: - Request -
65+
66+
// MARK: Decoding
67+
68+
func testRequestDecodingExampleConnectRequest() {
69+
let data = APIGatewayWebSocketsTests.exampleConnectEventBody.data(using: .utf8)!
70+
var req: APIGatewayWebSocketRequest?
71+
XCTAssertNoThrow(req = try JSONDecoder().decode(APIGatewayWebSocketRequest.self, from: data))
72+
73+
XCTAssertEqual(req?.context.routeKey, "$connect")
74+
XCTAssertEqual(req?.context.connectionId, "IU3kkeN4IAMCJwA=")
75+
XCTAssertNil(req?.body)
76+
}
77+
}

0 commit comments

Comments
 (0)