@@ -17,7 +17,7 @@ import class Foundation.JSONEncoder
17
17
// https://github.com/aws/aws-lambda-go/blob/master/events/alb.go
18
18
public enum ALB {
19
19
/// ALBTargetGroupRequest contains data originating from the ALB Lambda target group integration
20
- public struct TargetGroupRequest {
20
+ public struct TargetGroupRequest : Codable {
21
21
/// ALBTargetGroupRequestContext contains the information to identify the load balancer invoking the lambda
22
22
public struct Context : Codable {
23
23
public let elb : ELBContext
@@ -26,7 +26,20 @@ public enum ALB {
26
26
public let httpMethod : HTTPMethod
27
27
public let path : String
28
28
public let queryStringParameters : [ String : [ String ] ]
29
- public let headers : HTTPHeaders
29
+
30
+ /// Depending on your configuration of your target group either `headers` or `multiValueHeaders`
31
+ /// are set.
32
+ ///
33
+ /// For more information visit:
34
+ /// https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html#multi-value-headers
35
+ public let headers : [ String : String ] ?
36
+
37
+ /// Depending on your configuration of your target group either `headers` or `multiValueHeaders`
38
+ /// are set.
39
+ ///
40
+ /// For more information visit:
41
+ /// https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html#multi-value-headers
42
+ public let multiValueHeaders : [ String : [ String ] ] ?
30
43
public let requestContext : Context
31
44
public let isBase64Encoded : Bool
32
45
public let body : String ?
@@ -37,174 +50,28 @@ public enum ALB {
37
50
public let targetGroupArn : String
38
51
}
39
52
40
- public struct TargetGroupResponse {
53
+ public struct TargetGroupResponse : Codable {
41
54
public let statusCode : HTTPResponseStatus
42
55
public let statusDescription : String ?
43
- public let headers : HTTPHeaders ?
56
+ public let headers : [ String : String ] ?
57
+ public let multiValueHeaders : [ String : [ String ] ] ?
44
58
public let body : String
45
59
public let isBase64Encoded : Bool
46
60
47
61
public init (
48
62
statusCode: HTTPResponseStatus ,
49
63
statusDescription: String ? = nil ,
50
- headers: HTTPHeaders ? = nil ,
64
+ headers: [ String : String ] ? = nil ,
65
+ multiValueHeaders: [ String : [ String ] ] ? = nil ,
51
66
body: String = " " ,
52
67
isBase64Encoded: Bool = false
53
68
) {
54
69
self . statusCode = statusCode
55
70
self . statusDescription = statusDescription
56
71
self . headers = headers
72
+ self . multiValueHeaders = multiValueHeaders
57
73
self . body = body
58
74
self . isBase64Encoded = isBase64Encoded
59
75
}
60
76
}
61
77
}
62
-
63
- // MARK: - Request -
64
-
65
- extension ALB . TargetGroupRequest : Decodable {
66
- enum CodingKeys : String , CodingKey {
67
- case httpMethod
68
- case path
69
- case queryStringParameters
70
- case multiValueQueryStringParameters
71
- case headers
72
- case multiValueHeaders
73
- case requestContext
74
- case isBase64Encoded
75
- case body
76
- }
77
-
78
- public init ( from decoder: Decoder ) throws {
79
- let container = try decoder. container ( keyedBy: CodingKeys . self)
80
-
81
- let rawMethod = try container. decode ( String . self, forKey: . httpMethod)
82
- guard let method = HTTPMethod ( rawValue: rawMethod) else {
83
- throw DecodingError . dataCorruptedError (
84
- forKey: . httpMethod,
85
- in: container,
86
- debugDescription: #"Method " \#( rawMethod) " does not conform to allowed http method syntax defined in RFC 7230 Section 3.2.6"#
87
- )
88
- }
89
- self . httpMethod = method
90
-
91
- self . path = try container. decode ( String . self, forKey: . path)
92
-
93
- // crazy multiple headers
94
- // https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html#multi-value-headers
95
-
96
- if let multiValueQueryStringParameters =
97
- try container. decodeIfPresent ( [ String : [ String ] ] . self, forKey: . multiValueQueryStringParameters) {
98
- self . queryStringParameters = multiValueQueryStringParameters
99
- } else {
100
- let singleValueQueryStringParameters = try container. decode (
101
- [ String : String ] . self,
102
- forKey: . queryStringParameters
103
- )
104
- self . queryStringParameters = singleValueQueryStringParameters. mapValues { [ $0] }
105
- }
106
-
107
- if let multiValueHeaders =
108
- try container. decodeIfPresent ( [ String : [ String ] ] . self, forKey: . multiValueHeaders) {
109
- self . headers = HTTPHeaders ( multiValueHeaders)
110
- } else {
111
- let singleValueHeaders = try container. decode (
112
- [ String : String ] . self,
113
- forKey: . headers
114
- )
115
- let multiValueHeaders = singleValueHeaders. mapValues { [ $0] }
116
- self . headers = HTTPHeaders ( multiValueHeaders)
117
- }
118
-
119
- self . requestContext = try container. decode ( Context . self, forKey: . requestContext)
120
- self . isBase64Encoded = try container. decode ( Bool . self, forKey: . isBase64Encoded)
121
-
122
- let body = try container. decode ( String . self, forKey: . body)
123
- self . body = body != " " ? body : nil
124
- }
125
- }
126
-
127
- // MARK: - Response -
128
-
129
- extension ALB . TargetGroupResponse : Encodable {
130
- static let MultiValueHeadersEnabledKey =
131
- CodingUserInfoKey ( rawValue: " ALB.TargetGroupResponse.MultiValueHeadersEnabledKey " ) !
132
-
133
- enum CodingKeys : String , CodingKey {
134
- case statusCode
135
- case statusDescription
136
- case headers
137
- case multiValueHeaders
138
- case body
139
- case isBase64Encoded
140
- }
141
-
142
- public func encode( to encoder: Encoder ) throws {
143
- var container = encoder. container ( keyedBy: CodingKeys . self)
144
- try container. encode ( statusCode. code, forKey: . statusCode)
145
-
146
- let multiValueHeaderSupport =
147
- encoder. userInfo [ ALB . TargetGroupResponse. MultiValueHeadersEnabledKey] as? Bool ?? false
148
-
149
- switch ( multiValueHeaderSupport, headers) {
150
- case ( true , . none) :
151
- try container. encode ( [ String: String] ( ) , forKey: . multiValueHeaders)
152
- case ( false , . none) :
153
- try container. encode ( [ String: [ String] ] ( ) , forKey: . headers)
154
- case ( true , . some( let headers) ) :
155
- try container. encode ( headers. headers, forKey: . multiValueHeaders)
156
- case ( false , . some( let headers) ) :
157
- let singleValueHeaders = headers. headers. mapValues { ( values) -> String in
158
- #warning("Is this correct?")
159
- return values. joined ( separator: " , " )
160
- }
161
- try container. encode ( singleValueHeaders, forKey: . headers)
162
- }
163
-
164
- try container. encodeIfPresent ( statusDescription, forKey: . statusDescription)
165
- try container. encodeIfPresent ( body, forKey: . body)
166
- try container. encodeIfPresent ( isBase64Encoded, forKey: . isBase64Encoded)
167
- }
168
- }
169
-
170
- extension ALB . TargetGroupResponse {
171
- public init < Payload: Encodable > (
172
- statusCode: HTTPResponseStatus ,
173
- statusDescription: String ? = nil ,
174
- headers: HTTPHeaders ? = nil ,
175
- payload: Payload ,
176
- encoder: JSONEncoder = JSONEncoder ( )
177
- ) throws {
178
- var headers = headers ?? HTTPHeaders ( )
179
- if !headers. contains ( name: " Content-Type " ) {
180
- headers. add ( name: " Content-Type " , value: " application/json " )
181
- }
182
-
183
- self . statusCode = statusCode
184
- self . statusDescription = statusDescription
185
- self . headers = headers
186
-
187
- let data = try encoder. encode ( payload)
188
- self . body = String ( decoding: data, as: Unicode . UTF8. self)
189
- self . isBase64Encoded = false
190
- }
191
-
192
- public init (
193
- statusCode: HTTPResponseStatus ,
194
- statusDescription: String ? = nil ,
195
- headers: HTTPHeaders ? = nil ,
196
- bytes: [ UInt8 ] ?
197
- ) {
198
- let headers = headers ?? HTTPHeaders ( )
199
-
200
- self . statusCode = statusCode
201
- self . statusDescription = statusDescription
202
- self . headers = headers
203
- if let bytes = bytes {
204
- self . body = String ( base64Encoding: bytes)
205
- } else {
206
- self . body = " "
207
- }
208
- self . isBase64Encoded = true
209
- }
210
- }
0 commit comments