Skip to content

Commit 893a461

Browse files
enasserPushkar Kulkarni
authored and
Pushkar Kulkarni
committed
[SR-3463][URLSession] config.httpAdditionalHeaders isn't picked up
1 parent b6059f2 commit 893a461

File tree

2 files changed

+63
-5
lines changed

2 files changed

+63
-5
lines changed

Foundation/NSURLSession/NSURLSessionTask.swift

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -548,9 +548,31 @@ fileprivate extension URLSessionTask {
548548

549549
// HTTP Options:
550550
easyHandle.set(followLocation: false)
551+
552+
// The httpAdditionalHeaders from session configuration has to be added to the request.
553+
// The request.allHTTPHeaders can override the httpAdditionalHeaders elements. Add the
554+
// httpAdditionalHeaders from session configuration first and then append/update the
555+
// request.allHTTPHeaders so that request.allHTTPHeaders can override httpAdditionalHeaders.
556+
557+
let httpSession = session as! URLSession
558+
var httpHeaders: [AnyHashable : Any]?
559+
560+
if let hh = httpSession.configuration.httpAdditionalHeaders {
561+
httpHeaders = hh
562+
}
563+
564+
if let hh = currentRequest?.allHTTPHeaderFields {
565+
if httpHeaders == nil {
566+
httpHeaders = hh
567+
} else {
568+
hh.forEach {
569+
httpHeaders![$0] = $1
570+
}
571+
}
572+
}
551573

552574
let customHeaders: [String]
553-
let headersForRequest = curlHeaders(for: request)
575+
let headersForRequest = curlHeaders(for: httpHeaders)
554576
if ((request.httpMethod == "POST") && (request.value(forHTTPHeaderField: "Content-Type") == nil)) {
555577
customHeaders = headersForRequest + ["Content-Type:application/x-www-form-urlencoded"]
556578
} else {
@@ -566,8 +588,7 @@ fileprivate extension URLSessionTask {
566588

567589
//set the request timeout
568590
//TODO: the timeout value needs to be reset on every data transfer
569-
let s = session as! URLSession
570-
let timeoutInterval = Int(s.configuration.timeoutIntervalForRequest) * 1000
591+
let timeoutInterval = Int(httpSession.configuration.timeoutIntervalForRequest) * 1000
571592
let timeoutHandler = DispatchWorkItem { [weak self] in
572593
guard let currentTask = self else { fatalError("Timeout on a task that doesn't exist") } //this guard must always pass
573594
currentTask.internalState = .transferFailed
@@ -593,10 +614,11 @@ fileprivate extension URLSessionTask {
593614
/// expects.
594615
///
595616
/// - SeeAlso: https://curl.haxx.se/libcurl/c/CURLOPT_HTTPHEADER.html
596-
func curlHeaders(for request: URLRequest) -> [String] {
617+
func curlHeaders(for httpHeaders: [AnyHashable : Any]?) -> [String] {
597618
var result: [String] = []
598619
var names = Set<String>()
599-
if let hh = currentRequest?.allHTTPHeaderFields {
620+
if httpHeaders != nil {
621+
let hh = httpHeaders as! [String:String]
600622
hh.forEach {
601623
let name = $0.0.lowercased()
602624
guard !names.contains(name) else { return }

TestFoundation/TestNSURLSession.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class TestURLSession : XCTestCase {
3434
("test_taskCopy", test_taskCopy),
3535
("test_taskTimeout", test_taskTimeout),
3636
("test_verifyRequestHeaders", test_verifyRequestHeaders),
37+
("test_verifyHttpAdditionalHeaders", test_verifyHttpAdditionalHeaders),
3738
]
3839
}
3940

@@ -329,6 +330,41 @@ class TestURLSession : XCTestCase {
329330
waitForExpectations(timeout: 30)
330331
}
331332

333+
// Verify httpAdditionalHeaders from session configuration are added to the request
334+
// and whether it is overriden by Request.allHTTPHeaderFields.
335+
336+
func test_verifyHttpAdditionalHeaders() {
337+
let serverReady = ServerSemaphore()
338+
globalDispatchQueue.async {
339+
do {
340+
try self.runServer(with: serverReady)
341+
} catch {
342+
XCTAssertTrue(true)
343+
return
344+
}
345+
}
346+
serverReady.wait()
347+
let config = URLSessionConfiguration.default
348+
config.timeoutIntervalForRequest = 5
349+
config.httpAdditionalHeaders = ["header2": "svalue2", "header3": "svalue3"]
350+
let session = URLSession(configuration: config, delegate: nil, delegateQueue: nil)
351+
var expect = expectation(description: "download task with handler")
352+
var req = URLRequest(url: URL(string: "http://127.0.0.1:\(serverPort)/requestHeaders")!)
353+
let headers = ["header1": "rvalue1", "header2": "rvalue2"]
354+
req.httpMethod = "POST"
355+
req.allHTTPHeaderFields = headers
356+
var task = session.dataTask(with: req) { (data, _, error) -> Void in
357+
defer { expect.fulfill() }
358+
let headers = String(data: data!, encoding: String.Encoding.utf8)!
359+
XCTAssertNotNil(headers.range(of: "header1: rvalue1"))
360+
XCTAssertNotNil(headers.range(of: "header2: rvalue2"))
361+
XCTAssertNotNil(headers.range(of: "header3: svalue3"))
362+
}
363+
task.resume()
364+
365+
waitForExpectations(timeout: 30)
366+
}
367+
332368
func test_taskTimeout() {
333369
let serverReady = ServerSemaphore()
334370
globalDispatchQueue.async {

0 commit comments

Comments
 (0)