Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package aws-c-http for openSUSE:Factory checked in at 2026-02-10 21:13:20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/aws-c-http (Old) and /work/SRC/openSUSE:Factory/.aws-c-http.new.1670 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aws-c-http" Tue Feb 10 21:13:20 2026 rev:24 rq:1332252 version:0.10.10 Changes: -------- --- /work/SRC/openSUSE:Factory/aws-c-http/aws-c-http.changes 2026-01-13 21:29:14.822773668 +0100 +++ /work/SRC/openSUSE:Factory/.aws-c-http.new.1670/aws-c-http.changes 2026-02-10 21:14:04.723726903 +0100 @@ -1,0 +2,7 @@ +Fri Feb 6 11:34:31 UTC 2026 - John Paul Adrian Glaubitz <[email protected]> + +- Update to 0.10.10 + * Fix h2 stream manager initial settings not passed correctly and + log the headers by @TingDaoK in (#544) + +------------------------------------------------------------------- Old: ---- v0.10.9.tar.gz New: ---- v0.10.10.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ aws-c-http.spec ++++++ --- /var/tmp/diff_new_pack.uXZ3S7/_old 2026-02-10 21:14:05.259749363 +0100 +++ /var/tmp/diff_new_pack.uXZ3S7/_new 2026-02-10 21:14:05.263749531 +0100 @@ -1,7 +1,7 @@ # # spec file for package aws-c-http # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2026 SUSE LLC and contributors # Copyright (c) 2025 Andreas Stieger <[email protected]> # # All modifications and additions to the file contributed by third parties @@ -20,7 +20,7 @@ %define library_version 1.0.0 %define library_soversion 1_0_0 Name: aws-c-http -Version: 0.10.9 +Version: 0.10.10 Release: 0 Summary: C99 implementation of the HTTP/1.1 and HTTP/2 specifications License: Apache-2.0 ++++++ v0.10.9.tar.gz -> v0.10.10.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-http-0.10.9/include/aws/http/private/http_impl.h new/aws-c-http-0.10.10/include/aws/http/private/http_impl.h --- old/aws-c-http-0.10.9/include/aws/http/private/http_impl.h 2026-01-07 00:27:34.000000000 +0100 +++ new/aws-c-http-0.10.10/include/aws/http/private/http_impl.h 2026-01-30 22:42:32.000000000 +0100 @@ -67,6 +67,8 @@ AWS_HTTP_HEADER_UPGRADE, AWS_HTTP_HEADER_KEEP_ALIVE, AWS_HTTP_HEADER_PROXY_CONNECTION, + AWS_HTTP_HEADER_SIGNING_SECURITY_TOKEN, + AWS_HTTP_HEADER_SIGNING_S3SESSION_TOKEN, AWS_HTTP_HEADER_COUNT, /* Number of enums */ }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-http-0.10.9/source/connection_manager.c new/aws-c-http-0.10.10/source/connection_manager.c --- old/aws-c-http-0.10.9/source/connection_manager.c 2026-01-07 00:27:34.000000000 +0100 +++ new/aws-c-http-0.10.10/source/connection_manager.c 2026-01-30 22:42:32.000000000 +0100 @@ -978,10 +978,13 @@ manager->initial_settings = aws_mem_calloc(allocator, 1, sizeof(struct aws_array_list)); aws_array_list_init_dynamic( manager->initial_settings, allocator, options->num_initial_settings, sizeof(struct aws_http2_setting)); + /* Copy the initial_settings_array to the internal structure */ memcpy( manager->initial_settings->data, options->initial_settings_array, options->num_initial_settings * sizeof(struct aws_http2_setting)); + /* Update the length of the array as the memcpy only copies the data, but the length remains 0. */ + manager->initial_settings->length = options->num_initial_settings; } manager->max_closed_streams = options->max_closed_streams; manager->http2_conn_manual_window_management = options->http2_conn_manual_window_management; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-http-0.10.9/source/h1_stream.c new/aws-c-http-0.10.10/source/h1_stream.c --- old/aws-c-http-0.10.9/source/h1_stream.c 2026-01-07 00:27:34.000000000 +0100 +++ new/aws-c-http-0.10.10/source/h1_stream.c 2026-01-30 22:42:32.000000000 +0100 @@ -431,6 +431,37 @@ stream->thread_data.is_final_stream = true; } + struct aws_http_headers *headers = aws_http_message_get_headers(options->request); + + /* Log the headers that we are sending out. */ + for (size_t i = 0; i < aws_http_headers_count(headers); i++) { + struct aws_http_header header; + aws_http_headers_get_index(headers, i, &header); + enum aws_http_header_name name_enum = aws_http_str_to_header_name(header.name); + switch (name_enum) { + case AWS_HTTP_HEADER_AUTHORIZATION: + case AWS_HTTP_HEADER_SIGNING_SECURITY_TOKEN: + case AWS_HTTP_HEADER_SIGNING_S3SESSION_TOKEN: + /* TODO: move the filter to SDKs, not the http client. */ + /* Sensitive header, do not log the value of the header */ + AWS_LOGF_TRACE( + AWS_LS_HTTP_STREAM, + "id=%p: Sending header: " PRInSTR ": ***", + (void *)&stream->base, + AWS_BYTE_CURSOR_PRI(header.name)); + break; + default: + /* Log the headers we are sending out */ + AWS_LOGF_TRACE( + AWS_LS_HTTP_STREAM, + "id=%p: Sending header: " PRInSTR ": " PRInSTR "", + (void *)&stream->base, + AWS_BYTE_CURSOR_PRI(header.name), + AWS_BYTE_CURSOR_PRI(header.value)); + break; + } + } + stream->synced_data.using_chunked_encoding = stream->thread_data.encoder_message.has_chunked_encoding_header; return stream; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-http-0.10.9/source/h2_stream.c new/aws-c-http-0.10.10/source/h2_stream.c --- old/aws-c-http-0.10.9/source/h2_stream.c 2026-01-07 00:27:34.000000000 +0100 +++ new/aws-c-http-0.10.10/source/h2_stream.c 2026-01-30 22:42:32.000000000 +0100 @@ -750,6 +750,48 @@ connection->thread_data.settings_self[AWS_HTTP2_SETTINGS_INITIAL_WINDOW_SIZE] / 2; } + /* Log the headers that we are sending out. */ + for (size_t i = 0; i < aws_http_headers_count(h2_headers); i++) { + struct aws_http_header header; + aws_http_headers_get_index(h2_headers, i, &header); + enum aws_http_header_name name_enum = aws_http_str_to_header_name(header.name); + switch (name_enum) { + case AWS_HTTP_HEADER_CONNECTION: + case AWS_HTTP_HEADER_TRANSFER_ENCODING: + case AWS_HTTP_HEADER_UPGRADE: + case AWS_HTTP_HEADER_KEEP_ALIVE: + case AWS_HTTP_HEADER_PROXY_CONNECTION: + /** + * An endpoint MUST NOT generate an HTTP/2 message containing connection-specific header fields. + * (RFC=9113 8.2.2) + */ + AWS_H2_STREAM_LOGF( + TRACE, + stream, + "Found connection-specific header that is allowed in HTTP/2. : " PRInSTR ": " PRInSTR "", + AWS_BYTE_CURSOR_PRI(header.name), + AWS_BYTE_CURSOR_PRI(header.value)); + aws_raise_error(AWS_ERROR_HTTP_INVALID_HEADER_FIELD); + goto error; + case AWS_HTTP_HEADER_AUTHORIZATION: + case AWS_HTTP_HEADER_SIGNING_SECURITY_TOKEN: + case AWS_HTTP_HEADER_SIGNING_S3SESSION_TOKEN: + /* TODO: move the filter to SDKs, not the http client. */ + /* Sensitive header, do not log the value of the header */ + AWS_H2_STREAM_LOGF(TRACE, stream, "Sending header: " PRInSTR ": ***", AWS_BYTE_CURSOR_PRI(header.name)); + break; + default: + /* Log the headers we are sending out */ + AWS_H2_STREAM_LOGF( + TRACE, + stream, + "Sending header: " PRInSTR ": " PRInSTR "", + AWS_BYTE_CURSOR_PRI(header.name), + AWS_BYTE_CURSOR_PRI(header.value)); + break; + } + } + if (with_data) { /* If stream has DATA to send, put it in the outgoing_streams_list, and we'll send data later */ stream->thread_data.state = AWS_H2_STREAM_STATE_OPEN; @@ -1109,6 +1151,14 @@ return s_send_rst_and_close_stream(stream, aws_h2err_from_h2_code(AWS_HTTP2_ERR_FLOW_CONTROL_ERROR)); } stream->thread_data.window_size_self -= payload_len; + if (stream->thread_data.window_size_self == 0) { + AWS_H2_STREAM_LOGF( + ERROR, + stream, + "DATA length=%" PRIu32 " exceeds flow-control window=%" PRIi32, + payload_len, + stream->thread_data.window_size_self); + } /* If stream isn't over, we may need to send automatic window updates to keep data flowing */ if (!end_stream) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-http-0.10.9/source/http.c new/aws-c-http-0.10.10/source/http.c --- old/aws-c-http-0.10.9/source/http.c 2026-01-07 00:27:34.000000000 +0100 +++ new/aws-c-http-0.10.10/source/http.c 2026-01-30 22:42:32.000000000 +0100 @@ -339,6 +339,8 @@ s_header_enum_to_str[AWS_HTTP_HEADER_UPGRADE] = aws_byte_cursor_from_c_str("upgrade"); s_header_enum_to_str[AWS_HTTP_HEADER_KEEP_ALIVE] = aws_byte_cursor_from_c_str("keep-alive"); s_header_enum_to_str[AWS_HTTP_HEADER_PROXY_CONNECTION] = aws_byte_cursor_from_c_str("proxy-connection"); + s_header_enum_to_str[AWS_HTTP_HEADER_SIGNING_SECURITY_TOKEN] = aws_byte_cursor_from_c_str("x-amz-security-token"); + s_header_enum_to_str[AWS_HTTP_HEADER_SIGNING_S3SESSION_TOKEN] = aws_byte_cursor_from_c_str("x-amz-s3session-token"); s_init_str_to_enum_hash_table( &s_header_str_to_enum, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-http-0.10.9/source/request_response.c new/aws-c-http-0.10.10/source/request_response.c --- old/aws-c-http-0.10.9/source/request_response.c 2026-01-07 00:27:34.000000000 +0100 +++ new/aws-c-http-0.10.10/source/request_response.c 2026-01-30 22:42:32.000000000 +0100 @@ -1036,15 +1036,17 @@ struct aws_byte_cursor lower_name_cursor = aws_byte_cursor_from_buf(&lower_name_buf); enum aws_http_header_name name_enum = aws_http_lowercase_str_to_header_name(lower_name_cursor); switch (name_enum) { + /** + * An intermediary transforming an HTTP/1.x message to HTTP/2 MUST remove connection-specific header + * fields as discussed in Section 7.6.1 of [HTTP]. (RFC=9113 8.2.2) + */ + case AWS_HTTP_HEADER_CONNECTION: case AWS_HTTP_HEADER_TRANSFER_ENCODING: case AWS_HTTP_HEADER_UPGRADE: case AWS_HTTP_HEADER_KEEP_ALIVE: case AWS_HTTP_HEADER_PROXY_CONNECTION: + /* Host has been converted to :authority pseudo header, skip it as well. */ case AWS_HTTP_HEADER_HOST: - /** - * An intermediary transforming an HTTP/1.x message to HTTP/2 MUST remove connection-specific header - * fields as discussed in Section 7.6.1 of [HTTP]. (RFC=9113 8.2.2) - */ AWS_LOGF_TRACE( AWS_LS_HTTP_GENERAL, "Skip connection-specific headers - \"%.*s\" ", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-http-0.10.9/tests/CMakeLists.txt new/aws-c-http-0.10.10/tests/CMakeLists.txt --- old/aws-c-http-0.10.9/tests/CMakeLists.txt 2026-01-07 00:27:34.000000000 +0100 +++ new/aws-c-http-0.10.10/tests/CMakeLists.txt 2026-01-30 22:42:32.000000000 +0100 @@ -692,6 +692,8 @@ add_net_test_case(h2_sm_mock_large_ideal_num_streams) add_net_test_case(h2_sm_mock_goaway) add_net_test_case(h2_sm_connection_ping) +add_net_test_case(h2_sm_with_flow_control_err) +add_net_test_case(h2_sm_with_initial_settings) # Tests against real world server add_net_test_case(h2_sm_acquire_stream) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-http-0.10.9/tests/test_stream_manager.c new/aws-c-http-0.10.10/tests/test_stream_manager.c --- old/aws-c-http-0.10.9/tests/test_stream_manager.c 2026-01-07 00:27:34.000000000 +0100 +++ new/aws-c-http-0.10.10/tests/test_stream_manager.c 2026-01-30 22:42:32.000000000 +0100 @@ -55,6 +55,13 @@ bool close_connection_on_server_error; size_t connection_ping_period_ms; size_t connection_ping_timeout_ms; + + /* HTTP/2 initial settings */ + const struct aws_http2_setting *initial_settings_array; + size_t num_initial_settings; + + bool manual_window; + size_t initial_window_size; }; static struct aws_logger s_logger; @@ -290,6 +297,10 @@ .connection_ping_period_ms = options->connection_ping_period_ms, .connection_ping_timeout_ms = options->connection_ping_timeout_ms, .http2_prior_knowledge = options->prior_knowledge, + .initial_settings_array = options->initial_settings_array, + .num_initial_settings = options->num_initial_settings, + .initial_window_size = options->initial_window_size, + .enable_read_back_pressure = options->manual_window, }; s_tester.stream_manager = aws_http2_stream_manager_new(alloc, &sm_options); @@ -330,7 +341,8 @@ /* complete first num_streams_to_complete. If num_streams_to_complete is zero, complete all the streams. */ static void s_fake_connection_complete_streams( struct sm_fake_connection *fake_connection, - int num_streams_to_complete) { + int num_streams_to_complete, + bool with_data) { if (!fake_connection->connection) { return; } @@ -350,8 +362,16 @@ struct h2_decoded_frame *frame = h2_decode_tester_get_frame(&fake_connection->peer.decode, i); if (frame->end_stream) { struct aws_h2_frame *response_frame = aws_h2_frame_new_headers( - s_tester.allocator, frame->stream_id, response_headers, true /*end_stream*/, 0, NULL); + s_tester.allocator, frame->stream_id, response_headers, !with_data /*end_stream*/, 0, NULL); AWS_FATAL_ASSERT(h2_fake_peer_send_frame(&fake_connection->peer, response_frame) == AWS_OP_SUCCESS); + if (with_data) { + AWS_FATAL_ASSERT( + h2_fake_peer_send_data_frame( + &fake_connection->peer, + frame->stream_id, + aws_byte_cursor_from_c_str("tests"), + true /*end_stream*/) == AWS_OP_SUCCESS); + } if (num_streams_to_complete && ++streams_completed >= num_streams_to_complete) { break; } @@ -395,18 +415,26 @@ s_drain_all_fake_connection_testing_channel(); } -static int s_complete_all_fake_connection_streams(void) { +static int s_complete_all_fake_connection_streams_impl(bool with_data) { size_t count = aws_array_list_length(&s_tester.fake_connections); for (size_t i = 0; i < count; ++i) { struct sm_fake_connection *fake_connection = NULL; ASSERT_SUCCESS(aws_array_list_get_at(&s_tester.fake_connections, &fake_connection, i)); /* complete all the streams from the fake connection */ - s_fake_connection_complete_streams(fake_connection, 0 /*all streams*/); + s_fake_connection_complete_streams(fake_connection, 0 /*all streams*/, with_data); testing_channel_drain_queued_tasks(&fake_connection->testing_channel); } return AWS_OP_SUCCESS; } +static int s_complete_all_fake_connection_streams(void) { + return s_complete_all_fake_connection_streams_impl(false); +} + +static int s_complete_all_fake_connection_streams_with_data(void) { + return s_complete_all_fake_connection_streams_impl(true); +} + static int s_tester_clean_up(void) { s_release_all_streams(); if (s_tester.stream_manager) { @@ -952,7 +980,7 @@ /* Fake peer send settings that only allow 2 concurrent streams */ struct sm_fake_connection *fake_connection = s_get_fake_connection(0); ASSERT_SUCCESS(h2_fake_peer_send_connection_preface_default_settings(&fake_connection->peer)); - s_fake_connection_complete_streams(fake_connection, 1); + s_fake_connection_complete_streams(fake_connection, 1, false); /* Acquire a new streams */ ASSERT_SUCCESS(s_sm_stream_acquiring(1)); @@ -1160,7 +1188,7 @@ ASSERT_SUCCESS(h2_fake_peer_send_frame(&fake_connection_1->peer, peer_frame)); testing_channel_drain_queued_tasks(&fake_connection_1->testing_channel); s_fake_connection_complete_streams( - fake_connection_1, 0 /*all streams*/); /* Make sure the streams completed successfully */ + fake_connection_1, 0 /*all streams*/, false); /* Make sure the streams completed successfully */ /* Check fake connection 2 received PING */ ASSERT_SUCCESS(h2_fake_peer_decode_messages_from_testing_channel(&fake_connection_2->peer)); @@ -1187,6 +1215,83 @@ return s_tester_clean_up(); } + +/* Test that stream manager with flow control error if the server didn't respect the window */ +TEST_CASE(h2_sm_with_flow_control_err) { + (void)ctx; + + struct sm_tester_options options = { + .max_connections = 5, + .alloc = allocator, + .manual_window = true, + .initial_window_size = 0, + }; + + ASSERT_SUCCESS(s_tester_init(&options)); + ASSERT_NOT_NULL(s_tester.stream_manager); + + /* Verify stream manager works with initial settings */ + s_override_cm_connect_function(s_aws_http_connection_manager_create_connection_sync_mock); + int num_to_acquire = 1; + ASSERT_SUCCESS(s_sm_stream_acquiring(num_to_acquire)); + ASSERT_SUCCESS(s_wait_on_fake_connection_count(1)); + s_drain_all_fake_connection_testing_channel(); + ASSERT_SUCCESS(s_wait_on_streams_acquired_count(num_to_acquire)); + ASSERT_SUCCESS(s_complete_all_fake_connection_streams_with_data()); + ASSERT_INT_EQUALS(1, s_tester.stream_complete_errors); + ASSERT_INT_EQUALS(AWS_ERROR_HTTP_PROTOCOL_ERROR, s_tester.stream_completed_error_code); + + return s_tester_clean_up(); +} + +/* Test that stream manager can be created with initial_settings_array configured */ +TEST_CASE(h2_sm_with_initial_settings) { + (void)ctx; + /* TODO: VALIDATE from the peer that those settings received. For now we test this with settings to override the + * initial window. */ + /* Configure custom HTTP/2 initial settings */ + struct aws_http2_setting initial_settings[] = { + { + .id = AWS_HTTP2_SETTINGS_HEADER_TABLE_SIZE, + .value = 8192, + }, + { + .id = AWS_HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, + .value = 128, + }, + { + .id = AWS_HTTP2_SETTINGS_INITIAL_WINDOW_SIZE, + .value = 65536, + }, + }; + + struct sm_tester_options options = { + .max_connections = 5, + .alloc = allocator, + .initial_settings_array = initial_settings, + .num_initial_settings = AWS_ARRAY_SIZE(initial_settings), + .manual_window = true, + /* Set initial window size to 0, but the settings should override it to keep the data flow. */ + .initial_window_size = 0, + }; + + ASSERT_SUCCESS(s_tester_init(&options)); + ASSERT_NOT_NULL(s_tester.stream_manager); + + /* Verify stream manager works with initial settings */ + s_override_cm_connect_function(s_aws_http_connection_manager_create_connection_sync_mock); + int num_to_acquire = 1; + ASSERT_SUCCESS(s_sm_stream_acquiring(num_to_acquire)); + ASSERT_SUCCESS(s_wait_on_fake_connection_count(1)); + s_drain_all_fake_connection_testing_channel(); + ASSERT_SUCCESS(s_wait_on_streams_acquired_count(num_to_acquire)); + ASSERT_SUCCESS(s_complete_all_fake_connection_streams_with_data()); + /* Should complete without error */ + ASSERT_INT_EQUALS(0, s_tester.stream_complete_errors); + ASSERT_INT_EQUALS(AWS_ERROR_SUCCESS, s_tester.stream_completed_error_code); + + return s_tester_clean_up(); +} /******************************************************************************* * Net test, that makes real HTTP/2 connection and requests
