diff --git a/Proposals/0018-urlsession-new-loader.md b/Proposals/0018-urlsession-new-loader.md new file mode 100644 index 000000000..852c9e75c --- /dev/null +++ b/Proposals/0018-urlsession-new-loader.md @@ -0,0 +1,111 @@ +# New HTTP loader for URLSession + +* Proposal: [SF-0018](0018-urlsession-new-loader.md) +* Authors: [Guoye Zhang](https://github.com/guoye-zhang) +* Review Manager: [Tina L](https://github.com/itingliu) +* Status: **Accepted** +* Implementation: [swiftlang/swift-corelibs-foundation#5162](https://github.com/swiftlang/swift-corelibs-foundation/pull/5162) +* Review: ([pitch](https://forums.swift.org/t/pitch-new-http-loader-for-urlsession-on-darwin/77440)) + +## 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. + +```swift +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 with `NSURLErrorFailingURLErrorKey` and it is incompatible with WHATWG URLs. +* `shouldUseExtendedBackgroundIdleMode` was not supported in either the old stack or the new stack. + +```swift +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.