From 5e5be776766d0a9eb4808e84c870685118954a21 Mon Sep 17 00:00:00 2001 From: Lily Vulcano Date: Thu, 23 May 2019 12:29:30 -0700 Subject: [PATCH] =?UTF-8?q?Parity:=20URLSession.reset(=E2=80=A6)/.flush(?= =?UTF-8?q?=E2=80=A6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement reset(…) and flush(…) per their contracts. Note that URLCredentialStorage is unimplemented right now; invoking reset(…) will thus crash if a credentials storage is set. Ensure that URLSessionConfiguration users do not attempt to use init(), leading to non-portable code. --- Foundation/URLSession/URLSession.swift | 26 +++++++++++++++-- .../URLSession/URLSessionConfiguration.swift | 29 +++++++++++++++++-- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/Foundation/URLSession/URLSession.swift b/Foundation/URLSession/URLSession.swift index e75a2f80b3..7b14c457db 100644 --- a/Foundation/URLSession/URLSession.swift +++ b/Foundation/URLSession/URLSession.swift @@ -346,9 +346,31 @@ open class URLSession : NSObject { } } - open func reset(completionHandler: @escaping () -> Void) { NSUnimplemented() } /* empty all cookies, cache and credential stores, removes disk files, issues -flushWithCompletionHandler:. Invokes completionHandler() on the delegate queue if not nil. */ + /* empty all cookies, cache and credential stores, removes disk files, issues -flushWithCompletionHandler:. Invokes completionHandler() on the delegate queue. */ + open func reset(completionHandler: @escaping () -> Void) { + let configuration = self.configuration + + DispatchQueue.global(qos: .background).async { + configuration.urlCache?.removeAllCachedResponses() + if let storage = configuration.urlCredentialStorage { + for credentialEntry in storage.allCredentials { + for credential in credentialEntry.value { + storage.remove(credential.value, for: credentialEntry.key) + } + } + } + + self.flush(completionHandler: completionHandler) + } + } - open func flush(completionHandler: @escaping () -> Void) { NSUnimplemented() }/* flush storage to disk and clear transient network caches. Invokes completionHandler() on the delegate queue if not nil. */ + /* flush storage to disk and clear transient network caches. Invokes completionHandler() on the delegate queue. */ + open func flush(completionHandler: @escaping () -> Void) { + // We create new CURL handles every request. + delegateQueue.addOperation { + completionHandler() + } + } /* invokes completionHandler with outstanding data, upload and download tasks. */ open func getTasksWithCompletionHandler(completionHandler: @escaping ([URLSessionDataTask], [URLSessionUploadTask], [URLSessionDownloadTask]) -> Void) { diff --git a/Foundation/URLSession/URLSessionConfiguration.swift b/Foundation/URLSession/URLSessionConfiguration.swift index 46c9bafdc3..9ce89de4c6 100644 --- a/Foundation/URLSession/URLSessionConfiguration.swift +++ b/Foundation/URLSession/URLSessionConfiguration.swift @@ -36,6 +36,8 @@ import Foundation /// A background session can be used to perform networking operations /// on behalf of a suspended application, within certain constraints. open class URLSessionConfiguration : NSObject, NSCopying { + // -init is silently incorrect in URLSessionCofiguration on the desktop. Ensure code that relied on swift-corelibs-foundation's init() being functional is redirected to the appropriate cross-platform class property. + @available(*, deprecated, message: "Use .default instead.", renamed: "URLSessionConfiguration.default") public override init() { self.requestCachePolicy = .useProtocolCachePolicy self.timeoutIntervalForRequest = 60 @@ -55,6 +57,27 @@ open class URLSessionConfiguration : NSObject, NSCopying { super.init() } + internal convenience init(correctly: ()) { + self.init(identifier: nil, + requestCachePolicy: .useProtocolCachePolicy, + timeoutIntervalForRequest: 60, + timeoutIntervalForResource: 604800, + networkServiceType: .default, + allowsCellularAccess: true, + isDiscretionary: false, + connectionProxyDictionary: nil, + httpShouldUsePipelining: false, + httpShouldSetCookies: true, + httpCookieAcceptPolicy: .onlyFromMainDocumentDomain, + httpAdditionalHeaders: nil, + httpMaximumConnectionsPerHost: 6, + httpCookieStorage: .shared, + urlCredentialStorage: nil, // Should be .shared once implemented. + urlCache: nil, + shouldUseExtendedBackgroundIdleMode: false, + protocolClasses: [_HTTPURLProtocol.self, _FTPURLProtocol.self]) + } + private init(identifier: String?, requestCachePolicy: URLRequest.CachePolicy, timeoutIntervalForRequest: TimeInterval, @@ -121,15 +144,15 @@ open class URLSessionConfiguration : NSObject, NSCopying { } open class var `default`: URLSessionConfiguration { - return URLSessionConfiguration() + return URLSessionConfiguration(correctly: ()) } open class var ephemeral: URLSessionConfiguration { // Return a new ephemeral URLSessionConfiguration every time this property is invoked // TODO: urlCache and urlCredentialStorage should also be ephemeral/in-memory // URLCache and URLCredentialStorage are still unimplemented - let ephemeralConfiguration = URLSessionConfiguration() - ephemeralConfiguration.httpCookieStorage = HTTPCookieStorage.ephemeralStorage() + let ephemeralConfiguration = URLSessionConfiguration.default.copy() as! URLSessionConfiguration + ephemeralConfiguration.httpCookieStorage = .ephemeralStorage() return ephemeralConfiguration }