@@ -451,3 +451,110 @@ TEST_CASE(h2_client_stream_ignores_some_frames_received_soon_after_closing) {
451451 client_stream_tester_clean_up (& stream_tester );
452452 return s_tester_clean_up ();
453453}
454+
455+ /* Test receiving a response with DATA frames */
456+ TEST_CASE (h2_client_stream_receive_data ) {
457+ ASSERT_SUCCESS (s_tester_init (allocator , ctx ));
458+
459+ /* fake peer sends connection preface */
460+ ASSERT_SUCCESS (h2_fake_peer_send_connection_preface_default_settings (& s_tester .peer ));
461+ testing_channel_drain_queued_tasks (& s_tester .testing_channel );
462+
463+ /* send request */
464+ struct aws_http_message * request = aws_http_message_new_request (allocator );
465+ ASSERT_NOT_NULL (request );
466+
467+ struct aws_http_header request_headers_src [] = {
468+ DEFINE_HEADER (":method" , "GET" ),
469+ DEFINE_HEADER (":scheme" , "https" ),
470+ DEFINE_HEADER (":path" , "/" ),
471+ };
472+ aws_http_message_add_header_array (request , request_headers_src , AWS_ARRAY_SIZE (request_headers_src ));
473+
474+ struct client_stream_tester stream_tester ;
475+ ASSERT_SUCCESS (s_stream_tester_init (& stream_tester , request ));
476+ testing_channel_drain_queued_tasks (& s_tester .testing_channel );
477+
478+ uint32_t stream_id = aws_http_stream_get_id (stream_tester .stream );
479+
480+ /* fake peer sends response headers */
481+ struct aws_http_header response_headers_src [] = {
482+ DEFINE_HEADER (":status" , "200" ),
483+ };
484+
485+ struct aws_http_headers * response_headers = aws_http_headers_new (allocator );
486+ aws_http_headers_add_array (response_headers , response_headers_src , AWS_ARRAY_SIZE (response_headers_src ));
487+
488+ struct aws_h2_frame * response_frame =
489+ aws_h2_frame_new_headers (allocator , stream_id , response_headers , false /*end_stream*/ , 0 , NULL );
490+ ASSERT_SUCCESS (h2_fake_peer_send_frame (& s_tester .peer , response_frame ));
491+
492+ /* fake peer sends response body */
493+ const char * body_src = "hello" ;
494+ ASSERT_SUCCESS (h2_fake_peer_send_data_frame_str (& s_tester .peer , stream_id , body_src , true /*end_stream*/ ));
495+
496+ /* validate that client received complete response */
497+ testing_channel_drain_queued_tasks (& s_tester .testing_channel );
498+ ASSERT_TRUE (stream_tester .complete );
499+ ASSERT_INT_EQUALS (AWS_ERROR_SUCCESS , stream_tester .on_complete_error_code );
500+ ASSERT_INT_EQUALS (200 , stream_tester .response_status );
501+ ASSERT_SUCCESS (s_compare_headers (response_headers , stream_tester .response_headers ));
502+ ASSERT_TRUE (aws_byte_buf_eq_c_str (& stream_tester .response_body , body_src ));
503+
504+ ASSERT_TRUE (aws_http_connection_is_open (s_tester .connection ));
505+
506+ /* clean up */
507+ aws_http_headers_release (response_headers );
508+ aws_http_message_release (request );
509+ client_stream_tester_clean_up (& stream_tester );
510+ return s_tester_clean_up ();
511+ }
512+
513+ /* A message is malformed if DATA is received before HEADERS */
514+ TEST_CASE (h2_client_stream_err_receive_data_before_headers ) {
515+ ASSERT_SUCCESS (s_tester_init (allocator , ctx ));
516+
517+ /* fake peer sends connection preface */
518+ ASSERT_SUCCESS (h2_fake_peer_send_connection_preface_default_settings (& s_tester .peer ));
519+ testing_channel_drain_queued_tasks (& s_tester .testing_channel );
520+
521+ /* send request */
522+ struct aws_http_message * request = aws_http_message_new_request (allocator );
523+ ASSERT_NOT_NULL (request );
524+
525+ struct aws_http_header request_headers_src [] = {
526+ DEFINE_HEADER (":method" , "GET" ),
527+ DEFINE_HEADER (":scheme" , "https" ),
528+ DEFINE_HEADER (":path" , "/" ),
529+ };
530+ aws_http_message_add_header_array (request , request_headers_src , AWS_ARRAY_SIZE (request_headers_src ));
531+
532+ struct client_stream_tester stream_tester ;
533+ ASSERT_SUCCESS (s_stream_tester_init (& stream_tester , request ));
534+ testing_channel_drain_queued_tasks (& s_tester .testing_channel );
535+
536+ uint32_t stream_id = aws_http_stream_get_id (stream_tester .stream );
537+
538+ /* fake peer sends response body BEFORE any response headers */
539+ const char * body_src = "hello" ;
540+ ASSERT_SUCCESS (h2_fake_peer_send_data_frame_str (& s_tester .peer , stream_id , body_src , true /*end_stream*/ ));
541+
542+ /* validate that stream completed with error */
543+ testing_channel_drain_queued_tasks (& s_tester .testing_channel );
544+ ASSERT_TRUE (stream_tester .complete );
545+ ASSERT_INT_EQUALS (AWS_ERROR_HTTP_PROTOCOL_ERROR , stream_tester .on_complete_error_code );
546+
547+ /* a stream error should not affect the connection */
548+ ASSERT_TRUE (aws_http_connection_is_open (s_tester .connection ));
549+
550+ /* validate that stream sent RST_STREAM */
551+ ASSERT_SUCCESS (h2_fake_peer_decode_messages_from_testing_channel (& s_tester .peer ));
552+ struct h2_decoded_frame * rst_stream_frame = h2_decode_tester_latest_frame (& s_tester .peer .decode );
553+ ASSERT_INT_EQUALS (AWS_H2_FRAME_T_RST_STREAM , rst_stream_frame -> type );
554+ ASSERT_UINT_EQUALS (AWS_H2_ERR_PROTOCOL_ERROR , rst_stream_frame -> error_code );
555+
556+ /* clean up */
557+ aws_http_message_release (request );
558+ client_stream_tester_clean_up (& stream_tester );
559+ return s_tester_clean_up ();
560+ }
0 commit comments