From 34207468898d34be15d6a14a103b8595d3d01367 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Sat, 20 Jul 2024 14:56:26 -0700 Subject: [PATCH] Add default implementations for three default protocol conformances in the URLSessionDelegate family Implementing these callbacks without calling the completion handler causes hangs in cases where these methods are called. Add reasonable default behaviors for all of them, to prevent this. This issue has been in place for at least 8 years for one of these callbacks. --- .../URLSession/URLSessionDelegate.swift | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/Sources/FoundationNetworking/URLSession/URLSessionDelegate.swift b/Sources/FoundationNetworking/URLSession/URLSessionDelegate.swift index 8ec0729968..d9ef60de98 100644 --- a/Sources/FoundationNetworking/URLSession/URLSessionDelegate.swift +++ b/Sources/FoundationNetworking/URLSession/URLSessionDelegate.swift @@ -76,7 +76,9 @@ public protocol URLSessionDelegate : NSObjectProtocol, Sendable { extension URLSessionDelegate { public func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) { } - public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @Sendable @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { } + public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @Sendable @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + completionHandler(.performDefaultHandling, nil) + } } /* If an application has received an @@ -244,7 +246,13 @@ public protocol URLSessionDataDelegate : URLSessionTaskDelegate { extension URLSessionDataDelegate { - public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @Sendable @escaping (URLSession.ResponseDisposition) -> Void) { } + public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @Sendable @escaping (URLSession.ResponseDisposition) -> Void) { + if self === dataTask.delegate, let sessionDelegate = session.delegate as? URLSessionDataDelegate, self !== sessionDelegate { + sessionDelegate.urlSession(session, dataTask: dataTask, didReceive: response, completionHandler: completionHandler) + } else { + completionHandler(.allow) + } + } public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didBecome downloadTask: URLSessionDownloadTask) { } @@ -252,7 +260,13 @@ extension URLSessionDataDelegate { public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { } - public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, willCacheResponse proposedResponse: CachedURLResponse, completionHandler: @Sendable @escaping (CachedURLResponse?) -> Void) { } + public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, willCacheResponse proposedResponse: CachedURLResponse, completionHandler: @Sendable @escaping (CachedURLResponse?) -> Void) { + if self === dataTask.delegate, let sessionDelegate = session.delegate as? URLSessionDataDelegate, self !== sessionDelegate { + sessionDelegate.urlSession(session, dataTask: dataTask, willCacheResponse: proposedResponse, completionHandler: completionHandler) + } else { + completionHandler(proposedResponse) + } + } } /*