Skip to content

Commit 905ef56

Browse files
authored
Merge pull request #927 from enasser/master
2 parents 7042d36 + 20064e3 commit 905ef56

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
@@ -554,9 +554,31 @@ fileprivate extension URLSessionTask {
554554

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

558580
let customHeaders: [String]
559-
let headersForRequest = curlHeaders(for: request)
581+
let headersForRequest = curlHeaders(for: httpHeaders)
560582
if ((request.httpMethod == "POST") && (request.value(forHTTPHeaderField: "Content-Type") == nil)) {
561583
customHeaders = headersForRequest + ["Content-Type:application/x-www-form-urlencoded"]
562584
} else {
@@ -570,8 +592,7 @@ fileprivate extension URLSessionTask {
570592

571593
//set the request timeout
572594
//TODO: the timeout value needs to be reset on every data transfer
573-
let s = session as! URLSession
574-
let timeoutInterval = Int(s.configuration.timeoutIntervalForRequest) * 1000
595+
let timeoutInterval = Int(httpSession.configuration.timeoutIntervalForRequest) * 1000
575596
let timeoutHandler = DispatchWorkItem { [weak self] in
576597
guard let currentTask = self else { fatalError("Timeout on a task that doesn't exist") } //this guard must always pass
577598
currentTask.internalState = .transferFailed
@@ -597,10 +618,11 @@ fileprivate extension URLSessionTask {
597618
/// expects.
598619
///
599620
/// - SeeAlso: https://curl.haxx.se/libcurl/c/CURLOPT_HTTPHEADER.html
600-
func curlHeaders(for request: URLRequest) -> [String] {
621+
func curlHeaders(for httpHeaders: [AnyHashable : Any]?) -> [String] {
601622
var result: [String] = []
602623
var names = Set<String>()
603-
if let hh = currentRequest?.allHTTPHeaderFields {
624+
if httpHeaders != nil {
625+
let hh = httpHeaders as! [String:String]
604626
hh.forEach {
605627
let name = $0.0.lowercased()
606628
guard !names.contains(name) else { return }

TestFoundation/TestNSURLSession.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class TestURLSession : XCTestCase {
3535
("test_cancelTask", test_cancelTask),
3636
("test_taskTimeout", test_taskTimeout),
3737
("test_verifyRequestHeaders", test_verifyRequestHeaders),
38+
("test_verifyHttpAdditionalHeaders", test_verifyHttpAdditionalHeaders),
3839
]
3940
}
4041

@@ -349,6 +350,41 @@ class TestURLSession : XCTestCase {
349350
waitForExpectations(timeout: 30)
350351
}
351352

353+
// Verify httpAdditionalHeaders from session configuration are added to the request
354+
// and whether it is overriden by Request.allHTTPHeaderFields.
355+
356+
func test_verifyHttpAdditionalHeaders() {
357+
let serverReady = ServerSemaphore()
358+
globalDispatchQueue.async {
359+
do {
360+
try self.runServer(with: serverReady)
361+
} catch {
362+
XCTAssertTrue(true)
363+
return
364+
}
365+
}
366+
serverReady.wait()
367+
let config = URLSessionConfiguration.default
368+
config.timeoutIntervalForRequest = 5
369+
config.httpAdditionalHeaders = ["header2": "svalue2", "header3": "svalue3"]
370+
let session = URLSession(configuration: config, delegate: nil, delegateQueue: nil)
371+
var expect = expectation(description: "download task with handler")
372+
var req = URLRequest(url: URL(string: "http://127.0.0.1:\(serverPort)/requestHeaders")!)
373+
let headers = ["header1": "rvalue1", "header2": "rvalue2"]
374+
req.httpMethod = "POST"
375+
req.allHTTPHeaderFields = headers
376+
var task = session.dataTask(with: req) { (data, _, error) -> Void in
377+
defer { expect.fulfill() }
378+
let headers = String(data: data!, encoding: String.Encoding.utf8)!
379+
XCTAssertNotNil(headers.range(of: "header1: rvalue1"))
380+
XCTAssertNotNil(headers.range(of: "header2: rvalue2"))
381+
XCTAssertNotNil(headers.range(of: "header3: svalue3"))
382+
}
383+
task.resume()
384+
385+
waitForExpectations(timeout: 30)
386+
}
387+
352388
func test_taskTimeout() {
353389
let serverReady = ServerSemaphore()
354390
globalDispatchQueue.async {

0 commit comments

Comments
 (0)