Skip to content

Commit dffecf1

Browse files
author
Pushkar N Kulkarni
authored
Merge pull request swiftlang#1007 from saiHemak/nsrequesttimeout
URLRequest.timeoutInterval should override the URLSessionConfiguration.timeoutIntervalForRequest
2 parents 406f007 + 20b8835 commit dffecf1

File tree

4 files changed

+54
-18
lines changed

4 files changed

+54
-18
lines changed

Diff for: Foundation/NSURLSession/NSURLSessionTask.swift

+4-1
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,10 @@ fileprivate extension URLSessionTask {
634634

635635
//set the request timeout
636636
//TODO: the timeout value needs to be reset on every data transfer
637-
let timeoutInterval = Int(httpSession.configuration.timeoutIntervalForRequest) * 1000
637+
var timeoutInterval = Int(httpSession.configuration.timeoutIntervalForRequest) * 1000
638+
if request.isTimeoutIntervalSet {
639+
timeoutInterval = Int(request.timeoutInterval) * 1000
640+
}
638641
let timeoutHandler = DispatchWorkItem { [weak self] in
639642
guard let currentTask = self else { fatalError("Timeout on a task that doesn't exist") } //this guard must always pass
640643
currentTask.internalState = .transferFailed

Diff for: Foundation/URLRequest.swift

+6
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ public struct URLRequest : ReferenceConvertible, Equatable, Hashable {
5959
_applyMutation { $0.cachePolicy = newValue }
6060
}
6161
}
62+
63+
//URLRequest.timeoutInterval should be given precedence over the URLSessionConfiguration.timeoutIntervalForRequest regardless of the value set,
64+
// if it has been set at least once. Even though the default value is 60 ,if the user sets URLRequest.timeoutInterval
65+
// to explicitly 60 then the precedence should be given to URLRequest.timeoutInterval.
66+
internal var isTimeoutIntervalSet = false
6267

6368
/// Returns the timeout interval of the receiver.
6469
/// - discussion: The timeout interval specifies the limit on the idle
@@ -77,6 +82,7 @@ public struct URLRequest : ReferenceConvertible, Equatable, Hashable {
7782
}
7883
set {
7984
_applyMutation { $0.timeoutInterval = newValue }
85+
isTimeoutIntervalSet = true
8086
}
8187
}
8288

Diff for: TestFoundation/TestNSURLSession.swift

+43-15
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,23 @@ class TestURLSession : XCTestCase {
2121

2222
static var allTests: [(String, (TestURLSession) -> () throws -> Void)] {
2323
return [
24-
("test_dataTaskWithURL", test_dataTaskWithURL),
25-
("test_dataTaskWithURLRequest", test_dataTaskWithURLRequest),
26-
("test_dataTaskWithURLCompletionHandler", test_dataTaskWithURLCompletionHandler),
27-
("test_dataTaskWithURLRequestCompletionHandler", test_dataTaskWithURLRequestCompletionHandler),
28-
("test_downloadTaskWithURL", test_downloadTaskWithURL),
29-
("test_downloadTaskWithURLRequest", test_downloadTaskWithURLRequest),
30-
("test_downloadTaskWithRequestAndHandler", test_downloadTaskWithRequestAndHandler),
31-
("test_downloadTaskWithURLAndHandler", test_downloadTaskWithURLAndHandler),
32-
("test_finishTaskAndInvalidate", test_finishTasksAndInvalidate),
33-
("test_taskError", test_taskError),
34-
("test_taskCopy", test_taskCopy),
35-
("test_cancelTask", test_cancelTask),
36-
("test_taskTimeout", test_taskTimeout),
37-
("test_verifyRequestHeaders", test_verifyRequestHeaders),
38-
("test_verifyHttpAdditionalHeaders", test_verifyHttpAdditionalHeaders),
24+
//Disabling to avoid https://bugs.swift.org/browse/SR-4677 and a timeout failure
25+
// ("test_dataTaskWithURL", test_dataTaskWithURL),
26+
// ("test_dataTaskWithURLRequest", test_dataTaskWithURLRequest),
27+
// ("test_dataTaskWithURLCompletionHandler", test_dataTaskWithURLCompletionHandler),
28+
// ("test_dataTaskWithURLRequestCompletionHandler", test_dataTaskWithURLRequestCompletionHandler),
29+
// ("test_downloadTaskWithURL", test_downloadTaskWithURL),
30+
// ("test_downloadTaskWithURLRequest", test_downloadTaskWithURLRequest),
31+
// ("test_downloadTaskWithRequestAndHandler", test_downloadTaskWithRequestAndHandler),
32+
// ("test_downloadTaskWithURLAndHandler", test_downloadTaskWithURLAndHandler),
33+
// ("test_finishTaskAndInvalidate", test_finishTasksAndInvalidate),
34+
// ("test_taskError", test_taskError),
35+
// ("test_taskCopy", test_taskCopy),
36+
// ("test_cancelTask", test_cancelTask),
37+
// ("test_taskTimeout", test_taskTimeout),
38+
// ("test_verifyRequestHeaders", test_verifyRequestHeaders),
39+
// ("test_verifyHttpAdditionalHeaders", test_verifyHttpAdditionalHeaders),
40+
("test_timeoutInterval", test_timeoutInterval),
3941
]
4042
}
4143

@@ -409,6 +411,32 @@ class TestURLSession : XCTestCase {
409411

410412
waitForExpectations(timeout: 30)
411413
}
414+
415+
func test_timeoutInterval() {
416+
let serverReady = ServerSemaphore()
417+
globalDispatchQueue.async {
418+
do {
419+
try self.runServer(with: serverReady, startDelay: 3, sendDelay: 5, bodyChunks: 3)
420+
} catch {
421+
XCTAssertTrue(true)
422+
return
423+
}
424+
}
425+
serverReady.wait()
426+
let config = URLSessionConfiguration.default
427+
config.timeoutIntervalForRequest = 10
428+
let session = URLSession(configuration: config, delegate: nil, delegateQueue: nil)
429+
var expect = expectation(description: "download task with handler")
430+
var req = URLRequest(url: URL(string: "http://127.0.0.1:\(serverPort)/Peru")!)
431+
req.timeoutInterval = 1
432+
var task = session.dataTask(with: req) { (data, _, error) -> Void in
433+
defer { expect.fulfill() }
434+
XCTAssertNotNil(error)
435+
}
436+
task.resume()
437+
438+
waitForExpectations(timeout: 30)
439+
}
412440
}
413441

414442
class SessionDelegate: NSObject, URLSessionDelegate {

Diff for: TestFoundation/main.swift

+1-2
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ XCTMain([
7979
testCase(TestURLRequest.allTests),
8080
testCase(TestNSURLResponse.allTests),
8181
testCase(TestNSHTTPURLResponse.allTests),
82-
//Disabling to avoid https://bugs.swift.org/browse/SR-4677 and a timeout failure
83-
// testCase(TestURLSession.allTests),
82+
testCase(TestURLSession.allTests),
8483
testCase(TestNSNull.allTests),
8584
testCase(TestNSUUID.allTests),
8685
testCase(TestNSValue.allTests),

0 commit comments

Comments
 (0)