# 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.
