Summary
A forced unwrap of the location parameter in the internal completion handler causes a crash, because it is nil when driven by a custom URLProtocol because there's no way for custom protocols to provide the file location that URLSession is demanding.
Environment
- OS: Linux (Debian GNU/Linux rodete)
- Swift version: 6.2.4
Root Cause
855: let completionHandler: URLSession._TaskRegistry.DownloadTaskCompletion = { location, response, error in
856: if let error = error {
857: continuation.resume(throwing: error)
858: } else {
859: continuation.resume(returning: (location!, response!)) // <-- BAD
860: }
861: }
When using a custom URLProtocol, there's no way to specify location, because it comes from an internal property:
let temporaryFileURL = urlProtocol.properties[URLProtocol._PropertyKey.temporaryFileURL] as! URL
…which is private within Foundation:
extension URLProtocol {
enum _PropertyKey: String, Sendable {
case responseData
case temporaryFileURL
}
}
Fix
Make the temporaryFileURL property key public, or remove the implicit requirement that it be used by URLProtocol subclasses.
In the interim, it would be nice if FoundationNetworking didn't crash - it could remove those forced unwraps. e.g.:
--- a/Sources/FoundationNetworking/URLSession/URLSession.swift
+++ b/Sources/FoundationNetworking/URLSession/URLSession.swift
@@ -855,3 +855,10 @@
let completionHandler: URLSession._TaskRegistry.DownloadTaskCompletion = { location, response, error in
if let error = error {
continuation.resume(throwing: error)
} else {
- continuation.resume(returning: (location!, response!))
+ guard let location = location, let response = response else {
+ let urlError = URLError(_nsError: NSError(domain: NSURLErrorDomain, code: NSURLErrorUnknown, userInfo: [NSLocalizedDescriptionKey: "Internal error: download task completed but temporary file location was missing."]))
+ continuation.resume(throwing: urlError)
+ return
+ }
+ continuation.resume(returning: (location, response))
}
Summary
A forced unwrap of the
locationparameter in the internal completion handler causes a crash, because it isnilwhen driven by a customURLProtocolbecause there's no way for custom protocols to provide the file location thatURLSessionis demanding.Environment
Root Cause
When using a custom
URLProtocol, there's no way to specifylocation, because it comes from an internal property:…which is private within Foundation:
Fix
Make the
temporaryFileURLproperty key public, or remove the implicit requirement that it be used byURLProtocolsubclasses.In the interim, it would be nice if FoundationNetworking didn't crash - it could remove those forced unwraps. e.g.: