From b274a526039dc866d670dee0b4e58ba92158fc53 Mon Sep 17 00:00:00 2001 From: Dengke Tang Date: Wed, 28 Jan 2026 11:52:08 -0800 Subject: [PATCH 1/7] log headers --- source/h2_stream.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/source/h2_stream.c b/source/h2_stream.c index 4a5f93649..a1d1a1caf 100644 --- a/source/h2_stream.c +++ b/source/h2_stream.c @@ -750,6 +750,19 @@ int aws_h2_stream_on_activated(struct aws_h2_stream *stream, enum aws_h2_stream_ connection->thread_data.settings_self[AWS_HTTP2_SETTINGS_INITIAL_WINDOW_SIZE] / 2; } + /* Log the headers that we are sending out. */ + size_t header_count = aws_http_headers_count(h2_headers); + for (size_t i = 0; i < header_count; i++) { + struct aws_http_header header; + aws_http_headers_get_index(h2_headers, i, &header); + AWS_H2_STREAM_LOGF( + TRACE, + stream, + "id=%p: Sending header: " PRInSTR ": " PRInSTR, + AWS_BYTE_CURSOR_PRI(header.name), + AWS_BYTE_CURSOR_PRI(header.value)); + } + 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; From 00641ac504b32ab34c440e1bf0a8ed9ce85aa039 Mon Sep 17 00:00:00 2001 From: Dengke Tang Date: Wed, 28 Jan 2026 13:21:45 -0800 Subject: [PATCH 2/7] hmmm --- source/h2_stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/h2_stream.c b/source/h2_stream.c index a1d1a1caf..f1d2378fc 100644 --- a/source/h2_stream.c +++ b/source/h2_stream.c @@ -758,7 +758,7 @@ int aws_h2_stream_on_activated(struct aws_h2_stream *stream, enum aws_h2_stream_ AWS_H2_STREAM_LOGF( TRACE, stream, - "id=%p: Sending header: " PRInSTR ": " PRInSTR, + "Sending header: " PRInSTR ": " PRInSTR "", AWS_BYTE_CURSOR_PRI(header.name), AWS_BYTE_CURSOR_PRI(header.value)); } From 7e72d2a912e7f1abd227e40994963db2a0e0c631 Mon Sep 17 00:00:00 2001 From: Dengke Tang Date: Thu, 29 Jan 2026 09:26:36 -0800 Subject: [PATCH 3/7] eh, connection header is also connection-specific header --- source/request_response.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/request_response.c b/source/request_response.c index dbd5214e7..9bf7aa6f3 100644 --- a/source/request_response.c +++ b/source/request_response.c @@ -1036,6 +1036,7 @@ struct aws_http_message *aws_http2_message_new_from_http1( 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) { + case AWS_HTTP_HEADER_CONNECTION: case AWS_HTTP_HEADER_TRANSFER_ENCODING: case AWS_HTTP_HEADER_UPGRADE: case AWS_HTTP_HEADER_KEEP_ALIVE: From 4710f7b1f2fabe1a84b279e945e6da6c14686246 Mon Sep 17 00:00:00 2001 From: Dengke Tang Date: Thu, 29 Jan 2026 09:50:43 -0800 Subject: [PATCH 4/7] log the headers at trace level --- source/h1_stream.c | 28 ++++++++++++++++++++++++++++ source/h2_stream.c | 42 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/source/h1_stream.c b/source/h1_stream.c index a43bd37fb..1687ddb5f 100644 --- a/source/h1_stream.c +++ b/source/h1_stream.c @@ -431,6 +431,34 @@ struct aws_h1_stream *aws_h1_stream_new_request( 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: + /* 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 --git a/source/h2_stream.c b/source/h2_stream.c index f1d2378fc..09a1a36b7 100644 --- a/source/h2_stream.c +++ b/source/h2_stream.c @@ -751,16 +751,42 @@ int aws_h2_stream_on_activated(struct aws_h2_stream *stream, enum aws_h2_stream_ } /* Log the headers that we are sending out. */ - size_t header_count = aws_http_headers_count(h2_headers); - for (size_t i = 0; i < header_count; i++) { + 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); - AWS_H2_STREAM_LOGF( - TRACE, - stream, - "Sending header: " PRInSTR ": " PRInSTR "", - AWS_BYTE_CURSOR_PRI(header.name), - AWS_BYTE_CURSOR_PRI(header.value)); + 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: + case AWS_HTTP_HEADER_HOST: + /** + * An endpoint MUST NOT generate an HTTP/2 message containing connection-specific header fields. + */ + 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: + /* 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) { From 3ce6747c1f4e033e15525fad139da6495f5f8624 Mon Sep 17 00:00:00 2001 From: Dengke Tang Date: Thu, 29 Jan 2026 09:53:15 -0800 Subject: [PATCH 5/7] host is allowed --- source/h2_stream.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/h2_stream.c b/source/h2_stream.c index 09a1a36b7..edbf3340a 100644 --- a/source/h2_stream.c +++ b/source/h2_stream.c @@ -761,7 +761,6 @@ int aws_h2_stream_on_activated(struct aws_h2_stream *stream, enum aws_h2_stream_ case AWS_HTTP_HEADER_UPGRADE: case AWS_HTTP_HEADER_KEEP_ALIVE: case AWS_HTTP_HEADER_PROXY_CONNECTION: - case AWS_HTTP_HEADER_HOST: /** * An endpoint MUST NOT generate an HTTP/2 message containing connection-specific header fields. */ From 5e6716f7be24c07e7bcb507ebcfd6aea6629755c Mon Sep 17 00:00:00 2001 From: Dengke Tang Date: Thu, 29 Jan 2026 09:55:30 -0800 Subject: [PATCH 6/7] document it better --- source/request_response.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/request_response.c b/source/request_response.c index 9bf7aa6f3..6f290b0e1 100644 --- a/source/request_response.c +++ b/source/request_response.c @@ -1036,16 +1036,17 @@ struct aws_http_message *aws_http2_message_new_from_http1( 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\" ", From 28c9fd9671007a919124bf0d124ee353ca30af65 Mon Sep 17 00:00:00 2001 From: Dengke Tang Date: Thu, 29 Jan 2026 09:56:26 -0800 Subject: [PATCH 7/7] RFC link --- source/h2_stream.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/h2_stream.c b/source/h2_stream.c index edbf3340a..74655853f 100644 --- a/source/h2_stream.c +++ b/source/h2_stream.c @@ -763,6 +763,7 @@ int aws_h2_stream_on_activated(struct aws_h2_stream *stream, enum aws_h2_stream_ 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,