Hi all, I'd like to share a proposal about the new HTTP loader for URLSession on Darwin. The API is not currently available non-Darwin platforms. Please check out the details below.
New HTTP loader for URLSession
- Proposal: SF-NNNN
- Authors: Guoye Zhang
- Review Manager: TBD
- Status: Pitch
- Implementation: swiftlang/swift-corelibs-foundation#5162
Introduction
The new HTTP stack built in Network framework was enabled in Safari on iOS 18 and macOS Sequoia. It supports new features like 0-RTT early data, oblivious HTTP, WebSocket over HTTP/2, and unix domain socket. Support for FTP and HTTP/1 pipelining was dropped.
In this proposal, we are introducing an API to enable the new HTTP loader in URLSession on Darwin, as well as deprecating several legacy features not supported in the new stack.
Proposed solution
Introducing a new flag usesClassicLoadingMode
that defaults to true on URLSessionConfiguration to allow developers to opt-in to the new stack.
The flag is not available on non-Darwin platforms at this moment.
Detailed design
Opt-in flag
The new loader is enabled when usesClassicLoadingMode
is set to false. usesClassicLoadingMode
currently defaults to true, but might default to false in a future OS.
open class URLSessionConfiguration {
/* Uses the classic network loader */
@available(*, unavailable, message: "Not available on non-Darwin platforms")
open var usesClassicLoadingMode: Bool
}
Deprecations
- FTP was deprecated in the old stack and unsupported in the new stack.
- HTTP/1 pipelining is not supported in the new HTTP stack. It is disabled by default in the old stack and has known compatibility issues with some servers.
- Server push was disabled in both stacks on iOS 17 and aligned releases due to low adoption and web compatibility issues.
NSURLErrorFailingURLStringErrorKey
is redundant withNSURLErrorFailingURLErrorKey
and it is incompatible with WHATWG URLs.shouldUseExtendedBackgroundIdleMode
was not supported in either the old stack or the new stack.
public struct URLRequest {
@available(swift, deprecated: 6.1, message: "HTTP/1 pipelining has known compatibility issues, please adopt HTTP/2 and HTTP/3 instead")
public var httpShouldUsePipelining: Bool
}
open class NSURLRequest {
@available(swift, deprecated: 6.1, message: "HTTP/1 pipelining has known compatibility issues, please adopt HTTP/2 and HTTP/3 instead")
open var httpShouldUsePipelining: Bool { get }
}
open class NSMutableURLRequest {
@available(swift, deprecated: 6.1, message: "HTTP/1 pipelining has known compatibility issues, please adopt HTTP/2 and HTTP/3 instead")
open override var httpShouldUsePipelining: Bool
}
open class URLSessionConfiguration {
@available(swift, deprecated: 6.1, message: "HTTP/1 pipelining has known compatibility issues, please adopt HTTP/2 and HTTP/3 instead")
open var httpShouldUsePipelining: Bool
@available(swift, deprecated: 6.1, message: "Not supported")
open var shouldUseExtendedBackgroundIdleMode: Bool
}
public enum URLSessionTaskMetrics.ResourceFetchType {
@available(swift, deprecated: 6.1, message: "Server push is not supported")
case serverPush
}
public struct URLError {
@available(swift, deprecated: 6.1, message: "Use failingURL instead")
public var failureURLString: String?
}
@available(swift, deprecated: 6.1, message: "Use NSURLErrorFailingURLErrorKey instead")
public let NSURLErrorFailingURLStringErrorKey: String
@available(swift, deprecated: 6.1, message: "FTP is deprecated")
public let NSURLProtectionSpaceFTP: String
@available(swift, deprecated: 6.1, message: "FTP is deprecated")
public let NSURLProtectionSpaceFTPProxy: String
Source compatibility
No impact.
Implications on adoption
This feature can be freely adopted and un-adopted in source code with no deployment constraints and without affecting source compatibility.
Future directions
The new HTTP stack might become the default on a future Darwin release.
Alternatives considered
Alternative spelling usesNewLoader
The initial idea was an opt-in flag where YES means the new loader, and we considered multiple variants, including usesModernLoader
, usesNWLoader
(NW stands for Network framework). However, this makes it hard to come up with names for newer loaders in the future, and an opt-out flag gives the impression that the new loader is the default, not the exception.