Skip to content

fix: skip CRT Content-Length when chunked#7173

Merged
zoewangg merged 1 commit into
masterfrom
zoewang/crt-chunked-transfer-encoding
Jul 21, 2026
Merged

fix: skip CRT Content-Length when chunked#7173
zoewangg merged 1 commit into
masterfrom
zoewang/crt-chunked-transfer-encoding

Conversation

@zoewangg

Copy link
Copy Markdown
Contributor

Motivation and Context

When the AWS CRT-based async HTTP client sends a request with a body of unknown
length, the SDK marshals it with Transfer-Encoding: chunked and no
Content-Length. However, the CRT request adapter also synthesized a
Content-Length from the request body publisher's reported length whenever one
was available. This could produce a request carrying both
Content-Length and Transfer-Encoding: chunked.

Per RFC 7230 (section 3.3.2/3.3.3) a sender must not emit Content-Length
together with Transfer-Encoding. The underlying CRT layer enforces this and
rejects such a request with AWS_ERROR_HTTP_INVALID_HEADER_FIELD
("Both Content-Length and Transfer-Encoding are set. Only one may be used").

This is RFC 7230 compliance hardening. It aligns the CRT client with the Netty
client, which never synthesizes a Content-Length from the publisher length for
a chunked request. Note: for the operations that actually use request chunked
transfer encoding (unsigned-payload operations) over their normal HTTPS
endpoints, the payload is unsigned and no concrete publisher length is
introduced, so real callers did not hit the conflict; this is defense-in-depth,
not a fix for a runtime hang.

Modifications

CrtRequestAdapter.createAsyncHttpHeaderList (aws-crt-client): no longer adds
the Content-Length header when the request already carries a
Transfer-Encoding header. Uses the existing Header.CONTENT_LENGTH /
Header.TRANSFER_ENCODING constants and the existing firstMatchingHeader
lookup style. The sync createHttpHeaderList was left unchanged: it never
synthesizes Content-Length (it only copies headers already on the request),
so it cannot produce the conflict.

Testing

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

Checklist

License

  • I confirm that this pull request can be released under the Apache 2 license

The CRT async request adapter synthesized a Content-Length from the
request body publisher even when the request already carried
Transfer-Encoding: chunked. Emitting both headers violates RFC 7230
and was rejected by the underlying CRT layer. Skip Content-Length
when Transfer-Encoding is present, aligning the CRT client with the
Netty client, which never synthesizes Content-Length for a chunked
request. Adds unit coverage for the adapter and HTTPS functional
tests for the sync and async CRT chunked paths.
@zoewangg
zoewangg requested a review from a team as a code owner July 21, 2026 17:49
@zoewangg
zoewangg added this pull request to the merge queue Jul 21, 2026
Merged via the queue into master with commit 378771e Jul 21, 2026
12 of 13 checks passed
@github-actions

Copy link
Copy Markdown

This pull request has been closed and the conversation has been locked. Comments on closed PRs are hard for our team to see. If you need more assistance, please open a new issue that references this one.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Jul 21, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants