File: Configuration.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (157 lines) | stat: -rw-r--r-- 6,832 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Foundation/URLSession/Configuration.swift - URLSession & libcurl
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
// -----------------------------------------------------------------------------
///
/// These are libcurl helpers for the URLSession API code.
/// - SeeAlso: https://curl.haxx.se/libcurl/c/
/// - SeeAlso: URLSession.swift
///
// -----------------------------------------------------------------------------

#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
import SwiftFoundation
#else
import Foundation
#endif

internal extension URLSession {
    /// This is an immutable / `struct` version of `URLSessionConfiguration`.
    struct _Configuration : Sendable {
        /// identifier for the background session configuration
        let identifier: String?
        
        /// default cache policy for requests
        let requestCachePolicy: URLRequest.CachePolicy
        
        /// default timeout for requests.  This will cause a timeout if no data is transmitted for the given timeout value, and is reset whenever data is transmitted.
        let timeoutIntervalForRequest: TimeInterval
        
        /// default timeout for requests.  This will cause a timeout if a resource is not retrievable within a given timeout.
        let timeoutIntervalForResource: TimeInterval
        
        /// type of service for requests.
        let networkServiceType: URLRequest.NetworkServiceType
        
        /// allow request to route over cellular.
        let allowsCellularAccess: Bool
        
        /// allows background tasks to be scheduled at the discretion of the system for optimal performance.
        let isDiscretionary: Bool
        
        /// The proxy dictionary, as described by <CFNetwork/CFHTTPStream.h>
        // TODO: It would be nice to have the type not be AnyHashable, but for now we need this for source compatibility.
        nonisolated(unsafe) let connectionProxyDictionary: [AnyHashable : Any]?
        
        /// Allow the use of HTTP pipelining
        let httpShouldUsePipelining: Bool
        
        /// Allow the session to set cookies on requests
        let httpShouldSetCookies: Bool
        
        /// Policy for accepting cookies.  This overrides the policy otherwise specified by the cookie storage.
        let httpCookieAcceptPolicy: HTTPCookie.AcceptPolicy
        
        /// Specifies additional headers which will be set on outgoing requests.
        /// Note that these headers are added to the request only if not already present.
        
        let httpAdditionalHeaders: [String : String]?
        /// The maximum number of simultaneous persistent connections per host
        let httpMaximumConnectionsPerHost: Int
        
        /// The cookie storage object to use, or nil to indicate that no cookies should be handled
        let httpCookieStorage: HTTPCookieStorage?
        
        /// The credential storage object, or nil to indicate that no credential storage is to be used
        let urlCredentialStorage: URLCredentialStorage?
        
        /// The URL resource cache, or nil to indicate that no caching is to be performed
        let urlCache: URLCache?
        
        /// Enable extended background idle mode for any tcp sockets created.
        let shouldUseExtendedBackgroundIdleMode: Bool
        
        let protocolClasses: [AnyClass]?
    }
}
internal extension URLSession._Configuration {
    init(URLSessionConfiguration config: URLSessionConfiguration) {
        identifier = config.identifier
        requestCachePolicy = config.requestCachePolicy
        timeoutIntervalForRequest = config.timeoutIntervalForRequest
        timeoutIntervalForResource = config.timeoutIntervalForResource
        networkServiceType = config.networkServiceType
        allowsCellularAccess = config.allowsCellularAccess
        isDiscretionary = config.isDiscretionary
        connectionProxyDictionary = config.connectionProxyDictionary
        httpShouldUsePipelining = config.httpShouldUsePipelining
        httpShouldSetCookies = config.httpShouldSetCookies
        httpCookieAcceptPolicy = config.httpCookieAcceptPolicy
        httpAdditionalHeaders = config.httpAdditionalHeaders.map { convertToStringString(dictionary: $0) }
        httpMaximumConnectionsPerHost = config.httpMaximumConnectionsPerHost
        httpCookieStorage = config.httpCookieStorage
        urlCredentialStorage = config.urlCredentialStorage
        urlCache = config.urlCache
        shouldUseExtendedBackgroundIdleMode = config.shouldUseExtendedBackgroundIdleMode
        protocolClasses = config.protocolClasses
    }
}

// Configure NSURLRequests
internal extension URLSession._Configuration {
    func configure(request: URLRequest) -> URLRequest {
        return setCookies(on: request)
    }

     func setCookies(on request: URLRequest) -> URLRequest {
        var request = request
        if httpShouldSetCookies {
            if let cookieStorage = self.httpCookieStorage, let url = request.url, let cookies = cookieStorage.cookies(for: url) {
                let cookiesHeaderFields =  HTTPCookie.requestHeaderFields(with: cookies)
                if let cookieValue = cookiesHeaderFields["Cookie"], cookieValue != "" {
                    request.setValue(cookieValue, forHTTPHeaderField: "Cookie")
                }
            }
        }
        return request
    }
}

// Cache Management
private extension URLSession._Configuration {
    func cachedResponse(forRequest request: URLRequest) -> CachedURLResponse? {
        //TODO: Check the policy & consult the cache.
        // There's more detail on how this should work here:
        // <https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/Foundation/Classes/NSURLRequest_Class/index.html#//apple_ref/swift/enum/c:@E@URLRequestCachePolicy>
        switch requestCachePolicy {
        default: return nil
        }
    }
}

private func convertToStringString(dictionary: [AnyHashable:Any]) -> [String: String] {
    //TODO: There's some confusion about [NSObject:AnyObject] vs. [String:String] for headers.
    // C.f. <https://github.com/apple/swift-corelibs-foundation/pull/287>
    var r: [String: String] = [:]
    dictionary.forEach {
        let k = getString(from: $0.key)
        let v = getString(from: $0.value)
        r[k] = v
    }
    return r
}

private func getString(from obj: Any) -> String {
    if let string = obj as? String {
        return string
    } else {
        return String(describing: obj as! NSString)
    }
}