@@ -33,7 +33,7 @@ open class URLSessionTask : NSObject, NSCopying {
33
33
internal var suspendCount = 1
34
34
internal var session : URLSessionProtocol ! //change to nil when task completes
35
35
internal let body : _Body
36
- fileprivate var _protocol : URLProtocol ! = nil
36
+ fileprivate var _protocol : URLProtocol ? = nil
37
37
private let syncQ = DispatchQueue ( label: " org.swift.URLSessionTask.SyncQ " )
38
38
39
39
/// All operations must run on this queue.
@@ -178,8 +178,8 @@ open class URLSessionTask : NSObject, NSCopying {
178
178
self . workQueue. async {
179
179
let urlError = URLError ( _nsError: NSError ( domain: NSURLErrorDomain, code: NSURLErrorCancelled, userInfo: nil ) )
180
180
self . error = urlError
181
- self . _protocol. stopLoading ( )
182
- self . _protocol. client? . urlProtocol ( self . _protocol, didFailWithError: urlError)
181
+ self . _protocol? . stopLoading ( )
182
+ self . _protocol? . client? . urlProtocol ( self . _protocol! , didFailWithError: urlError)
183
183
}
184
184
}
185
185
}
@@ -235,7 +235,7 @@ open class URLSessionTask : NSObject, NSCopying {
235
235
236
236
if self . suspendCount == 1 {
237
237
self . workQueue. async {
238
- self . _protocol. stopLoading ( )
238
+ self . _protocol? . stopLoading ( )
239
239
}
240
240
}
241
241
}
@@ -250,7 +250,21 @@ open class URLSessionTask : NSObject, NSCopying {
250
250
self . updateTaskState ( )
251
251
if self . suspendCount == 0 {
252
252
self . workQueue. async {
253
- self . _protocol. startLoading ( )
253
+ if let _protocol = self . _protocol {
254
+ _protocol. startLoading ( )
255
+ }
256
+ else if self . error == nil {
257
+ var userInfo : [ String : Any ] = [ NSLocalizedDescriptionKey: " unsupported URL " ]
258
+ if let url = self . originalRequest? . url {
259
+ userInfo [ NSURLErrorFailingURLErrorKey] = url
260
+ userInfo [ NSURLErrorFailingURLStringErrorKey] = url. absoluteString
261
+ }
262
+ let urlError = URLError ( _nsError: NSError ( domain: NSURLErrorDomain,
263
+ code: NSURLErrorUnsupportedURL,
264
+ userInfo: userInfo) )
265
+ self . error = urlError
266
+ _ProtocolClient ( ) . urlProtocol ( task: self , didFailWithError: urlError)
267
+ }
254
268
}
255
269
}
256
270
}
@@ -547,6 +561,7 @@ extension _ProtocolClient : URLProtocolClient {
547
561
session. taskRegistry. remove ( task)
548
562
}
549
563
}
564
+ task. _protocol = nil
550
565
}
551
566
552
567
func urlProtocol( _ protocol: URLProtocol , didCancel challenge: URLAuthenticationChallenge ) {
@@ -574,6 +589,10 @@ extension _ProtocolClient : URLProtocolClient {
574
589
575
590
func urlProtocol( _ protocol: URLProtocol , didFailWithError error: Error ) {
576
591
guard let task = `protocol`. task else { fatalError ( ) }
592
+ urlProtocol ( task: task, didFailWithError: error)
593
+ }
594
+
595
+ func urlProtocol( task: URLSessionTask , didFailWithError error: Error ) {
577
596
guard let session = task. session as? URLSession else { fatalError ( ) }
578
597
switch session. behaviour ( for: task) {
579
598
case . taskDelegate( let delegate) :
@@ -602,6 +621,7 @@ extension _ProtocolClient : URLProtocolClient {
602
621
session. taskRegistry. remove ( task)
603
622
}
604
623
}
624
+ task. _protocol = nil
605
625
}
606
626
607
627
func urlProtocol( _ protocol: URLProtocol , cachedResponseIsValid cachedResponse: CachedURLResponse ) {
0 commit comments