@@ -5141,3 +5141,126 @@ H1_CLIENT_TEST_CASE(h1_client_connection_close_before_request_finishes_with_buff
51415141 (void )ctx ;
51425142 return s_h1_client_connection_close_before_request_finishes_with_buffer_force_shutdown_helper (allocator , false);
51435143}
5144+
5145+ /* Test: Response with no Content-Length or Transfer-Encoding has its body determined by connection closure */
5146+ H1_CLIENT_TEST_CASE (h1_client_response_indeterminate_length_body ) {
5147+ (void )ctx ;
5148+ struct tester tester ;
5149+ ASSERT_SUCCESS (s_tester_init (& tester , allocator ));
5150+
5151+ /* send request */
5152+ struct aws_http_message * request = s_new_default_get_request (allocator );
5153+
5154+ struct client_stream_tester stream_tester ;
5155+ ASSERT_SUCCESS (s_stream_tester_init (& stream_tester , & tester , request ));
5156+
5157+ testing_channel_drain_queued_tasks (& tester .testing_channel );
5158+ aws_http_message_destroy (request );
5159+
5160+ /* send response with no Content-Length or Transfer-Encoding */
5161+ ASSERT_SUCCESS (testing_channel_push_read_str (
5162+ & tester .testing_channel ,
5163+ "HTTP/1.1 200 OK\r\n"
5164+ "Connection: close\r\n"
5165+ "\r\n"
5166+ "hello " ));
5167+
5168+ testing_channel_drain_queued_tasks (& tester .testing_channel );
5169+
5170+ /* stream should NOT be complete yet - waiting for connection close */
5171+ ASSERT_FALSE (stream_tester .complete );
5172+ ASSERT_UINT_EQUALS (6 , stream_tester .response_body .len );
5173+
5174+ /* send more body data */
5175+ ASSERT_SUCCESS (testing_channel_push_read_str (& tester .testing_channel , "world" ));
5176+ testing_channel_drain_queued_tasks (& tester .testing_channel );
5177+
5178+ ASSERT_FALSE (stream_tester .complete );
5179+ ASSERT_UINT_EQUALS (11 , stream_tester .response_body .len );
5180+
5181+ /* close the connection - this should complete the stream */
5182+ aws_channel_shutdown (tester .testing_channel .channel , AWS_ERROR_SUCCESS );
5183+ testing_channel_drain_queued_tasks (& tester .testing_channel );
5184+
5185+ ASSERT_TRUE (stream_tester .complete );
5186+ ASSERT_INT_EQUALS (AWS_ERROR_SUCCESS , stream_tester .on_complete_error_code );
5187+ ASSERT_INT_EQUALS (200 , stream_tester .response_status );
5188+ ASSERT_TRUE (aws_byte_buf_eq_c_str (& stream_tester .response_body , "hello world" ));
5189+
5190+ /* clean up */
5191+ client_stream_tester_clean_up (& stream_tester );
5192+ ASSERT_SUCCESS (s_tester_clean_up (& tester ));
5193+ return AWS_OP_SUCCESS ;
5194+ }
5195+
5196+ /* Test: Response with no Content-Length and empty body - connection closes right after headers */
5197+ H1_CLIENT_TEST_CASE (h1_client_response_indeterminate_length_empty_body ) {
5198+ (void )ctx ;
5199+ struct tester tester ;
5200+ ASSERT_SUCCESS (s_tester_init (& tester , allocator ));
5201+
5202+ struct aws_http_message * request = s_new_default_get_request (allocator );
5203+
5204+ struct client_stream_tester stream_tester ;
5205+ ASSERT_SUCCESS (s_stream_tester_init (& stream_tester , & tester , request ));
5206+
5207+ testing_channel_drain_queued_tasks (& tester .testing_channel );
5208+ aws_http_message_destroy (request );
5209+
5210+ /* send response headers only, no body, no Content-Length */
5211+ ASSERT_SUCCESS (testing_channel_push_read_str (
5212+ & tester .testing_channel ,
5213+ "HTTP/1.1 200 OK\r\n"
5214+ "\r\n" ));
5215+
5216+ testing_channel_drain_queued_tasks (& tester .testing_channel );
5217+
5218+ /* stream should NOT be complete yet */
5219+ ASSERT_FALSE (stream_tester .complete );
5220+
5221+ /* close connection */
5222+ aws_channel_shutdown (tester .testing_channel .channel , AWS_ERROR_SUCCESS );
5223+ testing_channel_drain_queued_tasks (& tester .testing_channel );
5224+
5225+ ASSERT_TRUE (stream_tester .complete );
5226+ ASSERT_INT_EQUALS (AWS_ERROR_SUCCESS , stream_tester .on_complete_error_code );
5227+ ASSERT_INT_EQUALS (200 , stream_tester .response_status );
5228+ ASSERT_UINT_EQUALS (0 , stream_tester .response_body .len );
5229+
5230+ client_stream_tester_clean_up (& stream_tester );
5231+ ASSERT_SUCCESS (s_tester_clean_up (& tester ));
5232+ return AWS_OP_SUCCESS ;
5233+ }
5234+
5235+ /* Test: 1xx and 204 responses must NOT enter indeterminate-length mode (body_headers_forbidden) */
5236+ H1_CLIENT_TEST_CASE (h1_client_response_204_no_indeterminate_length ) {
5237+ (void )ctx ;
5238+ struct tester tester ;
5239+ ASSERT_SUCCESS (s_tester_init (& tester , allocator ));
5240+
5241+ struct aws_http_message * request = s_new_default_get_request (allocator );
5242+
5243+ struct client_stream_tester stream_tester ;
5244+ ASSERT_SUCCESS (s_stream_tester_init (& stream_tester , & tester , request ));
5245+
5246+ testing_channel_drain_queued_tasks (& tester .testing_channel );
5247+ aws_http_message_destroy (request );
5248+
5249+ /* 204 with no Content-Length should complete immediately, not wait for connection close */
5250+ ASSERT_SUCCESS (testing_channel_push_read_str (
5251+ & tester .testing_channel ,
5252+ "HTTP/1.1 204 No Content\r\n"
5253+ "\r\n" ));
5254+
5255+ testing_channel_drain_queued_tasks (& tester .testing_channel );
5256+
5257+ /* stream should be complete immediately - 204 has no body */
5258+ ASSERT_TRUE (stream_tester .complete );
5259+ ASSERT_INT_EQUALS (AWS_ERROR_SUCCESS , stream_tester .on_complete_error_code );
5260+ ASSERT_INT_EQUALS (204 , stream_tester .response_status );
5261+ ASSERT_UINT_EQUALS (0 , stream_tester .response_body .len );
5262+
5263+ client_stream_tester_clean_up (& stream_tester );
5264+ ASSERT_SUCCESS (s_tester_clean_up (& tester ));
5265+ return AWS_OP_SUCCESS ;
5266+ }
0 commit comments