From b49d7a54d954f7880be335ade892cbe991aa3d4c Mon Sep 17 00:00:00 2001 From: Nakul Bajaj Date: Thu, 2 Apr 2026 12:55:44 -0700 Subject: [PATCH 1/5] Abstract API: add server HTTP version request option --- Sources/AHCHTTPClient/AHC+HTTPClient.swift | 6 ++-- ...pability+ServerHTTPVersionCapability.swift | 31 +++++++++++++++++ Sources/HTTPClient/DefaultHTTPClient.swift | 6 ++-- Sources/HTTPClient/HTTPRequestOptions.swift | 5 ++- Sources/NetworkTypes/HTTPVersion.swift | 34 +++++++++++++++++++ .../URLSessionHTTPClient.swift | 2 +- .../URLSessionRequestOptions.swift | 5 +-- 7 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 Sources/HTTPAPIs/Client/HTTPClientCapability+ServerHTTPVersionCapability.swift create mode 100644 Sources/NetworkTypes/HTTPVersion.swift diff --git a/Sources/AHCHTTPClient/AHC+HTTPClient.swift b/Sources/AHCHTTPClient/AHC+HTTPClient.swift index 4469f5a..6081afc 100644 --- a/Sources/AHCHTTPClient/AHC+HTTPClient.swift +++ b/Sources/AHCHTTPClient/AHC+HTTPClient.swift @@ -11,6 +11,8 @@ // //===----------------------------------------------------------------------===// +public import NetworkTypes + @_spi(ExperimentalHTTPAPIsSupport) public import AsyncHTTPClient import BasicContainers import Foundation @@ -25,8 +27,8 @@ extension AsyncHTTPClient.HTTPClient: HTTPAPIs.HTTPClient { public typealias RequestWriter = RequestBodyWriter public typealias ResponseConcludingReader = ResponseReader - public struct RequestOptions: HTTPClientCapability.RequestOptions { - + public struct RequestOptions: HTTPClientCapability.ServerHTTPVersionCapability { + public var serverSupportedHTTPVersions: Set = [] } public struct RequestBodyWriter: AsyncWriter, ~Copyable { diff --git a/Sources/HTTPAPIs/Client/HTTPClientCapability+ServerHTTPVersionCapability.swift b/Sources/HTTPAPIs/Client/HTTPClientCapability+ServerHTTPVersionCapability.swift new file mode 100644 index 0000000..4e40041 --- /dev/null +++ b/Sources/HTTPAPIs/Client/HTTPClientCapability+ServerHTTPVersionCapability.swift @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift HTTP API Proposal open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift HTTP API Proposal project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift HTTP API Proposal project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +public import NetworkTypes + +@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) +extension HTTPClientCapability { + /// A protocol for HTTP request options that support specifying server HTTP version capabilities. + /// + /// Providing server HTTP version information allows the client to optimize + /// connection establishment. For example, if a server is known to support HTTP/3, + /// the client can attempt a QUIC connection directly. + public protocol ServerHTTPVersionCapability: RequestOptions { + /// The HTTP versions that the target server is known to support. + /// + /// An empty set indicates no prior knowledge of server capabilities, + /// and the client uses its default protocol negotiation behavior. + var serverSupportedHTTPVersions: Set { get set } + } +} diff --git a/Sources/HTTPClient/DefaultHTTPClient.swift b/Sources/HTTPClient/DefaultHTTPClient.swift index 29bceec..2716508 100644 --- a/Sources/HTTPClient/DefaultHTTPClient.swift +++ b/Sources/HTTPClient/DefaultHTTPClient.swift @@ -137,12 +137,12 @@ public final class DefaultHTTPClient: HTTPAPIs.HTTPClient { options: HTTPRequestOptions, responseHandler: (HTTPResponse, consuming ResponseConcludingReader) async throws -> Return ) async throws -> Return { - // TODO: translate request options - let options = self.client.defaultRequestOptions + var translatedOptions = self.client.defaultRequestOptions + translatedOptions.serverSupportedHTTPVersions = options.serverSupportedHTTPVersions let body = body.map { HTTPClientRequestBody(other: $0) { RequestWriter(actual: $0) } } - return try await self.client.perform(request: request, body: body, options: options) { response, body in + return try await self.client.perform(request: request, body: body, options: translatedOptions) { response, body in try await responseHandler(response, ResponseConcludingReader(actual: body)) } } diff --git a/Sources/HTTPClient/HTTPRequestOptions.swift b/Sources/HTTPClient/HTTPRequestOptions.swift index c87bdfa..67b2c42 100644 --- a/Sources/HTTPClient/HTTPRequestOptions.swift +++ b/Sources/HTTPClient/HTTPRequestOptions.swift @@ -10,9 +10,12 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +public import NetworkTypes /// The options for the default HTTP client implementation. @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) -public struct HTTPRequestOptions: HTTPClientCapability.RequestOptions { +public struct HTTPRequestOptions: HTTPClientCapability.ServerHTTPVersionCapability { + public var serverSupportedHTTPVersions: Set = [] + public init() {} } diff --git a/Sources/NetworkTypes/HTTPVersion.swift b/Sources/NetworkTypes/HTTPVersion.swift new file mode 100644 index 0000000..1fa16ac --- /dev/null +++ b/Sources/NetworkTypes/HTTPVersion.swift @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift HTTP API Proposal open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift HTTP API Proposal project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift HTTP API Proposal project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// An enumeration that represents an HTTP protocol version. +/// +/// ``HTTPVersion`` provides type-safe access to supported HTTP protocol versions, +/// allowing clients and servers to communicate version capabilities. +public enum HTTPVersion: UInt8, Sendable, Hashable { + /// HTTP/1. + /// + /// HTTP/1 is defined in RFC 9112. + case http1 = 1 + + /// HTTP/2. + /// + /// HTTP/2 is defined in RFC 9113. + case http2 = 2 + + /// HTTP/3. + /// + /// HTTP/3 is defined in RFC 9114 and operates over QUIC. + case http3 = 3 +} diff --git a/Sources/URLSessionHTTPClient/URLSessionHTTPClient.swift b/Sources/URLSessionHTTPClient/URLSessionHTTPClient.swift index 499e462..49cd553 100644 --- a/Sources/URLSessionHTTPClient/URLSessionHTTPClient.swift +++ b/Sources/URLSessionHTTPClient/URLSessionHTTPClient.swift @@ -279,7 +279,7 @@ public final class URLSessionHTTPClient: HTTPClient, IdleTimerEntryProvider { } request.allowsExpensiveNetworkAccess = options.allowsExpensiveNetworkAccess request.allowsConstrainedNetworkAccess = options.allowsConstrainedNetworkAccess - request.assumesHTTP3Capable = options.assumesHTTP3Capable + request.assumesHTTP3Capable = options.serverSupportedHTTPVersions.contains(.http3) if let stallTimeout = options.stallTimeout { request.timeoutInterval = stallTimeout / .seconds(1) } else { diff --git a/Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift b/Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift index b263d88..27a7f5a 100644 --- a/Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift +++ b/Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift @@ -19,7 +19,8 @@ public import NetworkTypes public struct URLSessionRequestOptions: HTTPClientCapability.RedirectionHandler, HTTPClientCapability.TLSSecurityHandler, - HTTPClientCapability.TLSVersionSelection + HTTPClientCapability.TLSVersionSelection, + HTTPClientCapability.ServerHTTPVersionCapability { public var redirectionHandler: (any HTTPClientRedirectionHandler)? = nil @@ -30,7 +31,7 @@ public struct URLSessionRequestOptions: public var maximumTLSVersion: TLSVersion = .v1_3 public var allowsExpensiveNetworkAccess: Bool = true public var allowsConstrainedNetworkAccess: Bool = true - public var assumesHTTP3Capable: Bool = false + public var serverSupportedHTTPVersions: Set = [] public var stallTimeout: Duration? = nil public init() {} From 8a363cffc1436f8c6578c5ad21213650cd46a82b Mon Sep 17 00:00:00 2001 From: Nakul Bajaj Date: Thu, 14 May 2026 07:58:59 -0700 Subject: [PATCH 2/5] Transport version hint instead of HTTP version --- Sources/AHCHTTPClient/AHC+HTTPClient.swift | 4 +-- ...ility+ServerTransportCapabilityHint.swift} | 16 +++++---- Sources/HTTPClient/DefaultHTTPClient.swift | 2 +- Sources/HTTPClient/HTTPRequestOptions.swift | 4 +-- Sources/NetworkTypes/HTTPVersion.swift | 34 ------------------ Sources/NetworkTypes/TransportVersion.swift | 35 +++++++++++++++++++ .../URLSessionHTTPClient.swift | 2 +- .../URLSessionRequestOptions.swift | 4 +-- 8 files changed, 52 insertions(+), 49 deletions(-) rename Sources/HTTPAPIs/Client/{HTTPClientCapability+ServerHTTPVersionCapability.swift => HTTPClientCapability+ServerTransportCapabilityHint.swift} (63%) delete mode 100644 Sources/NetworkTypes/HTTPVersion.swift create mode 100644 Sources/NetworkTypes/TransportVersion.swift diff --git a/Sources/AHCHTTPClient/AHC+HTTPClient.swift b/Sources/AHCHTTPClient/AHC+HTTPClient.swift index 6081afc..186837d 100644 --- a/Sources/AHCHTTPClient/AHC+HTTPClient.swift +++ b/Sources/AHCHTTPClient/AHC+HTTPClient.swift @@ -27,8 +27,8 @@ extension AsyncHTTPClient.HTTPClient: HTTPAPIs.HTTPClient { public typealias RequestWriter = RequestBodyWriter public typealias ResponseConcludingReader = ResponseReader - public struct RequestOptions: HTTPClientCapability.ServerHTTPVersionCapability { - public var serverSupportedHTTPVersions: Set = [] + public struct RequestOptions: HTTPClientCapability.ServerTransportCapabilityHint { + public var serverSupportedTransports: Set = [] } public struct RequestBodyWriter: AsyncWriter, ~Copyable { diff --git a/Sources/HTTPAPIs/Client/HTTPClientCapability+ServerHTTPVersionCapability.swift b/Sources/HTTPAPIs/Client/HTTPClientCapability+ServerTransportCapabilityHint.swift similarity index 63% rename from Sources/HTTPAPIs/Client/HTTPClientCapability+ServerHTTPVersionCapability.swift rename to Sources/HTTPAPIs/Client/HTTPClientCapability+ServerTransportCapabilityHint.swift index 4e40041..39ceddb 100644 --- a/Sources/HTTPAPIs/Client/HTTPClientCapability+ServerHTTPVersionCapability.swift +++ b/Sources/HTTPAPIs/Client/HTTPClientCapability+ServerTransportCapabilityHint.swift @@ -16,16 +16,18 @@ public import NetworkTypes @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) extension HTTPClientCapability { - /// A protocol for HTTP request options that support specifying server HTTP version capabilities. + /// A protocol for HTTP request options that hint at the transports a + /// server is known to support. /// - /// Providing server HTTP version information allows the client to optimize - /// connection establishment. For example, if a server is known to support HTTP/3, - /// the client can attempt a QUIC connection directly. - public protocol ServerHTTPVersionCapability: RequestOptions { - /// The HTTP versions that the target server is known to support. + /// Providing server transport information allows the client to optimize + /// connection establishment. For example, if a server is known to support + /// QUIC, the client can attempt an HTTP/3 connection directly instead of + /// falling back to TCP-based negotiation. + public protocol ServerTransportCapabilityHint: RequestOptions { + /// The transports that the target server is known to support. /// /// An empty set indicates no prior knowledge of server capabilities, /// and the client uses its default protocol negotiation behavior. - var serverSupportedHTTPVersions: Set { get set } + var serverSupportedTransports: Set { get set } } } diff --git a/Sources/HTTPClient/DefaultHTTPClient.swift b/Sources/HTTPClient/DefaultHTTPClient.swift index 2716508..c641a22 100644 --- a/Sources/HTTPClient/DefaultHTTPClient.swift +++ b/Sources/HTTPClient/DefaultHTTPClient.swift @@ -138,7 +138,7 @@ public final class DefaultHTTPClient: HTTPAPIs.HTTPClient { responseHandler: (HTTPResponse, consuming ResponseConcludingReader) async throws -> Return ) async throws -> Return { var translatedOptions = self.client.defaultRequestOptions - translatedOptions.serverSupportedHTTPVersions = options.serverSupportedHTTPVersions + translatedOptions.serverSupportedTransports = options.serverSupportedTransports let body = body.map { HTTPClientRequestBody(other: $0) { RequestWriter(actual: $0) } } diff --git a/Sources/HTTPClient/HTTPRequestOptions.swift b/Sources/HTTPClient/HTTPRequestOptions.swift index 67b2c42..1820460 100644 --- a/Sources/HTTPClient/HTTPRequestOptions.swift +++ b/Sources/HTTPClient/HTTPRequestOptions.swift @@ -14,8 +14,8 @@ public import NetworkTypes /// The options for the default HTTP client implementation. @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) -public struct HTTPRequestOptions: HTTPClientCapability.ServerHTTPVersionCapability { - public var serverSupportedHTTPVersions: Set = [] +public struct HTTPRequestOptions: HTTPClientCapability.ServerTransportCapabilityHint { + public var serverSupportedTransports: Set = [] public init() {} } diff --git a/Sources/NetworkTypes/HTTPVersion.swift b/Sources/NetworkTypes/HTTPVersion.swift deleted file mode 100644 index 1fa16ac..0000000 --- a/Sources/NetworkTypes/HTTPVersion.swift +++ /dev/null @@ -1,34 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift HTTP API Proposal open source project -// -// Copyright (c) 2026 Apple Inc. and the Swift HTTP API Proposal project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift HTTP API Proposal project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -/// An enumeration that represents an HTTP protocol version. -/// -/// ``HTTPVersion`` provides type-safe access to supported HTTP protocol versions, -/// allowing clients and servers to communicate version capabilities. -public enum HTTPVersion: UInt8, Sendable, Hashable { - /// HTTP/1. - /// - /// HTTP/1 is defined in RFC 9112. - case http1 = 1 - - /// HTTP/2. - /// - /// HTTP/2 is defined in RFC 9113. - case http2 = 2 - - /// HTTP/3. - /// - /// HTTP/3 is defined in RFC 9114 and operates over QUIC. - case http3 = 3 -} diff --git a/Sources/NetworkTypes/TransportVersion.swift b/Sources/NetworkTypes/TransportVersion.swift new file mode 100644 index 0000000..66cd035 --- /dev/null +++ b/Sources/NetworkTypes/TransportVersion.swift @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift HTTP API Proposal open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift HTTP API Proposal project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift HTTP API Proposal project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// An enumeration that represents a transport protocol used to carry HTTP +/// traffic. +/// +/// ``TransportVersion`` provides type-safe access to supported transport +/// protocols, allowing clients and servers to communicate transport +/// capabilities. New transports may be added in future releases, so client +/// code must handle unknown cases. +@nonexhaustive +public enum TransportVersion: Sendable, Hashable { + /// Plaintext TCP transport. + case tcp + + /// TCP with TLS transport. + case tcpWithTLS + + /// QUIC transport. + /// + /// QUIC is defined in RFC 9000 and is the transport used by HTTP/3 + /// (RFC 9114). + case quic +} diff --git a/Sources/URLSessionHTTPClient/URLSessionHTTPClient.swift b/Sources/URLSessionHTTPClient/URLSessionHTTPClient.swift index 49cd553..59d945b 100644 --- a/Sources/URLSessionHTTPClient/URLSessionHTTPClient.swift +++ b/Sources/URLSessionHTTPClient/URLSessionHTTPClient.swift @@ -279,7 +279,7 @@ public final class URLSessionHTTPClient: HTTPClient, IdleTimerEntryProvider { } request.allowsExpensiveNetworkAccess = options.allowsExpensiveNetworkAccess request.allowsConstrainedNetworkAccess = options.allowsConstrainedNetworkAccess - request.assumesHTTP3Capable = options.serverSupportedHTTPVersions.contains(.http3) + request.assumesHTTP3Capable = options.serverSupportedTransports.contains(.quic) if let stallTimeout = options.stallTimeout { request.timeoutInterval = stallTimeout / .seconds(1) } else { diff --git a/Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift b/Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift index 27a7f5a..ddd8d9e 100644 --- a/Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift +++ b/Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift @@ -20,7 +20,7 @@ public struct URLSessionRequestOptions: HTTPClientCapability.RedirectionHandler, HTTPClientCapability.TLSSecurityHandler, HTTPClientCapability.TLSVersionSelection, - HTTPClientCapability.ServerHTTPVersionCapability + HTTPClientCapability.ServerTransportCapabilityHint { public var redirectionHandler: (any HTTPClientRedirectionHandler)? = nil @@ -31,7 +31,7 @@ public struct URLSessionRequestOptions: public var maximumTLSVersion: TLSVersion = .v1_3 public var allowsExpensiveNetworkAccess: Bool = true public var allowsConstrainedNetworkAccess: Bool = true - public var serverSupportedHTTPVersions: Set = [] + public var serverSupportedTransports: Set = [] public var stallTimeout: Duration? = nil public init() {} From dc104927e6e93a0077ce7fb0c249b78f05c7813b Mon Sep 17 00:00:00 2001 From: Nakul Bajaj Date: Thu, 14 May 2026 08:06:33 -0700 Subject: [PATCH 3/5] format fixes --- Sources/AHCHTTPClient/AHC+HTTPClient.swift | 3 +-- .../HTTPClientCapability+ServerTransportCapabilityHint.swift | 1 - Sources/NetworkTypes/TransportVersion.swift | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Sources/AHCHTTPClient/AHC+HTTPClient.swift b/Sources/AHCHTTPClient/AHC+HTTPClient.swift index 186837d..f032350 100644 --- a/Sources/AHCHTTPClient/AHC+HTTPClient.swift +++ b/Sources/AHCHTTPClient/AHC+HTTPClient.swift @@ -11,8 +11,6 @@ // //===----------------------------------------------------------------------===// -public import NetworkTypes - @_spi(ExperimentalHTTPAPIsSupport) public import AsyncHTTPClient import BasicContainers import Foundation @@ -20,6 +18,7 @@ import Foundation import HTTPTypes import NIOCore import NIOHTTP1 +public import NetworkTypes import Synchronization @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, *) diff --git a/Sources/HTTPAPIs/Client/HTTPClientCapability+ServerTransportCapabilityHint.swift b/Sources/HTTPAPIs/Client/HTTPClientCapability+ServerTransportCapabilityHint.swift index 39ceddb..4103eef 100644 --- a/Sources/HTTPAPIs/Client/HTTPClientCapability+ServerTransportCapabilityHint.swift +++ b/Sources/HTTPAPIs/Client/HTTPClientCapability+ServerTransportCapabilityHint.swift @@ -6,7 +6,6 @@ // Licensed under Apache License v2.0 // // See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift HTTP API Proposal project authors // // SPDX-License-Identifier: Apache-2.0 // diff --git a/Sources/NetworkTypes/TransportVersion.swift b/Sources/NetworkTypes/TransportVersion.swift index 66cd035..ebf1d1b 100644 --- a/Sources/NetworkTypes/TransportVersion.swift +++ b/Sources/NetworkTypes/TransportVersion.swift @@ -6,7 +6,6 @@ // Licensed under Apache License v2.0 // // See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift HTTP API Proposal project authors // // SPDX-License-Identifier: Apache-2.0 // From 0fed93e5ec4d21ed0deefa1cf5f34a2c3c0b6c86 Mon Sep 17 00:00:00 2001 From: Nakul Bajaj Date: Mon, 18 May 2026 10:40:19 -0700 Subject: [PATCH 4/5] addressing feedback (renaming protocol + property) --- Sources/AHCHTTPClient/AHC+HTTPClient.swift | 4 ++-- ...> HTTPClientCapability+ServerTransportHint.swift} | 4 ++-- Sources/HTTPClient/DefaultHTTPClient.swift | 2 +- Sources/HTTPClient/HTTPRequestOptions.swift | 4 ++-- ...sportVersion.swift => HTTPTransportVersion.swift} | 12 ++++++------ .../URLSessionHTTPClient/URLSessionHTTPClient.swift | 2 +- .../URLSessionRequestOptions.swift | 4 ++-- 7 files changed, 16 insertions(+), 16 deletions(-) rename Sources/HTTPAPIs/Client/{HTTPClientCapability+ServerTransportCapabilityHint.swift => HTTPClientCapability+ServerTransportHint.swift} (89%) rename Sources/NetworkTypes/{TransportVersion.swift => HTTPTransportVersion.swift} (76%) diff --git a/Sources/AHCHTTPClient/AHC+HTTPClient.swift b/Sources/AHCHTTPClient/AHC+HTTPClient.swift index f032350..d37a4a3 100644 --- a/Sources/AHCHTTPClient/AHC+HTTPClient.swift +++ b/Sources/AHCHTTPClient/AHC+HTTPClient.swift @@ -26,8 +26,8 @@ extension AsyncHTTPClient.HTTPClient: HTTPAPIs.HTTPClient { public typealias RequestWriter = RequestBodyWriter public typealias ResponseConcludingReader = ResponseReader - public struct RequestOptions: HTTPClientCapability.ServerTransportCapabilityHint { - public var serverSupportedTransports: Set = [] + public struct RequestOptions: HTTPClientCapability.ServerTransportHint { + public var serverSupportedTransportsHint: Set = [] } public struct RequestBodyWriter: AsyncWriter, ~Copyable { diff --git a/Sources/HTTPAPIs/Client/HTTPClientCapability+ServerTransportCapabilityHint.swift b/Sources/HTTPAPIs/Client/HTTPClientCapability+ServerTransportHint.swift similarity index 89% rename from Sources/HTTPAPIs/Client/HTTPClientCapability+ServerTransportCapabilityHint.swift rename to Sources/HTTPAPIs/Client/HTTPClientCapability+ServerTransportHint.swift index 4103eef..76b1552 100644 --- a/Sources/HTTPAPIs/Client/HTTPClientCapability+ServerTransportCapabilityHint.swift +++ b/Sources/HTTPAPIs/Client/HTTPClientCapability+ServerTransportHint.swift @@ -22,11 +22,11 @@ extension HTTPClientCapability { /// connection establishment. For example, if a server is known to support /// QUIC, the client can attempt an HTTP/3 connection directly instead of /// falling back to TCP-based negotiation. - public protocol ServerTransportCapabilityHint: RequestOptions { + public protocol ServerTransportHint: RequestOptions { /// The transports that the target server is known to support. /// /// An empty set indicates no prior knowledge of server capabilities, /// and the client uses its default protocol negotiation behavior. - var serverSupportedTransports: Set { get set } + var serverSupportedTransportsHint: Set { get set } } } diff --git a/Sources/HTTPClient/DefaultHTTPClient.swift b/Sources/HTTPClient/DefaultHTTPClient.swift index c641a22..063ac56 100644 --- a/Sources/HTTPClient/DefaultHTTPClient.swift +++ b/Sources/HTTPClient/DefaultHTTPClient.swift @@ -138,7 +138,7 @@ public final class DefaultHTTPClient: HTTPAPIs.HTTPClient { responseHandler: (HTTPResponse, consuming ResponseConcludingReader) async throws -> Return ) async throws -> Return { var translatedOptions = self.client.defaultRequestOptions - translatedOptions.serverSupportedTransports = options.serverSupportedTransports + translatedOptions.serverSupportedTransportsHint = options.serverSupportedTransportsHint let body = body.map { HTTPClientRequestBody(other: $0) { RequestWriter(actual: $0) } } diff --git a/Sources/HTTPClient/HTTPRequestOptions.swift b/Sources/HTTPClient/HTTPRequestOptions.swift index 1820460..5ca9cc8 100644 --- a/Sources/HTTPClient/HTTPRequestOptions.swift +++ b/Sources/HTTPClient/HTTPRequestOptions.swift @@ -14,8 +14,8 @@ public import NetworkTypes /// The options for the default HTTP client implementation. @available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *) -public struct HTTPRequestOptions: HTTPClientCapability.ServerTransportCapabilityHint { - public var serverSupportedTransports: Set = [] +public struct HTTPRequestOptions: HTTPClientCapability.ServerTransportHint { + public var serverSupportedTransportsHint: Set = [] public init() {} } diff --git a/Sources/NetworkTypes/TransportVersion.swift b/Sources/NetworkTypes/HTTPTransportVersion.swift similarity index 76% rename from Sources/NetworkTypes/TransportVersion.swift rename to Sources/NetworkTypes/HTTPTransportVersion.swift index ebf1d1b..8233669 100644 --- a/Sources/NetworkTypes/TransportVersion.swift +++ b/Sources/NetworkTypes/HTTPTransportVersion.swift @@ -14,18 +14,18 @@ /// An enumeration that represents a transport protocol used to carry HTTP /// traffic. /// -/// ``TransportVersion`` provides type-safe access to supported transport +/// ``HTTPTransportVersion`` provides type-safe access to supported transport /// protocols, allowing clients and servers to communicate transport /// capabilities. New transports may be added in future releases, so client /// code must handle unknown cases. @nonexhaustive -public enum TransportVersion: Sendable, Hashable { - /// Plaintext TCP transport. +public enum HTTPTransportVersion: Sendable, Hashable { + /// TCP transport. + /// + /// Whether TLS is layered on top is determined by the request's URL + /// scheme (`http` vs. `https`). case tcp - /// TCP with TLS transport. - case tcpWithTLS - /// QUIC transport. /// /// QUIC is defined in RFC 9000 and is the transport used by HTTP/3 diff --git a/Sources/URLSessionHTTPClient/URLSessionHTTPClient.swift b/Sources/URLSessionHTTPClient/URLSessionHTTPClient.swift index 59d945b..bda4a70 100644 --- a/Sources/URLSessionHTTPClient/URLSessionHTTPClient.swift +++ b/Sources/URLSessionHTTPClient/URLSessionHTTPClient.swift @@ -279,7 +279,7 @@ public final class URLSessionHTTPClient: HTTPClient, IdleTimerEntryProvider { } request.allowsExpensiveNetworkAccess = options.allowsExpensiveNetworkAccess request.allowsConstrainedNetworkAccess = options.allowsConstrainedNetworkAccess - request.assumesHTTP3Capable = options.serverSupportedTransports.contains(.quic) + request.assumesHTTP3Capable = options.serverSupportedTransportsHint.contains(.quic) if let stallTimeout = options.stallTimeout { request.timeoutInterval = stallTimeout / .seconds(1) } else { diff --git a/Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift b/Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift index ddd8d9e..0986ee5 100644 --- a/Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift +++ b/Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift @@ -20,7 +20,7 @@ public struct URLSessionRequestOptions: HTTPClientCapability.RedirectionHandler, HTTPClientCapability.TLSSecurityHandler, HTTPClientCapability.TLSVersionSelection, - HTTPClientCapability.ServerTransportCapabilityHint + HTTPClientCapability.ServerTransportHint { public var redirectionHandler: (any HTTPClientRedirectionHandler)? = nil @@ -31,7 +31,7 @@ public struct URLSessionRequestOptions: public var maximumTLSVersion: TLSVersion = .v1_3 public var allowsExpensiveNetworkAccess: Bool = true public var allowsConstrainedNetworkAccess: Bool = true - public var serverSupportedTransports: Set = [] + public var serverSupportedTransportsHint: Set = [] public var stallTimeout: Duration? = nil public init() {} From 535c406c44133ac69387c1bd64cd62527ec54fc3 Mon Sep 17 00:00:00 2001 From: Nakul Bajaj Date: Mon, 18 May 2026 15:47:18 -0700 Subject: [PATCH 5/5] add TCP as default for URLSession serverSupportedTransportsHint --- Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift b/Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift index 0986ee5..c0305c9 100644 --- a/Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift +++ b/Sources/URLSessionHTTPClient/URLSessionRequestOptions.swift @@ -31,7 +31,7 @@ public struct URLSessionRequestOptions: public var maximumTLSVersion: TLSVersion = .v1_3 public var allowsExpensiveNetworkAccess: Bool = true public var allowsConstrainedNetworkAccess: Bool = true - public var serverSupportedTransportsHint: Set = [] + public var serverSupportedTransportsHint: Set = [.tcp] public var stallTimeout: Duration? = nil public init() {}