Skip to content

Refactor deconstructURL and scheme parsing #504

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

Merged
merged 11 commits into from
Dec 1, 2021

Conversation

dnadoba
Copy link
Collaborator

@dnadoba dnadoba commented Nov 30, 2021

Motivation

We want to reuse our URL parsing, validation and deconstruction logic for the upcoming new HTTPClientRequest from the async/await proposal.

Changes

  • Introduce a new DeconstructedURL struct which hold a scheme, connectionTarget and uri.
  • Introduce a new DeconstructedURL.Scheme enum which replaced the previous String in HTTPClient.Request and ConnectionPool.Scheme enum
  • move deconstructURL logic to an initialiser of DeconstructedURL
  • use DeconstructedURL instead of separate scheme, connectionTarget, and uri properties in HTTPClient.Request
  • remove HTTPClient.Request.Kind because it is almost a replica of the DeconstructedURL.Scheme enum where the only difference is that http and https are represented as one case called host. As we now represent scheme as an enum instead of a String we can safely replace it with an exhaustive switch over scheme instead.
  • refactor tests to use scheme instead of kind
  • remove unused config(overriding:) from ConnectionPool.Key

Conflicts:
	Sources/AsyncHTTPClient/ConnectionPool.swift
	Sources/AsyncHTTPClient/ConnectionPool/HTTPConnectionPool+Factory.swift
	Sources/AsyncHTTPClient/HTTPHandler.swift
	Tests/AsyncHTTPClientTests/HTTPClientInternalTests.swift
@dnadoba dnadoba requested a review from fabianfett November 30, 2021 19:03
@dnadoba
Copy link
Collaborator Author

dnadoba commented Nov 30, 2021

@swift-server-bot test this please

Copy link
Member

@fabianfett fabianfett left a comment

Choose a reason for hiding this comment

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

All in all looks good. Few changes wanted.

//
//===----------------------------------------------------------------------===//

import Foundation
Copy link
Member

Choose a reason for hiding this comment

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

NIT: Only import what is actually needed.

Suggested change
import Foundation
import struct Foundation.URL

}

extension DeconstructedURL.Scheme {
var useTLS: Bool {
Copy link
Member

Choose a reason for hiding this comment

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

He, she, it das s muss mit ;)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We will diverge from the public API on HTTPClient.Request but I’m okay with that

Comment on lines 18 to 24
enum Scheme: String {
case http
case https
case unix
case httpUnix = "http+unix"
case httpsUnix = "https+unix"
}
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure this should be namespaced in DeconstructedURL. Would you mind moving this out?

- rename `useTLS` to `usesTLS` where posible without breaking public API
- only import Foundation.URL
@@ -748,7 +748,7 @@ internal struct RedirectHandler<ResponseType> {
}
}

extension DeconstructedURL.Scheme {
extension Scheme {
Copy link
Member

Choose a reason for hiding this comment

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

I think this should live in the Scheme file.

Comment on lines 100 to 102
/// Parsed, validated and deconstructed URL.
internal let deconstructedURL: DeconstructedURL

Copy link
Member

Choose a reason for hiding this comment

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

NIT: Move down to other internal var like redirect state. Mixing internal and public makes this hard to read.

Copy link
Member

@fabianfett fabianfett left a comment

Choose a reason for hiding this comment

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

Very cool, except for the tiny nits.

@fabianfett
Copy link
Member

@swift-server-bot test this please

@dnadoba dnadoba merged commit 99bd384 into swift-server:main Dec 1, 2021
@dnadoba dnadoba deleted the dn-scheme branch December 1, 2021 12:03
@fabianfett fabianfett added the 🔨 semver/patch No public API change. label Dec 1, 2021
@karwa
Copy link
Contributor

karwa commented Dec 1, 2021

One thing that might be worth considering is if the scheme can just be dropped?

  • http == httpUnix == unix, the only difference is the connection target (host/UDS)
  • https == httpsUnix, the only difference is the connection target (host/UDS)

Because it now knows which kind of connection target it has, the only thing the scheme provides is whether to use TLS.

@dnadoba
Copy link
Collaborator Author

dnadoba commented Dec 1, 2021

Sadly we expose the scheme as public API. Not as the Scheme enum but as a String on HTTPClient.Request and therefore need to preserve it for the time being.

@karwa
Copy link
Contributor

karwa commented Dec 1, 2021

Technically, it could get that from the URL. There's no need for ConnectionPool or most other things to know specifically which kind of scheme was used (also, http+unix and unix schemes should resolve to the same connection in the pool if they point to the same socket).

@Lukasa
Copy link
Collaborator

Lukasa commented Dec 1, 2021

(also, http+unix and unix schemes should resolve to the same connection in the pool if they point to the same socket).

I disagree with this: the scheme is meaningfully part of both the origin and the network key for a request, and so should use different connections.

@fabianfett
Copy link
Member

fabianfett commented Dec 1, 2021

The problem here are http semantics. From an http standpoint unix:///some/path and http+unix:///some/path go to different places. While the server might be the same, the pure semantics say they are different (because of the different scheme). And since connections are trust boundaries, we need to make the differentiation based on the scheme.

@karwa
Copy link
Contributor

karwa commented Dec 1, 2021

I'm not sure to what extent HTTP really intends to define the semantics of non-http:/https: URLs. It sounds more likely that the semantics of application-defined schemes are also application-defined.

@Lukasa
Copy link
Collaborator

Lukasa commented Dec 1, 2021

HTTP does not define them. I agree that in principle we can define them however we want. Given that schemes are explicitly part of the connection pooling pattern in fetch, the most prudent choice is to generalise that idea to these schemes, especially as there are very few practical problems caused by doing so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔨 semver/patch No public API change.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants