Skip to content

Commit a657b2e

Browse files
committed
When redirecting with a relative Location, add the port number to the new URL
- If the new location includes a host but no port number, then DONT add the port number.
1 parent b2c8092 commit a657b2e

File tree

3 files changed

+30
-0
lines changed

3 files changed

+30
-0
lines changed

Foundation/URLSession/http/HTTPURLProtocol.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,10 +398,19 @@ internal extension _HTTPURLProtocol {
398398

399399
let scheme = request.url?.scheme
400400
let host = request.url?.host
401+
let port = request.url?.port
401402

402403
var components = URLComponents()
403404
components.scheme = scheme
404405
components.host = host
406+
407+
// Use the original port if the new URL does not contain a host
408+
// ie Location: /foo => <original host>:<original port>/Foo
409+
// but Location: newhost/foo will ignore the original port
410+
if targetURL.host == nil {
411+
components.port = port
412+
}
413+
405414
//The path must either begin with "/" or be an empty string.
406415
if targetURL.relativeString.first != "/" {
407416
components.path = "/" + targetURL.relativeString

TestFoundation/HTTPServer.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,13 @@ public class TestURLSessionServer {
480480
let httpResponse = _HTTPResponse(response: .REDIRECT, headers: "Location: \(value)", body: text)
481481
return httpResponse
482482
}
483+
if uri == "/redirect-with-default-port" {
484+
let text = request.getCommaSeparatedHeaders()
485+
let host = request.headers[1].components(separatedBy: " ")[1]
486+
let ip = host.components(separatedBy: ":")[0]
487+
let httpResponse = _HTTPResponse(response: .REDIRECT, headers: "Location: http://\(ip)/redirected-with-default-port", body: text)
488+
return httpResponse
489+
}
483490
return _HTTPResponse(response: .OK, body: capitals[String(uri.dropFirst())]!)
484491
}
485492

TestFoundation/TestURLSession.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class TestURLSession : LoopbackServerTest {
2929
("test_timeoutInterval", test_timeoutInterval),
3030
("test_httpRedirectionWithCompleteRelativePath", test_httpRedirectionWithCompleteRelativePath),
3131
("test_httpRedirectionWithInCompleteRelativePath", test_httpRedirectionWithInCompleteRelativePath),
32+
("test_httpRedirectionWithDefaultPort", test_httpRedirectionWithDefaultPort),
3233
("test_httpRedirectionTimeout", test_httpRedirectionTimeout),
3334
("test_http0_9SimpleResponses", test_http0_9SimpleResponses),
3435
("test_outOfRangeButCorrectlyFormattedHTTPCode", test_outOfRangeButCorrectlyFormattedHTTPCode),
@@ -337,6 +338,14 @@ class TestURLSession : LoopbackServerTest {
337338
waitForExpectations(timeout: 12)
338339
}
339340

341+
func test_httpRedirectionWithDefaultPort() {
342+
let urlString = "http://127.0.0.1:\(TestURLSession.serverPort)/redirect-with-default-port"
343+
let url = URL(string: urlString)!
344+
let d = HTTPRedirectionDataTask(with: expectation(description: "GET \(urlString): with HTTP redirection"))
345+
d.run(with: url)
346+
waitForExpectations(timeout: 12)
347+
}
348+
340349
// temporarily disabled (https://bugs.swift.org/browse/SR-5751)
341350
func test_httpRedirectionTimeout() {
342351
let urlString = "http://127.0.0.1:\(TestURLSession.serverPort)/UnitedStates"
@@ -893,6 +902,11 @@ extension HTTPRedirectionDataTask : URLSessionTaskDelegate {
893902
public func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {
894903
XCTAssertNotNil(response)
895904
XCTAssertEqual(302, response.statusCode, "HTTP response code is not 302")
905+
if let url = response.url, url.path.hasSuffix("/redirect-with-default-port") {
906+
XCTAssertEqual(request.url?.absoluteString, "http://127.0.0.1/redirected-with-default-port")
907+
// Dont follow the redirect as the test server is not running on port 80
908+
return
909+
}
896910
completionHandler(request)
897911
}
898912
}

0 commit comments

Comments
 (0)