@@ -771,6 +771,33 @@ class TestURLSession: LoopbackServerTest {
771
771
waitForExpectations ( timeout: 12 )
772
772
}
773
773
774
+ func test_httpRedirectionChainInheritsTimeoutInterval( ) throws {
775
+ let redirectCount = 4
776
+ let urlString = " http://127.0.0.1: \( TestURLSession . serverPort) /redirect/ \( redirectCount) "
777
+ let url = try XCTUnwrap ( URL ( string: urlString) )
778
+ let timeoutInterval = 3.0
779
+
780
+ for method in httpMethods {
781
+ var request = URLRequest ( url: url)
782
+ request. httpMethod = method
783
+ request. timeoutInterval = timeoutInterval
784
+ let delegate = SessionDelegate ( with: expectation ( description: " \( method) \( urlString) : with HTTP redirection " ) )
785
+ var timeoutIntervals : [ Double ] = [ ]
786
+ delegate. redirectionHandler = { ( response: HTTPURLResponse , request: URLRequest , completionHandler: @escaping ( URLRequest ? ) -> Void ) in
787
+ timeoutIntervals. append ( request. timeoutInterval)
788
+ completionHandler ( request)
789
+ }
790
+ delegate. run ( with: request, timeoutInterval: timeoutInterval)
791
+ waitForExpectations ( timeout: timeoutInterval + 1 )
792
+ XCTAssertEqual ( timeoutIntervals. count, redirectCount, " Redirect chain count for \( method) " )
793
+
794
+ // Check the redirect request timeouts are the same as the original request timeout
795
+ XCTAssertFalse ( timeoutIntervals. contains { $0 != timeoutInterval } , " Timeout Intervals for \( method) " )
796
+ let httpResponse = delegate. response as? HTTPURLResponse
797
+ XCTAssertEqual ( httpResponse? . statusCode, 200 , " .statusCode for \( method) " )
798
+ }
799
+ }
800
+
774
801
func test_httpNotFound( ) throws {
775
802
let urlString = " http://127.0.0.1: \( TestURLSession . serverPort) /404 "
776
803
let url = try XCTUnwrap ( URL ( string: urlString) )
@@ -1663,6 +1690,7 @@ class TestURLSession: LoopbackServerTest {
1663
1690
( " test_httpRedirectionWithInCompleteRelativePath " , test_httpRedirectionWithInCompleteRelativePath) ,
1664
1691
( " test_httpRedirectionWithDefaultPort " , test_httpRedirectionWithDefaultPort) ,
1665
1692
( " test_httpRedirectionTimeout " , test_httpRedirectionTimeout) ,
1693
+ ( " test_httpRedirectionChainInheritsTimeoutInterval " , test_httpRedirectionChainInheritsTimeoutInterval) ,
1666
1694
( " test_httpNotFound " , test_httpNotFound) ,
1667
1695
( " test_http0_9SimpleResponses " , test_http0_9SimpleResponses) ,
1668
1696
( " test_outOfRangeButCorrectlyFormattedHTTPCode " , test_outOfRangeButCorrectlyFormattedHTTPCode) ,
@@ -1733,6 +1761,7 @@ class SessionDelegate: NSObject, URLSessionDelegate {
1733
1761
private( set) var receivedData : Data ?
1734
1762
private( set) var error : Error ?
1735
1763
private( set) var response : URLResponse ?
1764
+ private( set) var redirectionRequest : URLRequest ?
1736
1765
private( set) var redirectionResponse : HTTPURLResponse ?
1737
1766
private( set) var callbacks : [ String ] = [ ]
1738
1767
private( set) var authenticationChallenges : [ URLAuthenticationChallenge ] = [ ]
@@ -1805,6 +1834,7 @@ extension SessionDelegate: URLSessionTaskDelegate {
1805
1834
// HTTP Redirect
1806
1835
public func urlSession( _ session: URLSession , task: URLSessionTask , willPerformHTTPRedirection response: HTTPURLResponse , newRequest request: URLRequest , completionHandler: @escaping ( URLRequest ? ) -> Void ) {
1807
1836
callbacks. append ( #function)
1837
+ redirectionRequest = request
1808
1838
redirectionResponse = response
1809
1839
1810
1840
if let handler = redirectionHandler {
0 commit comments