Skip to content

Conversation

Lukasa
Copy link
Contributor

@Lukasa Lukasa commented Aug 21, 2023

Motivation:

Right now we always set the framing headers in HTTP requests and responses that we send. This is a good practice for most users, but it can cause issues, most notably in responses to CONNECT requests which requires that we do not set framing headers.

Unfortunately, in NIO's current HTTP/1.1 design it is not possible for us to suppress these headers. This is because the HTTP encoders come earlier in the pipeline than the decoders, so the HTTP encoders do not know structurally what requests they are responding to.

While we could merge the encoders/decoders, that's a fairly substantial change. A better short-term change is to offer users the ability to turn off the NIO header manipulation feature. In this circumstance, users take on full responsibility for appropriately framing their HTTP messages.

Modifications

  • Add config to HTTPRequestEncoder and HTTPResponseEncoder.
  • Plumb this config through.
  • Add a bunch of tests.

Result

Users have way more control of HTTP/1.1 messages.

Motivation:

Right now we always set the framing headers in HTTP requests and
responses that we send. This is a good practice for most users, but
it can cause issues, most notably in responses to CONNECT requests
which requires that we do not set framing headers.

Unfortunately, in NIO's current HTTP/1.1 design it is not possible
for us to suppress these headers. This is because the HTTP encoders
come _earlier_ in the pipeline than the decoders, so the HTTP
encoders do not know structurally what requests they are responding
to.

While we could merge the encoders/decoders, that's a fairly
substantial change. A better short-term change is to offer users
the ability to turn off the NIO header manipulation feature. In
this circumstance, users take on full responsibility for
appropriately framing their HTTP messages.

Modifications

- Add config to HTTPRequestEncoder and HTTPResponseEncoder.
- Plumb this config through.
- Add a bunch of tests.

Result

Users have way more control of HTTP/1.1 messages.
Copy link
Contributor

@glbrntt glbrntt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Left a couple of nits inline.

/// encoding, when needed.
private func messageIsChunked(headers: HTTPHeaders, version: HTTPVersion) -> Bool {
if version.major == 1 && version.minor >= 1 {
return headers["transfer-encoding"].first == "chunked" ? true : false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: headers.first(name: "transfer-encoding")

self.isChunked = correctlyFrameTransportHeaders(hasBody: response.status.mayHaveResponseBody ? .yes : .no,
headers: &response.headers, version: response.version) == .chunked

if configuration.automaticallySetFramingHeaders {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if configuration.automaticallySetFramingHeaders {
if self.configuration.automaticallySetFramingHeaders {

@Lukasa Lukasa enabled auto-merge (squash) August 22, 2023 09:26
@Lukasa Lukasa merged commit 7d9f892 into apple:main Aug 22, 2023
@Lukasa Lukasa deleted the cb-no-framing-headers-on-connect branch August 22, 2023 10:32
1proprogrammerchant added a commit to 1proprogrammerchant/swift-nio that referenced this pull request Aug 24, 2023
Support users opting-out of us setting framing headers. (apple#2508)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🆕 semver/minor Adds new public API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants