@@ -24,7 +24,7 @@ final class ControlPlaneResponseDecoderTests: XCTestCase {
24
24
Content-Type: application/json \r \n \
25
25
Lambda-Runtime-Aws-Request-Id: 9028dc49-a01b-4b44-8ffe-4912e9dabbbd \r \n \
26
26
Lambda-Runtime-Deadline-Ms: 1638392696671 \r \n \
27
- Lambda-Runtime-Invoked-Function-Arn: arn:aws:lambda:eu-central-1:079477498937 :function:lambda-log-http-HelloWorldLambda-NiDlzMFXtF3x \r \n \
27
+ Lambda-Runtime-Invoked-Function-Arn: arn:aws:lambda:eu-central-1:000000000000 :function:lambda-log-http-HelloWorldLambda-NiDlzMFXtF3x \r \n \
28
28
Lambda-Runtime-Trace-Id: Root=1-61a7e375-40b3edf95b388fe75d1fa416;Parent=348bb48e251c1254;Sampled=0 \r \n \
29
29
Date: Wed, 01 Dec 2021 21:04:53 GMT \r \n \
30
30
Content-Length: 49 \r \n \
@@ -35,7 +35,7 @@ final class ControlPlaneResponseDecoderTests: XCTestCase {
35
35
let invocation = Invocation (
36
36
requestID: " 9028dc49-a01b-4b44-8ffe-4912e9dabbbd " ,
37
37
deadlineInMillisSinceEpoch: 1_638_392_696_671 ,
38
- invokedFunctionARN: " arn:aws:lambda:eu-central-1:079477498937 :function:lambda-log-http-HelloWorldLambda-NiDlzMFXtF3x " ,
38
+ invokedFunctionARN: " arn:aws:lambda:eu-central-1:000000000000 :function:lambda-log-http-HelloWorldLambda-NiDlzMFXtF3x " ,
39
39
traceID: " Root=1-61a7e375-40b3edf95b388fe75d1fa416;Parent=348bb48e251c1254;Sampled=0 " ,
40
40
clientContext: nil ,
41
41
cognitoIdentity: nil
@@ -63,14 +63,14 @@ final class ControlPlaneResponseDecoderTests: XCTestCase {
63
63
decoderFactory: { ControlPlaneResponseDecoder ( ) }
64
64
) )
65
65
}
66
-
66
+
67
67
func testWhitespaceInHeaderIsRejected( ) {
68
68
let nextResponse = ByteBuffer ( string: """
69
69
HTTP/1.1 200 OK \r \n \
70
70
Content-Type: application/json \r \n \
71
71
Lambda-Runtime Aws-Request-Id: 9028dc49-a01b-4b44-8ffe-4912e9dabbbd \r \n \
72
72
Lambda-Runtime-Deadline-Ms: 1638392696671 \r \n \
73
- Lambda-Runtime-Invoked-Function-Arn: arn:aws:lambda:eu-central-1:079477498937 :function:lambda-log-http-HelloWorldLambda-NiDlzMFXtF3x \r \n \
73
+ Lambda-Runtime-Invoked-Function-Arn: arn:aws:lambda:eu-central-1:000000000000 :function:lambda-log-http-HelloWorldLambda-NiDlzMFXtF3x \r \n \
74
74
Lambda-Runtime-Trace-Id: Root=1-61a7e375-40b3edf95b388fe75d1fa416;Parent=348bb48e251c1254;Sampled=0 \r \n \
75
75
Date: Wed, 01 Dec 2021 21:04:53 GMT \r \n \
76
76
Content-Length: 49 \r \n \
@@ -79,17 +79,258 @@ final class ControlPlaneResponseDecoderTests: XCTestCase {
79
79
"""
80
80
)
81
81
82
- let pairs : [ ( ByteBuffer , [ ControlPlaneResponse ] ) ] = [
83
- ( nextResponse, [ ] )
84
- ]
85
-
86
82
XCTAssertThrowsError ( try ByteToMessageDecoderVerifier . verifyDecoder (
87
- inputOutputPairs: pairs ,
83
+ inputOutputPairs: [ ( nextResponse , [ ] ) ] ,
88
84
decoderFactory: { ControlPlaneResponseDecoder ( ) }
89
85
) ) {
90
86
XCTAssertEqual ( $0 as? LambdaRuntimeError , . responseHeadHeaderInvalidCharacter)
91
87
}
92
88
}
89
+
90
+ func testVeryLongHTTPStatusLine( ) {
91
+ let nextResponse = ByteBuffer ( repeating: UInt8 ( ascii: " H " ) , count: 1024 )
92
+
93
+ XCTAssertThrowsError ( try ByteToMessageDecoderVerifier . verifyDecoder (
94
+ inputOutputPairs: [ ( nextResponse, [ ] ) ] ,
95
+ decoderFactory: { ControlPlaneResponseDecoder ( ) }
96
+ ) ) {
97
+ XCTAssertEqual ( $0 as? LambdaRuntimeError , . responseHeadMoreThan256BytesBeforeCRLF)
98
+ }
99
+ }
100
+
101
+ func testVeryLongHTTPHeader( ) {
102
+ let acceptedResponse = ByteBuffer ( string: """
103
+ HTTP/1.1 202 Accepted \r \n \
104
+ Content-Type: application/json \r \n \
105
+ Date: Sun, 05 Dec 2021 11:53:40 GMT \r \n \
106
+ Content-Length: 16 \r \n
107
+ """
108
+ ) + ByteBuffer( repeating: UInt8 ( ascii: " H " ) , count: 1024 )
109
+
110
+ XCTAssertThrowsError ( try ByteToMessageDecoderVerifier . verifyDecoder (
111
+ inputOutputPairs: [ ( acceptedResponse, [ ] ) ] ,
112
+ decoderFactory: { ControlPlaneResponseDecoder ( ) }
113
+ ) ) {
114
+ XCTAssertEqual ( $0 as? LambdaRuntimeError , . responseHeadMoreThan256BytesBeforeCRLF)
115
+ }
116
+ }
117
+
118
+ func testNextResponseWithoutTraceID( ) {
119
+ let nextResponse = ByteBuffer ( string: """
120
+ HTTP/1.1 200 OK \r \n \
121
+ Content-Type: application/json \r \n \
122
+ Lambda-Runtime-Aws-Request-Id: 9028dc49-a01b-4b44-8ffe-4912e9dabbbd \r \n \
123
+ Lambda-Runtime-Deadline-Ms: 1638392696671 \r \n \
124
+ Lambda-Runtime-Invoked-Function-Arn: arn:aws:lambda:eu-central-1:000000000000:function:lambda-log-http-HelloWorldLambda-NiDlzMFXtF3x \r \n \
125
+ Date: Wed, 01 Dec 2021 21:04:53 GMT \r \n \
126
+ Content-Length: 49 \r \n \
127
+ \r \n \
128
+ { " name " : " Fabian " , " key2 " : " value2 " , " key3 " : " value3 " }
129
+ """
130
+ )
131
+
132
+ XCTAssertThrowsError ( try ByteToMessageDecoderVerifier . verifyDecoder (
133
+ inputOutputPairs: [ ( nextResponse, [ ] ) ] ,
134
+ decoderFactory: { ControlPlaneResponseDecoder ( ) }
135
+ ) ) {
136
+ XCTAssertEqual ( $0 as? LambdaRuntimeError , . invocationHeadMissingTraceID)
137
+ }
138
+ }
139
+
140
+ func testNextResponseWithoutRequestID( ) {
141
+ let nextResponse = ByteBuffer ( string: """
142
+ HTTP/1.1 200 OK \r \n \
143
+ Content-Type: application/json \r \n \
144
+ Lambda-Runtime-Deadline-Ms: 1638392696671 \r \n \
145
+ Lambda-Runtime-Invoked-Function-Arn: arn:aws:lambda:eu-central-1:000000000000:function:lambda-log-http-HelloWorldLambda-NiDlzMFXtF3x \r \n \
146
+ Lambda-Runtime-Trace-Id: Root=1-61a7e375-40b3edf95b388fe75d1fa416;Parent=348bb48e251c1254;Sampled=0 \r \n \
147
+ Date: Wed, 01 Dec 2021 21:04:53 GMT \r \n \
148
+ Content-Length: 49 \r \n \
149
+ \r \n \
150
+ { " name " : " Fabian " , " key2 " : " value2 " , " key3 " : " value3 " }
151
+ """
152
+ )
153
+
154
+ XCTAssertThrowsError ( try ByteToMessageDecoderVerifier . verifyDecoder (
155
+ inputOutputPairs: [ ( nextResponse, [ ] ) ] ,
156
+ decoderFactory: { ControlPlaneResponseDecoder ( ) }
157
+ ) ) {
158
+ XCTAssertEqual ( $0 as? LambdaRuntimeError , . invocationHeadMissingRequestID)
159
+ }
160
+ }
161
+
162
+ func testNextResponseWithInvalidStatusCode( ) {
163
+ let nextResponse = ByteBuffer ( string: """
164
+ HTTP/1.1 20 OK \r \n \
165
+ Content-Type: application/json \r \n \
166
+ Lambda-Runtime-Deadline-Ms: 1638392696671 \r \n \
167
+ Lambda-Runtime-Invoked-Function-Arn: arn:aws:lambda:eu-central-1:000000000000:function:lambda-log-http-HelloWorldLambda-NiDlzMFXtF3x \r \n \
168
+ Lambda-Runtime-Trace-Id: Root=1-61a7e375-40b3edf95b388fe75d1fa416;Parent=348bb48e251c1254;Sampled=0 \r \n \
169
+ Date: Wed, 01 Dec 2021 21:04:53 GMT \r \n \
170
+ Content-Length: 49 \r \n \
171
+ \r \n \
172
+ { " name " : " Fabian " , " key2 " : " value2 " , " key3 " : " value3 " }
173
+ """
174
+ )
175
+
176
+ XCTAssertThrowsError ( try ByteToMessageDecoderVerifier . verifyDecoder (
177
+ inputOutputPairs: [ ( nextResponse, [ ] ) ] ,
178
+ decoderFactory: { ControlPlaneResponseDecoder ( ) }
179
+ ) ) {
180
+ XCTAssertEqual ( $0 as? LambdaRuntimeError , . responseHeadInvalidStatusLine)
181
+ }
182
+ }
183
+
184
+ func testNextResponseWithVersionHTTP2( ) {
185
+ let nextResponse = ByteBuffer ( string: """
186
+ HTTP/2.0 200 OK \r \n \
187
+ Content-Type: application/json \r \n \
188
+ Lambda-Runtime-Deadline-Ms: 1638392696671 \r \n \
189
+ Lambda-Runtime-Invoked-Function-Arn: arn:aws:lambda:eu-central-1:000000000000:function:lambda-log-http-HelloWorldLambda-NiDlzMFXtF3x \r \n \
190
+ Lambda-Runtime-Trace-Id: Root=1-61a7e375-40b3edf95b388fe75d1fa416;Parent=348bb48e251c1254;Sampled=0 \r \n \
191
+ Date: Wed, 01 Dec 2021 21:04:53 GMT \r \n \
192
+ Content-Length: 49 \r \n \
193
+ \r \n \
194
+ { " name " : " Fabian " , " key2 " : " value2 " , " key3 " : " value3 " }
195
+ """
196
+ )
197
+
198
+ XCTAssertThrowsError ( try ByteToMessageDecoderVerifier . verifyDecoder (
199
+ inputOutputPairs: [ ( nextResponse, [ ] ) ] ,
200
+ decoderFactory: { ControlPlaneResponseDecoder ( ) }
201
+ ) ) {
202
+ XCTAssertEqual ( $0 as? LambdaRuntimeError , . responseHeadInvalidStatusLine)
203
+ }
204
+ }
205
+
206
+ func testNextResponseLeadingAndTrailingWhitespaceHeaders( ) {
207
+ let nextResponse = ByteBuffer ( string: """
208
+ HTTP/1.1 200 OK \r \n \
209
+ Content-Type: \t \t application/json \t \t \r \n \
210
+ Lambda-Runtime-Aws-Request-Id: \t \t 9028dc49-a01b-4b44-8ffe-4912e9dabbbd \t \t \r \n \
211
+ Lambda-Runtime-Deadline-Ms: \t \t 1638392696671 \t \t \r \n \
212
+ Lambda-Runtime-Invoked-Function-Arn: \t \t arn:aws:lambda:eu-central-1:000000000000:function:lambda-log-http-HelloWorldLambda-NiDlzMFXtF3x \t \t \r \n \
213
+ Lambda-Runtime-Trace-Id: \t \t Root=1-61a7e375-40b3edf95b388fe75d1fa416;Parent=348bb48e251c1254;Sampled=0 \t \t \r \n \
214
+ Date: \t \t Wed, 01 Dec 2021 21:04:53 GMT \t \t \r \n \
215
+ Content-Length: \t \t 49 \t \t \r \n \
216
+ \r \n \
217
+ { " name " : " Fabian " , " key2 " : " value2 " , " key3 " : " value3 " }
218
+ """
219
+ )
220
+ let invocation = Invocation (
221
+ requestID: " 9028dc49-a01b-4b44-8ffe-4912e9dabbbd " ,
222
+ deadlineInMillisSinceEpoch: 1_638_392_696_671 ,
223
+ invokedFunctionARN: " arn:aws:lambda:eu-central-1:000000000000:function:lambda-log-http-HelloWorldLambda-NiDlzMFXtF3x " ,
224
+ traceID: " Root=1-61a7e375-40b3edf95b388fe75d1fa416;Parent=348bb48e251c1254;Sampled=0 " ,
225
+ clientContext: nil ,
226
+ cognitoIdentity: nil
227
+ )
228
+ let next : ControlPlaneResponse = . next( invocation, ByteBuffer ( string: #"{"name":"Fabian","key2":"value2","key3":"value3"}"# ) )
229
+
230
+ XCTAssertNoThrow ( try ByteToMessageDecoderVerifier . verifyDecoder (
231
+ inputOutputPairs: [ ( nextResponse, [ next] ) ] ,
232
+ decoderFactory: { ControlPlaneResponseDecoder ( ) }
233
+ ) )
234
+ }
235
+
236
+ func testContentLengthHasTrailingCharacterSurroundedByWhitespace( ) {
237
+ let nextResponse = ByteBuffer ( string: """
238
+ HTTP/1.1 200 OK \r \n \
239
+ Content-Type: \t \t application/json \t \t \r \n \
240
+ Content-Length: 49 r \r \n \
241
+ Date: \t \t Wed, 01 Dec 2021 21:04:53 GMT \t \t \r \n \
242
+
243
+ \r \n \
244
+ { " name " : " Fabian " , " key2 " : " value2 " , " key3 " : " value3 " }
245
+ """
246
+ )
247
+
248
+ XCTAssertThrowsError ( try ByteToMessageDecoderVerifier . verifyDecoder (
249
+ inputOutputPairs: [ ( nextResponse, [ ] ) ] ,
250
+ decoderFactory: { ControlPlaneResponseDecoder ( ) }
251
+ ) ) {
252
+ XCTAssertEqual ( $0 as? LambdaRuntimeError , . responseHeadInvalidContentLengthValue)
253
+ }
254
+ }
255
+
256
+ func testInvalidContentLength( ) {
257
+ let nextResponse = ByteBuffer ( string: """
258
+ HTTP/1.1 200 OK \r \n \
259
+ Content-Type: \t \t application/json \t \t \r \n \
260
+ Content-Length: 4u9 \r \n \
261
+ Date: \t \t Wed, 01 Dec 2021 21:04:53 GMT \t \t \r \n \
262
+
263
+ \r \n \
264
+ { " name " : " Fabian " , " key2 " : " value2 " , " key3 " : " value3 " }
265
+ """
266
+ )
267
+
268
+ XCTAssertThrowsError ( try ByteToMessageDecoderVerifier . verifyDecoder (
269
+ inputOutputPairs: [ ( nextResponse, [ ] ) ] ,
270
+ decoderFactory: { ControlPlaneResponseDecoder ( ) }
271
+ ) ) {
272
+ XCTAssertEqual ( $0 as? LambdaRuntimeError , . responseHeadInvalidContentLengthValue)
273
+ }
274
+ }
275
+
276
+ func testResponseHeaderWithoutColon( ) {
277
+ let nextResponse = ByteBuffer ( string: """
278
+ HTTP/1.1 200 OK \r \n \
279
+ Content-Type application/json \r \n \
280
+ Content-Length: 49 \r \n \
281
+ Date: Wed, 01 Dec 2021 21:04:53 GMT \r \n \
282
+
283
+ \r \n \
284
+ { " name " : " Fabian " , " key2 " : " value2 " , " key3 " : " value3 " }
285
+ """
286
+ )
287
+
288
+ XCTAssertThrowsError ( try ByteToMessageDecoderVerifier . verifyDecoder (
289
+ inputOutputPairs: [ ( nextResponse, [ ] ) ] ,
290
+ decoderFactory: { ControlPlaneResponseDecoder ( ) }
291
+ ) ) {
292
+ XCTAssertEqual ( $0 as? LambdaRuntimeError , . responseHeadHeaderMissingColon)
293
+ }
294
+ }
295
+
296
+ func testResponseHeaderWithDoubleCR( ) {
297
+ let nextResponse = ByteBuffer ( string: """
298
+ HTTP/1.1 200 OK \r \n \
299
+ Content-Type: application/json \r \r \n \
300
+ Content-Length: 49 \r \n \
301
+ Date: Wed, 01 Dec 2021 21:04:53 GMT \r \n \
302
+
303
+ \r \n \
304
+ { " name " : " Fabian " , " key2 " : " value2 " , " key3 " : " value3 " }
305
+ """
306
+ )
307
+
308
+ XCTAssertThrowsError ( try ByteToMessageDecoderVerifier . verifyDecoder (
309
+ inputOutputPairs: [ ( nextResponse, [ ] ) ] ,
310
+ decoderFactory: { ControlPlaneResponseDecoder ( ) }
311
+ ) ) {
312
+ XCTAssertEqual ( $0 as? LambdaRuntimeError , . responseHeadInvalidHeader)
313
+ }
314
+ }
315
+
316
+ func testResponseHeaderWithoutValue( ) {
317
+ let nextResponse = ByteBuffer ( string: """
318
+ HTTP/1.1 200 OK \r \n \
319
+ Content-Type: \r \n \
320
+ Content-Length: 49 \r \n \
321
+ Date: Wed, 01 Dec 2021 21:04:53 GMT \r \n \
322
+ \r \n \
323
+ { " name " : " Fabian " , " key2 " : " value2 " , " key3 " : " value3 " }
324
+ """
325
+ )
326
+
327
+ XCTAssertThrowsError ( try ByteToMessageDecoderVerifier . verifyDecoder (
328
+ inputOutputPairs: [ ( nextResponse, [ ] ) ] ,
329
+ decoderFactory: { ControlPlaneResponseDecoder ( ) }
330
+ ) ) {
331
+ XCTAssertEqual ( $0 as? LambdaRuntimeError , . responseHeadInvalidHeader)
332
+ }
333
+ }
93
334
}
94
335
95
336
extension ByteBuffer {
0 commit comments