From 4bb36322cee2f73fa775a403e428f9973687ed5b Mon Sep 17 00:00:00 2001 From: Michael Graeb Date: Thu, 30 May 2024 09:27:38 -0700 Subject: [PATCH] Add test where connection shuts down before response completes --- tests/CMakeLists.txt | 3 ++- tests/test_h1_client.c | 42 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9d23059a..9422fc80 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -121,7 +121,8 @@ add_test_case(h1_client_response_close_header_with_pipelining) add_test_case(h1_client_respects_stream_window) add_test_case(h1_client_connection_window_with_buffer) add_test_case(h1_client_connection_window_with_small_buffer) -add_test_case(h1_client_request_cancelled_by_channel_shutdown) +add_test_case(h1_client_request_cancelled_by_channel_shutdown_before_response) +add_test_case(h1_client_request_cancelled_by_channel_shutdown_mid_response) add_test_case(h1_client_multiple_requests_cancelled_by_channel_shutdown) add_test_case(h1_client_new_request_fails_if_channel_shut_down) add_test_case(h1_client_error_from_outgoing_body_callback_stops_decoder) diff --git a/tests/test_h1_client.c b/tests/test_h1_client.c index 0be08269..89ac9852 100644 --- a/tests/test_h1_client.c +++ b/tests/test_h1_client.c @@ -3273,7 +3273,8 @@ H1_CLIENT_TEST_CASE(h1_client_request_chunks_cancelled_by_channel_shutdown) { return AWS_OP_SUCCESS; } -H1_CLIENT_TEST_CASE(h1_client_request_cancelled_by_channel_shutdown) { +/* If channel shuts down before any response is received, the request should complete with an error */ +H1_CLIENT_TEST_CASE(h1_client_request_cancelled_by_channel_shutdown_before_response) { (void)ctx; struct tester tester; ASSERT_SUCCESS(s_tester_init(&tester, allocator)); @@ -3311,6 +3312,45 @@ H1_CLIENT_TEST_CASE(h1_client_request_cancelled_by_channel_shutdown) { return AWS_OP_SUCCESS; } +/* If channel shuts down in the middle of a response, the request should complete with an error */ +H1_CLIENT_TEST_CASE(h1_client_request_cancelled_by_channel_shutdown_mid_response) { + (void)ctx; + struct tester tester; + ASSERT_SUCCESS(s_tester_init(&tester, allocator)); + + /* send request */ + struct aws_http_message *request = s_new_default_get_request(allocator); + + struct client_stream_tester stream_tester; + ASSERT_SUCCESS(s_stream_tester_init(&stream_tester, &tester, request)); + + testing_channel_drain_queued_tasks(&tester.testing_channel); + + /* Ensure the request can be destroyed after request is sent */ + aws_http_message_destroy(request); + + /* send response that is 1 byte short of being complete */ + const char *response_str = "HTTP/1.1 200 OK\r\n" + "Content-Length: 4\r\n" + "\r\n" + "123"; + ASSERT_SUCCESS(testing_channel_push_read_str(&tester.testing_channel, response_str)); + + /* shutdown channel while response is 1 byte short of being complete */ + aws_channel_shutdown(tester.testing_channel.channel, AWS_ERROR_SUCCESS); + testing_channel_drain_queued_tasks(&tester.testing_channel); + + /* the request should complete with error, having only received a partial response */ + ASSERT_TRUE(stream_tester.complete); + ASSERT_INT_EQUALS(AWS_ERROR_HTTP_CONNECTION_CLOSED, stream_tester.on_complete_error_code); + ASSERT_UINT_EQUALS(3, stream_tester.response_body.len); + + /* clean up */ + client_stream_tester_clean_up(&stream_tester); + ASSERT_SUCCESS(s_tester_clean_up(&tester)); + return AWS_OP_SUCCESS; +} + H1_CLIENT_TEST_CASE(h1_client_multiple_requests_cancelled_by_channel_shutdown) { (void)ctx; struct tester tester;