1 /**
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0.
4 */
5
6 #include <aws/http/private/h1_encoder.h>
7
8 #include <aws/common/array_list.h>
9 #include <aws/io/logging.h>
10 #include <aws/testing/aws_test_harness.h>
11
12 #include <aws/io/stream.h>
13 #include <ctype.h>
14 #include <stdio.h>
15
16 #define H1_ENCODER_TEST_CASE(NAME) \
17 AWS_TEST_CASE(NAME, s_test_##NAME); \
18 static int s_test_##NAME(struct aws_allocator *allocator, void *ctx)
19
20 static const struct aws_http_header s_typical_request_headers[] = {
21 {
22 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Host"),
23 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("amazon.com"),
24 },
25 };
26
27 static struct aws_logger s_logger;
28
s_test_init(struct aws_allocator * allocator)29 static void s_test_init(struct aws_allocator *allocator) {
30 aws_http_library_init(allocator);
31
32 struct aws_logger_standard_options logger_options = {
33 .level = AWS_LOG_LEVEL_TRACE,
34 .file = stderr,
35 };
36
37 aws_logger_init_standard(&s_logger, allocator, &logger_options);
38 aws_logger_set(&s_logger);
39 }
40
s_test_clean_up(void)41 static void s_test_clean_up(void) {
42 aws_http_library_clean_up();
43 aws_logger_clean_up(&s_logger);
44 }
45
H1_ENCODER_TEST_CASE(h1_encoder_content_length_put_request_headers)46 H1_ENCODER_TEST_CASE(h1_encoder_content_length_put_request_headers) {
47 (void)ctx;
48 s_test_init(allocator);
49 struct aws_h1_encoder encoder;
50 aws_h1_encoder_init(&encoder, allocator);
51
52 /* request to send - we won't actually send it, we want to validate headers are set correctly. */
53 static const struct aws_byte_cursor body = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("write more tests");
54 struct aws_input_stream *body_stream = aws_input_stream_new_from_cursor(allocator, &body);
55
56 struct aws_http_header headers[] = {
57 {
58 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Content-Length"),
59 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("16"),
60 },
61 };
62
63 struct aws_http_message *request = aws_http_message_new_request(allocator);
64 ASSERT_SUCCESS(aws_http_message_set_request_method(request, aws_byte_cursor_from_c_str("PUT")));
65 ASSERT_SUCCESS(aws_http_message_set_request_path(request, aws_byte_cursor_from_c_str("/")));
66 aws_http_message_add_header_array(request, headers, AWS_ARRAY_SIZE(headers));
67 aws_http_message_set_body_stream(request, body_stream);
68
69 struct aws_linked_list chunk_list;
70 aws_linked_list_init(&chunk_list);
71
72 struct aws_h1_encoder_message encoder_message;
73 aws_h1_encoder_message_init_from_request(&encoder_message, allocator, request, &chunk_list);
74
75 ASSERT_FALSE(encoder_message.has_chunked_encoding_header);
76 ASSERT_FALSE(encoder_message.has_connection_close_header);
77 ASSERT_UINT_EQUALS(body.len, encoder_message.content_length);
78
79 aws_input_stream_destroy(body_stream);
80 aws_http_message_destroy(request);
81 aws_h1_encoder_message_clean_up(&encoder_message);
82 aws_h1_encoder_clean_up(&encoder);
83 s_test_clean_up();
84 return AWS_OP_SUCCESS;
85 }
86
H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_chunked_put_request_headers)87 H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_chunked_put_request_headers) {
88 (void)ctx;
89 s_test_init(allocator);
90 struct aws_h1_encoder encoder;
91 aws_h1_encoder_init(&encoder, allocator);
92
93 /* request to send - we won't actually send it, we want to validate headers are set correctly. */
94
95 struct aws_http_header headers[] = {
96 {
97 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Transfer-Encoding"),
98 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("chunked"),
99 },
100 };
101
102 struct aws_http_message *request = aws_http_message_new_request(allocator);
103 ASSERT_SUCCESS(aws_http_message_set_request_method(request, aws_byte_cursor_from_c_str("PUT")));
104 ASSERT_SUCCESS(aws_http_message_set_request_path(request, aws_byte_cursor_from_c_str("/")));
105 aws_http_message_add_header_array(request, headers, AWS_ARRAY_SIZE(headers));
106
107 struct aws_linked_list chunk_list;
108 aws_linked_list_init(&chunk_list);
109
110 struct aws_h1_encoder_message encoder_message;
111 aws_h1_encoder_message_init_from_request(&encoder_message, allocator, request, &chunk_list);
112
113 ASSERT_TRUE(encoder_message.has_chunked_encoding_header);
114 ASSERT_FALSE(encoder_message.has_connection_close_header);
115 ASSERT_UINT_EQUALS(0, encoder_message.content_length);
116
117 aws_http_message_destroy(request);
118 aws_h1_encoder_message_clean_up(&encoder_message);
119 aws_h1_encoder_clean_up(&encoder);
120 s_test_clean_up();
121 return AWS_OP_SUCCESS;
122 }
123
H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_chunked_put_request_multiple_te_headers)124 H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_chunked_put_request_multiple_te_headers) {
125 (void)ctx;
126 s_test_init(allocator);
127 struct aws_h1_encoder encoder;
128 aws_h1_encoder_init(&encoder, allocator);
129
130 /* request to send - we won't actually send it, we want to validate headers are set correctly. */
131
132 struct aws_http_header headers[] = {
133 {
134 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Transfer-Encoding"),
135 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("gzip"),
136 },
137 {
138 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Transfer-Encoding"),
139 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("chunked"),
140 },
141 };
142
143 struct aws_http_message *request = aws_http_message_new_request(allocator);
144 ASSERT_SUCCESS(aws_http_message_set_request_method(request, aws_byte_cursor_from_c_str("PUT")));
145 ASSERT_SUCCESS(aws_http_message_set_request_path(request, aws_byte_cursor_from_c_str("/")));
146 aws_http_message_add_header_array(request, headers, AWS_ARRAY_SIZE(headers));
147
148 struct aws_linked_list chunk_list;
149 aws_linked_list_init(&chunk_list);
150
151 struct aws_h1_encoder_message encoder_message;
152 aws_h1_encoder_message_init_from_request(&encoder_message, allocator, request, &chunk_list);
153
154 ASSERT_TRUE(encoder_message.has_chunked_encoding_header);
155 ASSERT_FALSE(encoder_message.has_connection_close_header);
156 ASSERT_UINT_EQUALS(0, encoder_message.content_length);
157
158 aws_http_message_destroy(request);
159 aws_h1_encoder_message_clean_up(&encoder_message);
160 aws_h1_encoder_clean_up(&encoder);
161 s_test_clean_up();
162 return AWS_OP_SUCCESS;
163 }
164
H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_chunked_put_request_headers_case_insensitivity)165 H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_chunked_put_request_headers_case_insensitivity) {
166 (void)ctx;
167 s_test_init(allocator);
168 struct aws_h1_encoder encoder;
169 aws_h1_encoder_init(&encoder, allocator);
170
171 /* request to send - we won't actually send it, we want to validate headers are set correctly. */
172
173 struct aws_http_header headers[] = {
174 {
175 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("traNsfeR-EncODIng"),
176 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("chunked"),
177 },
178 };
179
180 struct aws_http_message *request = aws_http_message_new_request(allocator);
181 ASSERT_SUCCESS(aws_http_message_set_request_method(request, aws_byte_cursor_from_c_str("PUT")));
182 ASSERT_SUCCESS(aws_http_message_set_request_path(request, aws_byte_cursor_from_c_str("/")));
183 aws_http_message_add_header_array(request, headers, AWS_ARRAY_SIZE(headers));
184
185 struct aws_linked_list chunk_list;
186 aws_linked_list_init(&chunk_list);
187
188 struct aws_h1_encoder_message encoder_message;
189 aws_h1_encoder_message_init_from_request(&encoder_message, allocator, request, &chunk_list);
190
191 ASSERT_TRUE(encoder_message.has_chunked_encoding_header);
192 ASSERT_FALSE(encoder_message.has_connection_close_header);
193 ASSERT_UINT_EQUALS(0, encoder_message.content_length);
194
195 aws_http_message_destroy(request);
196 aws_h1_encoder_message_clean_up(&encoder_message);
197 aws_h1_encoder_clean_up(&encoder);
198 s_test_clean_up();
199 return AWS_OP_SUCCESS;
200 }
201
H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_not_chunked_put_request_headers)202 H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_not_chunked_put_request_headers) {
203 (void)ctx;
204 s_test_init(allocator);
205 struct aws_h1_encoder encoder;
206 aws_h1_encoder_init(&encoder, allocator);
207
208 /* request to send - we won't actually send it, we want to validate headers are set correctly. */
209 static const struct aws_byte_cursor body = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("write more tests");
210 struct aws_input_stream *body_stream = aws_input_stream_new_from_cursor(allocator, &body);
211
212 struct aws_http_header headers[] = {
213 {
214 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Transfer-Encoding"),
215 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("gzip"),
216 },
217 };
218
219 struct aws_http_message *request = aws_http_message_new_request(allocator);
220 ASSERT_SUCCESS(aws_http_message_set_request_method(request, aws_byte_cursor_from_c_str("PUT")));
221 ASSERT_SUCCESS(aws_http_message_set_request_path(request, aws_byte_cursor_from_c_str("/")));
222 aws_http_message_add_header_array(request, headers, AWS_ARRAY_SIZE(headers));
223 aws_http_message_set_body_stream(request, body_stream);
224
225 struct aws_linked_list chunk_list;
226 aws_linked_list_init(&chunk_list);
227
228 struct aws_h1_encoder_message encoder_message;
229 aws_h1_encoder_message_init_from_request(&encoder_message, allocator, request, &chunk_list);
230
231 ASSERT_FALSE(encoder_message.has_chunked_encoding_header);
232 ASSERT_FALSE(encoder_message.has_connection_close_header);
233 ASSERT_UINT_EQUALS(0, encoder_message.content_length);
234
235 aws_input_stream_destroy(body_stream);
236 aws_http_message_destroy(request);
237 aws_h1_encoder_message_clean_up(&encoder_message);
238 aws_h1_encoder_clean_up(&encoder);
239 s_test_clean_up();
240 return AWS_OP_SUCCESS;
241 }
242
H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_set_body_stream_errors)243 H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_set_body_stream_errors) {
244 (void)ctx;
245 s_test_init(allocator);
246 struct aws_h1_encoder encoder;
247 aws_h1_encoder_init(&encoder, allocator);
248
249 /* request to send - we won't actually send it, we want to validate headers are set correctly. */
250 static const struct aws_byte_cursor body = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("write more tests");
251 struct aws_input_stream *body_stream = aws_input_stream_new_from_cursor(allocator, &body);
252
253 struct aws_http_header headers[] = {
254 {
255 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Transfer-Encoding"),
256 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("chunked"),
257 },
258 };
259
260 struct aws_http_message *request = aws_http_message_new_request(allocator);
261 ASSERT_SUCCESS(aws_http_message_set_request_method(request, aws_byte_cursor_from_c_str("PUT")));
262 ASSERT_SUCCESS(aws_http_message_set_request_path(request, aws_byte_cursor_from_c_str("/")));
263 aws_http_message_add_header_array(request, headers, AWS_ARRAY_SIZE(headers));
264 /* Setting the body stream should cause an error */
265 aws_http_message_set_body_stream(request, body_stream);
266
267 struct aws_linked_list chunk_list;
268 aws_linked_list_init(&chunk_list);
269
270 struct aws_h1_encoder_message encoder_message;
271 aws_h1_encoder_message_init_from_request(&encoder_message, allocator, request, &chunk_list);
272
273 ASSERT_FALSE(encoder_message.has_chunked_encoding_header);
274 ASSERT_FALSE(encoder_message.has_connection_close_header);
275 ASSERT_UINT_EQUALS(0, encoder_message.content_length);
276
277 aws_input_stream_destroy(body_stream);
278 aws_http_message_destroy(request);
279 aws_h1_encoder_message_clean_up(&encoder_message);
280 aws_h1_encoder_clean_up(&encoder);
281 s_test_clean_up();
282 return AWS_OP_SUCCESS;
283 }
284
H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_not_ending_in_chunked_put_request_headers)285 H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_not_ending_in_chunked_put_request_headers) {
286 (void)ctx;
287 s_test_init(allocator);
288 struct aws_h1_encoder encoder;
289 aws_h1_encoder_init(&encoder, allocator);
290
291 /* request to send - we won't actually send it, we want to validate headers are set correctly. */
292
293 struct aws_http_header headers[] = {
294 {
295 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Transfer-Encoding"),
296 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("chunked"),
297 },
298 {
299 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Transfer-Encoding"),
300 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("gzip"),
301 },
302 };
303
304 struct aws_http_message *request = aws_http_message_new_request(allocator);
305 ASSERT_SUCCESS(aws_http_message_set_request_method(request, aws_byte_cursor_from_c_str("PUT")));
306 ASSERT_SUCCESS(aws_http_message_set_request_path(request, aws_byte_cursor_from_c_str("/")));
307 aws_http_message_add_header_array(request, headers, AWS_ARRAY_SIZE(headers));
308
309 struct aws_linked_list chunk_list;
310 aws_linked_list_init(&chunk_list);
311
312 struct aws_h1_encoder_message encoder_message;
313 aws_h1_encoder_message_init_from_request(&encoder_message, allocator, request, &chunk_list);
314
315 ASSERT_FALSE(encoder_message.has_chunked_encoding_header);
316 ASSERT_FALSE(encoder_message.has_connection_close_header);
317 ASSERT_UINT_EQUALS(0, encoder_message.content_length);
318
319 aws_http_message_destroy(request);
320 aws_h1_encoder_message_clean_up(&encoder_message);
321 aws_h1_encoder_clean_up(&encoder);
322 s_test_clean_up();
323 return AWS_OP_SUCCESS;
324 }
325
H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_chunked_multiple_put_request_headers)326 H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_chunked_multiple_put_request_headers) {
327 (void)ctx;
328 s_test_init(allocator);
329 struct aws_h1_encoder encoder;
330 aws_h1_encoder_init(&encoder, allocator);
331
332 /* request to send - we won't actually send it, we want to validate headers are set correctly. */
333
334 struct aws_http_header headers[] = {
335 {
336 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Transfer-Encoding"),
337 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("gzip, chunked"),
338 },
339 };
340
341 struct aws_http_message *request = aws_http_message_new_request(allocator);
342 ASSERT_SUCCESS(aws_http_message_set_request_method(request, aws_byte_cursor_from_c_str("PUT")));
343 ASSERT_SUCCESS(aws_http_message_set_request_path(request, aws_byte_cursor_from_c_str("/")));
344 aws_http_message_add_header_array(request, headers, AWS_ARRAY_SIZE(headers));
345
346 struct aws_linked_list chunk_list;
347 aws_linked_list_init(&chunk_list);
348
349 struct aws_h1_encoder_message encoder_message;
350 aws_h1_encoder_message_init_from_request(&encoder_message, allocator, request, &chunk_list);
351
352 ASSERT_TRUE(encoder_message.has_chunked_encoding_header);
353 ASSERT_FALSE(encoder_message.has_connection_close_header);
354 ASSERT_UINT_EQUALS(0, encoder_message.content_length);
355
356 aws_http_message_destroy(request);
357 aws_h1_encoder_message_clean_up(&encoder_message);
358 aws_h1_encoder_clean_up(&encoder);
359 s_test_clean_up();
360 return AWS_OP_SUCCESS;
361 }
362
H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_chunked_and_content_length_put_request_headers)363 H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_chunked_and_content_length_put_request_headers) {
364 (void)ctx;
365 s_test_init(allocator);
366 struct aws_h1_encoder encoder;
367 aws_h1_encoder_init(&encoder, allocator);
368
369 /* request to send - we won't actually send it, we want to validate headers are set correctly. */
370 static const struct aws_byte_cursor body = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("write more tests");
371 struct aws_input_stream *body_stream = aws_input_stream_new_from_cursor(allocator, &body);
372
373 struct aws_http_header headers[] = {
374 {
375 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Transfer-Encoding"),
376 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("chunked"),
377 },
378 {
379 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Content-Length"),
380 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("16"),
381 },
382 };
383
384 struct aws_http_message *request = aws_http_message_new_request(allocator);
385 ASSERT_SUCCESS(aws_http_message_set_request_method(request, aws_byte_cursor_from_c_str("PUT")));
386 ASSERT_SUCCESS(aws_http_message_set_request_path(request, aws_byte_cursor_from_c_str("/")));
387 aws_http_message_add_header_array(request, headers, AWS_ARRAY_SIZE(headers));
388
389 struct aws_linked_list chunk_list;
390 aws_linked_list_init(&chunk_list);
391
392 struct aws_h1_encoder_message encoder_message;
393
394 /* Per RFC 2656 (https://tools.ietf.org/html/rfc2616#section-4.4), if both the Content-Length and Transfer-Encoding
395 * header are defined, the client should not send the request. */
396 ASSERT_INT_EQUALS(
397 AWS_OP_ERR, aws_h1_encoder_message_init_from_request(&encoder_message, allocator, request, &chunk_list));
398
399 aws_input_stream_destroy(body_stream);
400 aws_http_message_destroy(request);
401 aws_h1_encoder_message_clean_up(&encoder_message);
402 aws_h1_encoder_clean_up(&encoder);
403 s_test_clean_up();
404 return AWS_OP_SUCCESS;
405 }
406
H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_chunked_not_final_encoding_put_request_headers)407 H1_ENCODER_TEST_CASE(h1_encoder_transfer_encoding_chunked_not_final_encoding_put_request_headers) {
408 (void)ctx;
409 s_test_init(allocator);
410 struct aws_h1_encoder encoder;
411 aws_h1_encoder_init(&encoder, allocator);
412
413 /* request to send - we won't actually send it, we want to validate headers are set correctly. */
414
415 struct aws_http_header headers[] = {
416 {
417 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Transfer-Encoding"),
418 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("chunked;gzip"), /* must end with chunked */
419 },
420 };
421
422 struct aws_http_message *request = aws_http_message_new_request(allocator);
423 ASSERT_SUCCESS(aws_http_message_set_request_method(request, aws_byte_cursor_from_c_str("PUT")));
424 ASSERT_SUCCESS(aws_http_message_set_request_path(request, aws_byte_cursor_from_c_str("/")));
425 aws_http_message_add_header_array(request, headers, AWS_ARRAY_SIZE(headers));
426
427 struct aws_linked_list chunk_list;
428 aws_linked_list_init(&chunk_list);
429
430 struct aws_h1_encoder_message encoder_message;
431
432 /* Per RFC 2656 (https://tools.ietf.org/html/rfc2616#section-4.4), if both the Content-Length and Transfer-Encoding
433 * header are defined, the client should not send the request. */
434 ASSERT_INT_EQUALS(
435 AWS_OP_ERR, aws_h1_encoder_message_init_from_request(&encoder_message, allocator, request, &chunk_list));
436
437 aws_http_message_destroy(request);
438 aws_h1_encoder_message_clean_up(&encoder_message);
439 aws_h1_encoder_clean_up(&encoder);
440 s_test_clean_up();
441 return AWS_OP_SUCCESS;
442 }
443
s_test_bad_request(struct aws_allocator * allocator,const char * method,const char * path,const struct aws_http_header * header_array,size_t header_count,int expected_error)444 static int s_test_bad_request(
445 struct aws_allocator *allocator,
446 const char *method,
447 const char *path,
448 const struct aws_http_header *header_array,
449 size_t header_count,
450 int expected_error) {
451
452 s_test_init(allocator);
453
454 struct aws_http_message *request = aws_http_message_new_request(allocator);
455 ASSERT_NOT_NULL(request);
456 if (method) {
457 ASSERT_SUCCESS(aws_http_message_set_request_method(request, aws_byte_cursor_from_c_str(method)));
458 }
459 if (path) {
460 ASSERT_SUCCESS(aws_http_message_set_request_path(request, aws_byte_cursor_from_c_str(path)));
461 }
462 if (header_array) {
463 ASSERT_SUCCESS(aws_http_message_add_header_array(request, header_array, header_count));
464 }
465
466 struct aws_linked_list chunk_list;
467 aws_linked_list_init(&chunk_list);
468
469 struct aws_h1_encoder_message encoder_message;
470
471 ASSERT_ERROR(
472 expected_error, aws_h1_encoder_message_init_from_request(&encoder_message, allocator, request, &chunk_list));
473
474 aws_http_message_destroy(request);
475 aws_h1_encoder_message_clean_up(&encoder_message);
476 s_test_clean_up();
477 return AWS_OP_SUCCESS;
478 }
479
H1_ENCODER_TEST_CASE(h1_encoder_rejects_bad_method)480 H1_ENCODER_TEST_CASE(h1_encoder_rejects_bad_method) {
481 (void)ctx;
482 return s_test_bad_request(
483 allocator,
484 "G@T" /*method*/,
485 "/" /*path*/,
486 s_typical_request_headers /*header_array*/,
487 AWS_ARRAY_SIZE(s_typical_request_headers) /*header_count*/,
488 AWS_ERROR_HTTP_INVALID_METHOD /*expected_error*/);
489 }
490
H1_ENCODER_TEST_CASE(h1_encoder_rejects_missing_method)491 H1_ENCODER_TEST_CASE(h1_encoder_rejects_missing_method) {
492 (void)ctx;
493 return s_test_bad_request(
494 allocator,
495 NULL /*method*/,
496 "/" /*path*/,
497 s_typical_request_headers /*header_array*/,
498 AWS_ARRAY_SIZE(s_typical_request_headers) /*header_count*/,
499 AWS_ERROR_HTTP_INVALID_METHOD /*expected_error*/);
500 }
501
H1_ENCODER_TEST_CASE(h1_encoder_rejects_bad_path)502 H1_ENCODER_TEST_CASE(h1_encoder_rejects_bad_path) {
503 (void)ctx;
504 return s_test_bad_request(
505 allocator,
506 "GET" /*method*/,
507 "/\r\n/index.html" /*path*/,
508 s_typical_request_headers /*header_array*/,
509 AWS_ARRAY_SIZE(s_typical_request_headers) /*header_count*/,
510 AWS_ERROR_HTTP_INVALID_PATH /*expected_error*/);
511 }
512
H1_ENCODER_TEST_CASE(h1_encoder_rejects_missing_path)513 H1_ENCODER_TEST_CASE(h1_encoder_rejects_missing_path) {
514 (void)ctx;
515 return s_test_bad_request(
516 allocator,
517 "GET" /*method*/,
518 NULL /*path*/,
519 s_typical_request_headers /*header_array*/,
520 AWS_ARRAY_SIZE(s_typical_request_headers) /*header_count*/,
521 AWS_ERROR_HTTP_INVALID_PATH /*expected_error*/);
522 }
523
H1_ENCODER_TEST_CASE(h1_encoder_rejects_bad_header_name)524 H1_ENCODER_TEST_CASE(h1_encoder_rejects_bad_header_name) {
525 (void)ctx;
526 const struct aws_http_header headers[] = {
527 {
528 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Host"),
529 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("amazon.com"),
530 },
531 {
532 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Line-\r\n-Folds"),
533 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("bad header name"),
534 },
535 };
536
537 return s_test_bad_request(
538 allocator,
539 "GET" /*method*/,
540 "/" /*path*/,
541 headers /*header_array*/,
542 AWS_ARRAY_SIZE(headers) /*header_count*/,
543 AWS_ERROR_HTTP_INVALID_HEADER_NAME /*expected_error*/);
544 }
545
H1_ENCODER_TEST_CASE(h1_encoder_rejects_bad_header_value)546 H1_ENCODER_TEST_CASE(h1_encoder_rejects_bad_header_value) {
547 (void)ctx;
548 const struct aws_http_header headers[] = {
549 {
550 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Host"),
551 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("amazon.com"),
552 },
553 {
554 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("X-Line-Folds-Are-Bad-Mkay"),
555 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("item1,\r\n item2"),
556 },
557 };
558
559 return s_test_bad_request(
560 allocator,
561 "GET" /*method*/,
562 "/" /*path*/,
563 headers /*header_array*/,
564 AWS_ARRAY_SIZE(headers) /*header_count*/,
565 AWS_ERROR_HTTP_INVALID_HEADER_VALUE /*expected_error*/);
566 }
567