Merge pull request #1203 from johnno1962e/swift-4.0-branch
diff --git a/Foundation/URLSession/URLSessionTask.swift b/Foundation/URLSession/URLSessionTask.swift
index 1115ef5..7dcc66e 100644
--- a/Foundation/URLSession/URLSessionTask.swift
+++ b/Foundation/URLSession/URLSessionTask.swift
@@ -29,8 +29,8 @@
internal var suspendCount = 1
internal var session: URLSessionProtocol! //change to nil when task completes
internal let body: _Body
- fileprivate var _protocol: URLProtocol! = nil
-
+ fileprivate var _protocol: URLProtocol? = nil
+
/// All operations must run on this queue.
internal let workQueue: DispatchQueue
/// Using dispatch semaphore to make public attributes thread safe.
@@ -200,8 +200,8 @@
self.workQueue.async {
let urlError = URLError(_nsError: NSError(domain: NSURLErrorDomain, code: NSURLErrorCancelled, userInfo: nil))
self.error = urlError
- self._protocol.stopLoading()
- self._protocol.client?.urlProtocol(self._protocol, didFailWithError: urlError)
+ self._protocol?.stopLoading()
+ self._protocol?.client?.urlProtocol(self._protocol!, didFailWithError: urlError)
}
}
}
@@ -263,7 +263,7 @@
if self.suspendCount == 1 {
self.workQueue.async {
- self._protocol.stopLoading()
+ self._protocol?.stopLoading()
}
}
}
@@ -278,7 +278,21 @@
self.updateTaskState()
if self.suspendCount == 0 {
self.workQueue.async {
- self._protocol.startLoading()
+ if let _protocol = self._protocol {
+ _protocol.startLoading()
+ }
+ else if self.error == nil {
+ var userInfo: [String: Any] = [NSLocalizedDescriptionKey: "unsupported URL"]
+ if let url = self.originalRequest?.url {
+ userInfo[NSURLErrorFailingURLErrorKey] = url
+ userInfo[NSURLErrorFailingURLStringErrorKey] = url.absoluteString
+ }
+ let urlError = URLError(_nsError: NSError(domain: NSURLErrorDomain,
+ code: NSURLErrorUnsupportedURL,
+ userInfo: userInfo))
+ self.error = urlError
+ _ProtocolClient().urlProtocol(task: self, didFailWithError: urlError)
+ }
}
}
}
@@ -573,6 +587,7 @@
session.taskRegistry.remove(task)
}
}
+ task._protocol = nil
}
func urlProtocol(_ protocol: URLProtocol, didCancel challenge: URLAuthenticationChallenge) {
@@ -600,6 +615,10 @@
func urlProtocol(_ protocol: URLProtocol, didFailWithError error: Error) {
guard let task = `protocol`.task else { fatalError() }
+ urlProtocol(task: task, didFailWithError: error)
+ }
+
+ func urlProtocol(task: URLSessionTask, didFailWithError error: Error) {
guard let session = task.session as? URLSession else { fatalError() }
switch session.behaviour(for: task) {
case .taskDelegate(let delegate):
@@ -624,6 +643,7 @@
session.taskRegistry.remove(task)
}
}
+ task._protocol = nil
}
func urlProtocol(_ protocol: URLProtocol, cachedResponseIsValid cachedResponse: CachedURLResponse) {
diff --git a/Foundation/URLSession/http/HTTPURLProtocol.swift b/Foundation/URLSession/http/HTTPURLProtocol.swift
index 307a64f..78aff84 100644
--- a/Foundation/URLSession/http/HTTPURLProtocol.swift
+++ b/Foundation/URLSession/http/HTTPURLProtocol.swift
@@ -13,13 +13,14 @@
internal class _HTTPURLProtocol: URLProtocol {
fileprivate var easyHandle: _EasyHandle!
- fileprivate var tempFileURL: URL
+ fileprivate lazy var tempFileURL: URL = {
+ let fileName = NSTemporaryDirectory() + NSUUID().uuidString + ".tmp"
+ _ = FileManager.default.createFile(atPath: fileName, contents: nil)
+ return URL(fileURLWithPath: fileName)
+ }()
public required init(task: URLSessionTask, cachedResponse: CachedURLResponse?, client: URLProtocolClient?) {
self.internalState = _InternalState.initial
- let fileName = NSTemporaryDirectory() + NSUUID().uuidString + ".tmp"
- _ = FileManager.default.createFile(atPath: fileName, contents: nil)
- self.tempFileURL = URL(fileURLWithPath: fileName)
super.init(request: task.originalRequest!, cachedResponse: cachedResponse, client: client)
self.task = task
self.easyHandle = _EasyHandle(delegate: self)
@@ -27,9 +28,6 @@
public required init(request: URLRequest, cachedResponse: CachedURLResponse?, client: URLProtocolClient?) {
self.internalState = _InternalState.initial
- let fileName = NSTemporaryDirectory() + NSUUID().uuidString + ".tmp"
- _ = FileManager.default.createFile(atPath: fileName, contents: nil)
- self.tempFileURL = URL(fileURLWithPath: fileName)
super.init(request: request, cachedResponse: cachedResponse, client: client)
self.easyHandle = _EasyHandle(delegate: self)
}