Skip to content

Commit e7a517e

Browse files
Pushkar N Kulkarnifinestructure
Pushkar N Kulkarni
authored andcommitted
Don't fail a URLSessionTask on a 401 response
The basic authentication implementation fails a URLSessionTask with an error if a status code of 401 is received but we aren't able to build a URLProtectionSpace, possibly due to the absence of a the WWW-Authenticate response header. A valid HTTP response object is received in this case. It may not possible to go ahead with the `urlSession(_,task: task, didReceive:)` callback, either because a delegate isn't being used or because the `WWW-Authenticate` response header is absent. In such cases, the completion handler is invoked with the received response, NOT with an error. Note that basic authentication (swiftlang@4c1e8c4271c4e21000528 d3910f20a958d03f308#diff-14c6cb724eead661596e4468ae5ca638) wasn't available with Swift 4.x. It was first made available in development builds for Swift 5. Initially, when we failed to build a URLProtectionSpace, we failed with an error, which resulted in removing the task from the TaskRegistry. Further we went ahead and invoked the completion handler, which again tried to remove the same task from the TaskRegistry, resulting in a fatal error reported against Swift 5.0. As a fix to this, we decided to simply return after failing with an error (see swiftlang@69abd6dd396e1985a882a9 a39079801f84658fb3#diff-14c6cb724eead661596e4468ae5ca638) which means we skipped invoking the completion handler. It seems that the right thing to do is NOT fail with an error, but simply invoke the completion handler with the 401 response received.
1 parent 454b3bd commit e7a517e

File tree

2 files changed

+4
-6
lines changed

2 files changed

+4
-6
lines changed

Foundation/URLSession/URLSessionTask.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -574,11 +574,8 @@ extension _ProtocolClient : URLProtocolClient {
574574
sender: `protocol` as! _HTTPURLProtocol)
575575
task.previousFailureCount += 1
576576
urlProtocol(`protocol`, didReceive: authenticationChallenge)
577-
} else {
578-
let urlError = URLError(_nsError: NSError(domain: NSURLErrorDomain, code: NSURLErrorUserAuthenticationRequired, userInfo: nil))
579-
urlProtocol(`protocol`, didFailWithError: urlError)
577+
return
580578
}
581-
return
582579
}
583580
switch session.behaviour(for: task) {
584581
case .taskDelegate(let delegate):

TestFoundation/TestURLSession.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -766,9 +766,10 @@ class TestURLSession : LoopbackServerTest {
766766
let expect = expectation(description: "GET \(urlString): with a completion handler")
767767
var expectedResult = "unknown"
768768
let session = URLSession(configuration: URLSessionConfiguration.default)
769-
let task = session.dataTask(with: url) { _, _, error in
769+
let task = session.dataTask(with: url) { _, response, error in
770770
defer { expect.fulfill() }
771-
XCTAssertNotNil(error)
771+
XCTAssertNotNil(response)
772+
XCTAssertNil(error)
772773
}
773774
task.resume()
774775
waitForExpectations(timeout: 12, handler: nil)

0 commit comments

Comments
 (0)