Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HTTPDecoder] Decode informational http response head correctly #1984

Merged
merged 3 commits into from
Nov 8, 2021

Conversation

fabianfett
Copy link
Member

@fabianfett fabianfett commented Nov 8, 2021

We should support HTTP requests that are answered with an informational response first, which is followed up by the actual response. See issue: swift-server/async-http-client#461

Motivation:

  • Currently requests that lead to a 1xx response are handled incorrectly

Modifications:

  • Add an InformalResponseStrategy enum that allows the user to specify whether http 1xx responses shall be forwarded or dropped.
  • Implement the necessary cases in HTTPDecoder and BetterHTTPParser

Result:

We will be able to fix swift-server/async-http-client#461

}

/// Strategy to use when a HTTPDecoder receives an informal HTTP response (1xx except 101)
public enum InformalResponseStrategy {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: these are not informal responses, they are informational responses. All the terminology in this PR should be changed appropriately.

Copy link
Contributor

Choose a reason for hiding this comment

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

Similarly, we should probably use an extensible enum for our API design here (i.e. enum wrapped in struct with static lets.

} else if statusCode / 100 == 1 || // 1XX codes
statusCode == 204 || statusCode == 304 {

if (HTTPResponseStatus.continue.code <= statusCode && statusCode < HTTPResponseStatus.ok.code)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's fine to treat these codes as numbers here.

private let kind: HTTPDecoderKind
private var stopParsing = false // set on upgrade or HTTP version error
private var lastHeaderWasInformal = false
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't really mean "header" here, we mean "response".

status: .init(statusCode: statusCode),
headers: HTTPHeaders(self.headers,
keepAliveState: keepAliveState))
message = NIOAny(HTTPClientResponsePart.head(resHead))
Copy link
Contributor

Choose a reason for hiding this comment

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

Can I propose we wrap the common code in this case and the case below into a single helper?

public enum InformalResponseStrategy {
/// Drop the informal response and only forward the "real" response
case drop
/// Forward the informal response and then forward the "real" response
Copy link
Contributor

Choose a reason for hiding this comment

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

We should clarify what this looks like (namely, multiple .head messages for a single .end).

@fabianfett fabianfett marked this pull request as ready for review November 8, 2021 16:35
Copy link
Contributor

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

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

Really nice. One minor nit, otherwise I’m happy.

Tests/NIOHTTP1Tests/HTTPDecoderTest.swift Outdated Show resolved Hide resolved
Co-authored-by: Cory Benfield <lukasa@apple.com>
@fabianfett fabianfett changed the title [HTTPDecoder] Decode informal headers correctly [HTTPDecoder] Decode informational http response head correctly Nov 8, 2021
@fabianfett fabianfett merged commit 7a36304 into apple:main Nov 8, 2021
@fabianfett fabianfett deleted the ff-decode-informal-headers branch November 8, 2021 18:41
@fabianfett fabianfett added the semver/minor Adds new public API. label Nov 9, 2021
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.

100 Continue is not handled correctly in all cases
2 participants