Skip to content

Commit 60fef53

Browse files
authored
[HTTP2] Internal HTTPVersion configuration (#463)
1 parent 149b8d2 commit 60fef53

File tree

3 files changed

+67
-25
lines changed

3 files changed

+67
-25
lines changed

Diff for: Sources/AsyncHTTPClient/ConnectionPool/HTTPConnectionPool+Factory.swift

+9-12
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,14 @@ extension HTTPConnectionPool {
3131
let tlsConfiguration: TLSConfiguration
3232
let sslContextCache: SSLContextCache
3333

34-
// This property can be removed once we enable true http/2 support
35-
let allowHTTP2Connections: Bool
36-
3734
init(key: ConnectionPool.Key,
3835
tlsConfiguration: TLSConfiguration?,
3936
clientConfiguration: HTTPClient.Configuration,
40-
sslContextCache: SSLContextCache,
41-
allowHTTP2Connections: Bool = false) {
37+
sslContextCache: SSLContextCache) {
4238
self.key = key
4339
self.clientConfiguration = clientConfiguration
4440
self.sslContextCache = sslContextCache
4541
self.tlsConfiguration = tlsConfiguration ?? clientConfiguration.tlsConfiguration ?? .makeClientConfiguration()
46-
self.allowHTTP2Connections = allowHTTP2Connections
4742
}
4843
}
4944
}
@@ -303,13 +298,14 @@ extension HTTPConnectionPool.ConnectionFactory {
303298
return channel.eventLoop.makeSucceededFuture(.http1_1(channel))
304299
case .https:
305300
var tlsConfig = self.tlsConfiguration
306-
// since we can support h2, we need to advertise this in alpn
307-
if self.allowHTTP2Connections {
301+
switch self.clientConfiguration.httpVersion.configuration {
302+
case .automatic:
303+
// since we can support h2, we need to advertise this in alpn
308304
// "ProtocolNameList" contains the list of protocols advertised by the
309305
// client, in descending order of preference.
310306
// https://datatracker.ietf.org/doc/html/rfc7301#section-3.1
311307
tlsConfig.applicationProtocols = ["h2", "http/1.1"]
312-
} else {
308+
case .http1Only:
313309
tlsConfig.applicationProtocols = ["http/1.1"]
314310
}
315311
let tlsEventHandler = TLSEventsHandler(deadline: deadline)
@@ -407,14 +403,15 @@ extension HTTPConnectionPool.ConnectionFactory {
407403

408404
private func makeTLSBootstrap(deadline: NIODeadline, eventLoop: EventLoop, logger: Logger)
409405
-> EventLoopFuture<NIOClientTCPBootstrapProtocol> {
410-
// since we can support h2, we need to advertise this in alpn
411406
var tlsConfig = self.tlsConfiguration
412-
if self.allowHTTP2Connections {
407+
switch self.clientConfiguration.httpVersion.configuration {
408+
case .automatic:
409+
// since we can support h2, we need to advertise this in alpn
413410
// "ProtocolNameList" contains the list of protocols advertised by the
414411
// client, in descending order of preference.
415412
// https://datatracker.ietf.org/doc/html/rfc7301#section-3.1
416413
tlsConfig.applicationProtocols = ["h2", "http/1.1"]
417-
} else {
414+
case .http1Only:
418415
tlsConfig.applicationProtocols = ["http/1.1"]
419416
}
420417

Diff for: Sources/AsyncHTTPClient/HTTPClient.swift

+54-7
Original file line numberDiff line numberDiff line change
@@ -603,20 +603,51 @@ public class HTTPClient {
603603
/// Ignore TLS unclean shutdown error, defaults to `false`.
604604
public var ignoreUncleanSSLShutdown: Bool
605605

606-
public init(tlsConfiguration: TLSConfiguration? = nil,
607-
redirectConfiguration: RedirectConfiguration? = nil,
608-
timeout: Timeout = Timeout(),
609-
connectionPool: ConnectionPool = ConnectionPool(),
610-
proxy: Proxy? = nil,
611-
ignoreUncleanSSLShutdown: Bool = false,
612-
decompression: Decompression = .disabled) {
606+
// TODO: make public
607+
// TODO: set to automatic by default
608+
/// HTTP/2 is by default disabled
609+
internal var httpVersion: HTTPVersion
610+
611+
public init(
612+
tlsConfiguration: TLSConfiguration? = nil,
613+
redirectConfiguration: RedirectConfiguration? = nil,
614+
timeout: Timeout = Timeout(),
615+
connectionPool: ConnectionPool = ConnectionPool(),
616+
proxy: Proxy? = nil,
617+
ignoreUncleanSSLShutdown: Bool = false,
618+
decompression: Decompression = .disabled
619+
) {
620+
self.init(
621+
tlsConfiguration: tlsConfiguration,
622+
redirectConfiguration: redirectConfiguration,
623+
timeout: timeout, connectionPool: connectionPool,
624+
proxy: proxy,
625+
ignoreUncleanSSLShutdown: ignoreUncleanSSLShutdown,
626+
decompression: decompression,
627+
// TODO: set to automatic by default
628+
httpVersion: .http1Only
629+
)
630+
}
631+
632+
// TODO: make public
633+
internal init(
634+
tlsConfiguration: TLSConfiguration? = nil,
635+
redirectConfiguration: RedirectConfiguration? = nil,
636+
timeout: Timeout = Timeout(),
637+
connectionPool: ConnectionPool = ConnectionPool(),
638+
proxy: Proxy? = nil,
639+
ignoreUncleanSSLShutdown: Bool = false,
640+
decompression: Decompression = .disabled,
641+
httpVersion: HTTPVersion
642+
) {
613643
self.tlsConfiguration = tlsConfiguration
614644
self.redirectConfiguration = redirectConfiguration ?? RedirectConfiguration()
615645
self.timeout = timeout
616646
self.connectionPool = connectionPool
617647
self.proxy = proxy
618648
self.ignoreUncleanSSLShutdown = ignoreUncleanSSLShutdown
619649
self.decompression = decompression
650+
self.httpVersion = httpVersion
620651
}
621652

622653
public init(tlsConfiguration: TLSConfiguration? = nil,
@@ -830,6 +861,22 @@ extension HTTPClient.Configuration {
830861
self.concurrentHTTP1ConnectionsPerHostSoftLimit = concurrentHTTP1ConnectionsPerHostSoftLimit
831862
}
832863
}
864+
865+
// TODO: make this struct and its static properties public
866+
internal struct HTTPVersion {
867+
internal enum Configuration {
868+
case http1Only
869+
case automatic
870+
}
871+
872+
/// we only use HTTP/1, even if the server would supports HTTP/2
873+
internal static let http1Only: Self = .init(configuration: .http1Only)
874+
875+
/// HTTP/2 is used if we connect to a server with HTTPS and the server supports HTTP/2, otherwise we use HTTP/1
876+
internal static let automatic: Self = .init(configuration: .automatic)
877+
878+
internal var configuration: Configuration
879+
}
833880
}
834881

835882
/// Possible client errors.

Diff for: Tests/AsyncHTTPClientTests/HTTP2ConnectionTests.swift

+4-6
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,8 @@ class TestConnectionCreator {
253253
let factory = HTTPConnectionPool.ConnectionFactory(
254254
key: .init(request),
255255
tlsConfiguration: tlsConfiguration,
256-
clientConfiguration: .init(),
257-
sslContextCache: .init(),
258-
allowHTTP2Connections: true
256+
clientConfiguration: .init(httpVersion: .automatic),
257+
sslContextCache: .init()
259258
)
260259

261260
let promise = try self.lock.withLock { () -> EventLoopPromise<HTTP1Connection> in
@@ -295,9 +294,8 @@ class TestConnectionCreator {
295294
let factory = HTTPConnectionPool.ConnectionFactory(
296295
key: .init(request),
297296
tlsConfiguration: tlsConfiguration,
298-
clientConfiguration: .init(),
299-
sslContextCache: .init(),
300-
allowHTTP2Connections: true
297+
clientConfiguration: .init(httpVersion: .automatic),
298+
sslContextCache: .init()
301299
)
302300

303301
let promise = try self.lock.withLock { () -> EventLoopPromise<HTTP2Connection> in

0 commit comments

Comments
 (0)