/ Sources / FoundationNetworking / URLSession / URLSessionConfiguration.swift
URLSessionConfiguration.swift
  1  // Foundation/URLSession/URLSessionConfiguration.swift - URLSession Configuration
  2  //
  3  // This source file is part of the Swift.org open source project
  4  //
  5  // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
  6  // Licensed under Apache License v2.0 with Runtime Library Exception
  7  //
  8  // See http://swift.org/LICENSE.txt for license information
  9  // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 10  //
 11  // -----------------------------------------------------------------------------
 12  ///
 13  /// URLSession API code.
 14  /// - SeeAlso: URLSession.swift
 15  ///
 16  // -----------------------------------------------------------------------------
 17  
 18  #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
 19  import SwiftFoundation
 20  #else
 21  import Foundation
 22  #endif
 23  
 24  /// Configuration options for an URLSession.
 25  ///
 26  /// When a session is
 27  /// created, a copy of the configuration object is made - you cannot
 28  /// modify the configuration of a session after it has been created.
 29  ///
 30  /// The shared session uses the global singleton credential, cache
 31  /// and cookie storage objects.
 32  ///
 33  /// An ephemeral session has no persistent disk storage for cookies,
 34  /// cache or credentials.
 35  ///
 36  /// A background session can be used to perform networking operations
 37  /// on behalf of a suspended application, within certain constraints.
 38  open class URLSessionConfiguration : NSObject, NSCopying {
 39      // -init is silently incorrect in URLSessionCofiguration on the desktop. Ensure code that relied on swift-corelibs-foundation's init() being functional is redirected to the appropriate cross-platform class property.
 40      @available(*, deprecated, message: "Use .default instead.", renamed: "URLSessionConfiguration.default")
 41      public override init() {
 42          self.requestCachePolicy = URLSessionConfiguration.default.requestCachePolicy
 43          self.timeoutIntervalForRequest = URLSessionConfiguration.default.timeoutIntervalForRequest
 44          self.timeoutIntervalForResource = URLSessionConfiguration.default.timeoutIntervalForResource
 45          self.networkServiceType = URLSessionConfiguration.default.networkServiceType
 46          self.allowsCellularAccess = URLSessionConfiguration.default.allowsCellularAccess
 47          self.isDiscretionary = URLSessionConfiguration.default.isDiscretionary
 48          self.httpShouldUsePipelining = URLSessionConfiguration.default.httpShouldUsePipelining
 49          self.httpShouldSetCookies = URLSessionConfiguration.default.httpShouldSetCookies
 50          self.httpCookieAcceptPolicy = URLSessionConfiguration.default.httpCookieAcceptPolicy
 51          self.httpMaximumConnectionsPerHost = URLSessionConfiguration.default.httpMaximumConnectionsPerHost
 52          self.httpCookieStorage = URLSessionConfiguration.default.httpCookieStorage
 53          self.urlCredentialStorage = URLSessionConfiguration.default.urlCredentialStorage
 54          self.urlCache = URLSessionConfiguration.default.urlCache
 55          self.shouldUseExtendedBackgroundIdleMode = URLSessionConfiguration.default.shouldUseExtendedBackgroundIdleMode
 56          self.protocolClasses = URLSessionConfiguration.default.protocolClasses
 57          super.init()
 58      }
 59      
 60      internal convenience init(correctly: ()) {
 61          self.init(identifier: nil,
 62                    requestCachePolicy: .useProtocolCachePolicy,
 63                    timeoutIntervalForRequest: 60,
 64                    timeoutIntervalForResource: 604800,
 65                    networkServiceType: .default,
 66                    allowsCellularAccess: true,
 67                    isDiscretionary: false,
 68                    connectionProxyDictionary: nil,
 69                    httpShouldUsePipelining: false,
 70                    httpShouldSetCookies: true,
 71                    httpCookieAcceptPolicy: .onlyFromMainDocumentDomain,
 72                    httpAdditionalHeaders: nil,
 73                    httpMaximumConnectionsPerHost: 6,
 74                    httpCookieStorage: .shared,
 75                    urlCredentialStorage: .shared,
 76                    urlCache: .shared,
 77                    shouldUseExtendedBackgroundIdleMode: false,
 78                    protocolClasses: [_HTTPURLProtocol.self, _FTPURLProtocol.self])
 79      }
 80      
 81      private init(identifier: String?,
 82                   requestCachePolicy: URLRequest.CachePolicy,
 83                   timeoutIntervalForRequest: TimeInterval,
 84                   timeoutIntervalForResource: TimeInterval,
 85                   networkServiceType: URLRequest.NetworkServiceType,
 86                   allowsCellularAccess: Bool,
 87                   isDiscretionary: Bool,
 88                   connectionProxyDictionary: [AnyHashable:Any]?,
 89                   httpShouldUsePipelining: Bool,
 90                   httpShouldSetCookies: Bool,
 91                   httpCookieAcceptPolicy: HTTPCookie.AcceptPolicy,
 92                   httpAdditionalHeaders: [AnyHashable:Any]?,
 93                   httpMaximumConnectionsPerHost: Int,
 94                   httpCookieStorage: HTTPCookieStorage?,
 95                   urlCredentialStorage: URLCredentialStorage?,
 96                   urlCache: URLCache?,
 97                   shouldUseExtendedBackgroundIdleMode: Bool,
 98                   protocolClasses: [AnyClass]?)
 99      {
100          self.identifier = identifier
101          self.requestCachePolicy = requestCachePolicy
102          self.timeoutIntervalForRequest = timeoutIntervalForRequest
103          self.timeoutIntervalForResource = timeoutIntervalForResource
104          self.networkServiceType = networkServiceType
105          self.allowsCellularAccess = allowsCellularAccess
106          self.isDiscretionary = isDiscretionary
107          self.connectionProxyDictionary = connectionProxyDictionary
108          self.httpShouldUsePipelining = httpShouldUsePipelining
109          self.httpShouldSetCookies = httpShouldSetCookies
110          self.httpCookieAcceptPolicy = httpCookieAcceptPolicy
111          self.httpAdditionalHeaders = httpAdditionalHeaders
112          self.httpMaximumConnectionsPerHost = httpMaximumConnectionsPerHost
113          self.httpCookieStorage = httpCookieStorage
114          self.urlCredentialStorage = urlCredentialStorage
115          self.urlCache = urlCache
116          self.shouldUseExtendedBackgroundIdleMode = shouldUseExtendedBackgroundIdleMode
117          self.protocolClasses = protocolClasses
118      }
119      
120      open override func copy() -> Any {
121          return copy(with: nil)
122      }
123      
124      open func copy(with zone: NSZone?) -> Any {
125          return URLSessionConfiguration(
126              identifier: identifier,
127              requestCachePolicy: requestCachePolicy,
128              timeoutIntervalForRequest: timeoutIntervalForRequest,
129              timeoutIntervalForResource: timeoutIntervalForResource,
130              networkServiceType: networkServiceType,
131              allowsCellularAccess: allowsCellularAccess,
132              isDiscretionary: isDiscretionary,
133              connectionProxyDictionary: connectionProxyDictionary,
134              httpShouldUsePipelining: httpShouldUsePipelining,
135              httpShouldSetCookies: httpShouldSetCookies,
136              httpCookieAcceptPolicy: httpCookieAcceptPolicy,
137              httpAdditionalHeaders: httpAdditionalHeaders,
138              httpMaximumConnectionsPerHost: httpMaximumConnectionsPerHost,
139              httpCookieStorage: httpCookieStorage,
140              urlCredentialStorage: urlCredentialStorage,
141              urlCache: urlCache,
142              shouldUseExtendedBackgroundIdleMode: shouldUseExtendedBackgroundIdleMode,
143              protocolClasses: protocolClasses)
144      }
145      
146      open class var `default`: URLSessionConfiguration {
147          return URLSessionConfiguration(correctly: ())
148      }
149  
150      open class var ephemeral: URLSessionConfiguration {
151          let ephemeralConfiguration = URLSessionConfiguration.default.copy() as! URLSessionConfiguration
152          ephemeralConfiguration.httpCookieStorage = .ephemeralStorage()
153          ephemeralConfiguration.urlCredentialStorage = URLCredentialStorage(ephemeral: true)
154          ephemeralConfiguration.urlCache = URLCache(memoryCapacity: 4 * 1024 * 1024, diskCapacity: 0, diskPath: nil)
155          return ephemeralConfiguration
156      }
157  
158      @available(*, unavailable, message: "Not available on non-Darwin platforms")
159      open class func background(withIdentifier identifier: String) -> URLSessionConfiguration { NSUnsupported() }
160      
161      /* identifier for the background session configuration */
162      open var identifier: String?
163      
164      /* default cache policy for requests */
165      open var requestCachePolicy: URLRequest.CachePolicy
166      
167      /* 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. */
168      open var timeoutIntervalForRequest: TimeInterval
169      
170      /* default timeout for requests.  This will cause a timeout if a resource is not able to be retrieved within a given timeout. */
171      open var timeoutIntervalForResource: TimeInterval
172      
173      /* type of service for requests. */
174      open var networkServiceType: URLRequest.NetworkServiceType
175      
176      /* allow request to route over cellular. */
177      open var allowsCellularAccess: Bool
178      
179      /* allows background tasks to be scheduled at the discretion of the system for optimal performance. */
180      open var isDiscretionary: Bool
181      
182      /* The identifier of the shared data container into which files in background sessions should be downloaded.
183       * App extensions wishing to use background sessions *must* set this property to a valid container identifier, or
184       * all transfers in that session will fail with NSURLErrorBackgroundSessionRequiresSharedContainer.
185       */
186      open var sharedContainerIdentifier: String? { return nil }
187      
188      /*
189       * Allows the app to be resumed or launched in the background when tasks in background sessions complete
190       * or when auth is required. This only applies to configurations created with +backgroundSessionConfigurationWithIdentifier:
191       * and the default value is YES.
192       */
193      
194      /* The proxy dictionary, as described by <CFNetwork/CFHTTPStream.h> */
195      open var connectionProxyDictionary: [AnyHashable : Any]? = nil
196      
197      // TODO: We don't have the SSLProtocol type from Security
198      /*
199       /* The minimum allowable versions of the TLS protocol, from <Security/SecureTransport.h> */
200       open var TLSMinimumSupportedProtocol: SSLProtocol
201       
202       /* The maximum allowable versions of the TLS protocol, from <Security/SecureTransport.h> */
203       open var TLSMaximumSupportedProtocol: SSLProtocol
204       */
205      
206      /* Allow the use of HTTP pipelining */
207      open var httpShouldUsePipelining: Bool
208      
209      /* Allow the session to set cookies on requests */
210      open var httpShouldSetCookies: Bool
211      
212      /* Policy for accepting cookies.  This overrides the policy otherwise specified by the cookie storage. */
213      open var httpCookieAcceptPolicy: HTTPCookie.AcceptPolicy
214      
215      /* Specifies additional headers which will be set on outgoing requests.
216       Note that these headers are added to the request only if not already present. */
217      open var httpAdditionalHeaders: [AnyHashable : Any]? = nil
218      
219      #if NS_CURL_MISSING_MAX_HOST_CONNECTIONS
220      /* The maximum number of simultaneous persistent connections per host */
221      @available(*, deprecated, message: "This platform doles not support selecting the maximum number of simultaneous persistent connections per host. This property is ignored.")
222      open var httpMaximumConnectionsPerHost: Int
223      #else
224      /* The maximum number of simultaneous persistent connections per host */
225      open var httpMaximumConnectionsPerHost: Int
226      #endif
227      
228      /* The cookie storage object to use, or nil to indicate that no cookies should be handled */
229      open var httpCookieStorage: HTTPCookieStorage?
230      
231      /* The credential storage object, or nil to indicate that no credential storage is to be used */
232      open var urlCredentialStorage: URLCredentialStorage?
233      
234      /* The URL resource cache, or nil to indicate that no caching is to be performed */
235      open var urlCache: URLCache?
236      
237      /* Enable extended background idle mode for any tcp sockets created.    Enabling this mode asks the system to keep the socket open
238       *  and delay reclaiming it when the process moves to the background (see https://developer.apple.com/library/ios/technotes/tn2277/_index.html)
239       */
240      open var shouldUseExtendedBackgroundIdleMode: Bool
241      
242      /* An optional array of Class objects which subclass URLProtocol.
243       The Class will be sent +canInitWithRequest: when determining if
244       an instance of the class can be used for a given URL scheme.
245       You should not use +[URLProtocol registerClass:], as that
246       method will register your class with the default session rather
247       than with an instance of URLSession.
248       Custom URLProtocol subclasses are not available to background
249       sessions.
250       */
251       open var protocolClasses: [AnyClass]?
252  
253       /* A Boolean value that indicates whether the session should wait for connectivity to become available, or fail immediately */
254       @available(*, unavailable, message: "Not available on non-Darwin platforms")
255       open var waitsForConnectivity: Bool { NSUnsupported() }
256  
257       /* A service type that specifies the Multipath TCP connection policy for transmitting data over Wi-Fi and cellular interfaces*/
258       @available(*, unavailable, message: "Not available on non-Darwin platforms")
259       open var multipathServiceType: URLSessionConfiguration.MultipathServiceType { NSUnsupported() }
260  
261  }
262  
263  @available(*, unavailable, message: "Not available on non-Darwin platforms")
264  extension URLSessionConfiguration {
265      public enum MultipathServiceType {
266          case none
267          case handover
268          case interactive
269          case aggregate
270      }
271  }