diff --git a/Sources/FoundationNetworking/URLSession/URLSessionConfiguration.swift b/Sources/FoundationNetworking/URLSession/URLSessionConfiguration.swift index 1282b70135..3f3b26bcb8 100644 --- a/Sources/FoundationNetworking/URLSession/URLSessionConfiguration.swift +++ b/Sources/FoundationNetworking/URLSession/URLSessionConfiguration.swift @@ -216,14 +216,9 @@ open class URLSessionConfiguration : NSObject, NSCopying { Note that these headers are added to the request only if not already present. */ open var httpAdditionalHeaders: [AnyHashable : Any]? = nil - #if NS_CURL_MISSING_MAX_HOST_CONNECTIONS /* The maximum number of simultaneous persistent connections per host */ - @available(*, deprecated, message: "This platform doles not support selecting the maximum number of simultaneous persistent connections per host. This property is ignored.") + /* On platforms with NS_CURL_MISSING_MAX_HOST_CONNECTIONS, this property is ignored. */ open var httpMaximumConnectionsPerHost: Int - #else - /* The maximum number of simultaneous persistent connections per host */ - open var httpMaximumConnectionsPerHost: Int - #endif /* The cookie storage object to use, or nil to indicate that no cookies should be handled */ open var httpCookieStorage: HTTPCookieStorage? diff --git a/Sources/FoundationNetworking/URLSession/URLSessionTask.swift b/Sources/FoundationNetworking/URLSession/URLSessionTask.swift index 1ab0ff9dca..4abf622466 100644 --- a/Sources/FoundationNetworking/URLSession/URLSessionTask.swift +++ b/Sources/FoundationNetworking/URLSession/URLSessionTask.swift @@ -38,12 +38,8 @@ open class URLSessionTask : NSObject, NSCopying { didSet { updateProgress() } } - #if NS_CURL_MISSING_XFERINFOFUNCTION - @available(*, deprecated, message: "This platform doesn't fully support reporting the progress of a URLSessionTask. The progress instance returned will be functional, but may not have continuous updates as bytes are sent or received.") + /* On platforms with NS_CURL_XFERINFOFUNCTION_SUPPORTED not set, the progress instance returned will be functional, but may not have continuous updates as bytes are sent or received. */ open private(set) var progress = Progress(totalUnitCount: -1) - #else - open private(set) var progress = Progress(totalUnitCount: -1) - #endif func updateProgress() { self.workQueue.async { diff --git a/Sources/FoundationNetworking/URLSession/libcurl/EasyHandle.swift b/Sources/FoundationNetworking/URLSession/libcurl/EasyHandle.swift index 5d3d849af7..671b694278 100644 --- a/Sources/FoundationNetworking/URLSession/libcurl/EasyHandle.swift +++ b/Sources/FoundationNetworking/URLSession/libcurl/EasyHandle.swift @@ -209,40 +209,39 @@ extension _EasyHandle { } #endif -#if !NS_CURL_MISSING_CURLINFO_CAINFO #if !os(Windows) && !os(macOS) && !os(iOS) && !os(watchOS) && !os(tvOS) - // Check if there is a default path; if there is, it will already - // be set, so leave things alone - var p: UnsafeMutablePointer? = nil - - try! CFURLSession_easy_getinfo_charp(rawHandle, CFURLSessionInfoCAINFO, &p).asError() - - if p != nil { - return - } - - // Otherwise, search a list of known paths - let paths = [ - "/etc/ssl/certs/ca-certificates.crt", - "/etc/pki/tls/certs/ca-bundle.crt", - "/usr/share/ssl/certs/ca-bundle.crt", - "/usr/local/share/certs/ca-root-nss.crt", - "/etc/ssl/cert.pem" - ] - - for path in paths { - var isDirectory: ObjCBool = false - if FileManager.default.fileExists(atPath: path, - isDirectory: &isDirectory) - && !isDirectory.boolValue { - path.withCString { pathPtr in - try! CFURLSession_easy_setopt_ptr(rawHandle, CFURLSessionOptionCAINFO, UnsafeMutablePointer(mutating: pathPtr)).asError() - } - return - } + if NS_CURL_CURLINFO_CAINFO_SUPPORTED == 1 { + // Check if there is a default path; if there is, it will already + // be set, so leave things alone + var p: UnsafeMutablePointer? = nil + + try! CFURLSession_easy_getinfo_charp(rawHandle, CFURLSessionInfoCAINFO, &p).asError() + if p != nil { + return + } + + // Otherwise, search a list of known paths + let paths = [ + "/etc/ssl/certs/ca-certificates.crt", + "/etc/pki/tls/certs/ca-bundle.crt", + "/usr/share/ssl/certs/ca-bundle.crt", + "/usr/local/share/certs/ca-root-nss.crt", + "/etc/ssl/cert.pem" + ] + + for path in paths { + var isDirectory: ObjCBool = false + if FileManager.default.fileExists(atPath: path, + isDirectory: &isDirectory) + && !isDirectory.boolValue { + path.withCString { pathPtr in + try! CFURLSession_easy_setopt_ptr(rawHandle, CFURLSessionOptionCAINFO, UnsafeMutablePointer(mutating: pathPtr)).asError() + } + return + } + } } #endif // !os(Windows) && !os(macOS) && !os(iOS) && !os(watchOS) && !os(tvOS) -#endif // !NS_CURL_MISSING_CURLINFO_CAINFO } /// Set allowed protocols @@ -626,13 +625,13 @@ fileprivate extension _EasyHandle { try! CFURLSession_easy_setopt_ptr(rawHandle, CFURLSessionOptionPROGRESSDATA, UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())).asError() - #if !NS_CURL_MISSING_XFERINFOFUNCTION - try! CFURLSession_easy_setopt_tc(rawHandle, CFURLSessionOptionXFERINFOFUNCTION, { (userdata: UnsafeMutableRawPointer?, dltotal :Int64, dlnow: Int64, ultotal: Int64, ulnow: Int64) -> Int32 in - guard let handle = _EasyHandle.from(callbackUserData: userdata) else { return -1 } - handle.updateProgressMeter(with: _Progress(totalBytesSent: ulnow, totalBytesExpectedToSend: ultotal, totalBytesReceived: dlnow, totalBytesExpectedToReceive: dltotal)) - return 0 - }).asError() - #endif + if NS_CURL_XFERINFOFUNCTION_SUPPORTED == 1 { + try! CFURLSession_easy_setopt_tc(rawHandle, CFURLSessionOptionXFERINFOFUNCTION, { (userdata: UnsafeMutableRawPointer?, dltotal :Int64, dlnow: Int64, ultotal: Int64, ulnow: Int64) -> Int32 in + guard let handle = _EasyHandle.from(callbackUserData: userdata) else { return -1 } + handle.updateProgressMeter(with: _Progress(totalBytesSent: ulnow, totalBytesExpectedToSend: ultotal, totalBytesReceived: dlnow, totalBytesExpectedToReceive: dltotal)) + return 0 + }).asError() + } } /// This callback function gets called by libcurl when it receives body diff --git a/Sources/FoundationNetworking/URLSession/libcurl/MultiHandle.swift b/Sources/FoundationNetworking/URLSession/libcurl/MultiHandle.swift index 8309ea3969..d63573cace 100644 --- a/Sources/FoundationNetworking/URLSession/libcurl/MultiHandle.swift +++ b/Sources/FoundationNetworking/URLSession/libcurl/MultiHandle.swift @@ -65,9 +65,9 @@ extension URLSession { extension URLSession._MultiHandle { func configure(with configuration: URLSession._Configuration) { - #if !NS_CURL_MISSING_MAX_HOST_CONNECTIONS - try! CFURLSession_multi_setopt_l(rawHandle, CFURLSessionMultiOptionMAX_HOST_CONNECTIONS, numericCast(configuration.httpMaximumConnectionsPerHost)).asError() - #endif + if NS_CURL_MAX_HOST_CONNECTIONS_SUPPORTED == 1 { + try! CFURLSession_multi_setopt_l(rawHandle, CFURLSessionMultiOptionMAX_HOST_CONNECTIONS, numericCast(configuration.httpMaximumConnectionsPerHost)).asError() + } try! CFURLSession_multi_setopt_l(rawHandle, CFURLSessionMultiOptionPIPELINING, configuration.httpShouldUsePipelining ? 3 : 2).asError() //TODO: We may want to set diff --git a/Sources/_CFURLSessionInterface/CFURLSessionInterface.c b/Sources/_CFURLSessionInterface/CFURLSessionInterface.c index d6d5f69f26..f97a49c171 100644 --- a/Sources/_CFURLSessionInterface/CFURLSessionInterface.c +++ b/Sources/_CFURLSessionInterface/CFURLSessionInterface.c @@ -540,8 +540,10 @@ CFURLSessionOption const CFURLSessionOptionTCP_KEEPIDLE = { CURLOPT_TCP_KEEPIDLE CFURLSessionOption const CFURLSessionOptionTCP_KEEPINTVL = { CURLOPT_TCP_KEEPINTVL }; CFURLSessionOption const CFURLSessionOptionSSL_OPTIONS = { CURLOPT_SSL_OPTIONS }; CFURLSessionOption const CFURLSessionOptionMAIL_AUTH = { CURLOPT_MAIL_AUTH }; -#if !NS_CURL_MISSING_XFERINFOFUNCTION +#if NS_CURL_XFERINFOFUNCTION_SUPPORTED CFURLSessionOption const CFURLSessionOptionXFERINFOFUNCTION = { CURLOPT_XFERINFOFUNCTION }; +#else +CFURLSessionOption const CFURLSessionOptionXFERINFOFUNCTION = { 0 }; #endif CFURLSessionInfo const CFURLSessionInfoTEXT = { CURLINFO_TEXT }; @@ -586,8 +588,10 @@ CFURLSessionInfo const CFURLSessionInfoFTP_ENTRY_PATH = { CURLINFO_FTP_ENTRY_PAT CFURLSessionInfo const CFURLSessionInfoREDIRECT_URL = { CURLINFO_REDIRECT_URL }; CFURLSessionInfo const CFURLSessionInfoPRIMARY_IP = { CURLINFO_PRIMARY_IP }; CFURLSessionInfo const CFURLSessionInfoAPPCONNECT_TIME = { CURLINFO_APPCONNECT_TIME }; -#if !NS_CURL_MISSING_CURLINFO_CAINFO +#if NS_CURL_CURLINFO_CAINFO_SUPPORTED CFURLSessionInfo const CFURLSessionInfoCAINFO = { CURLINFO_CAINFO }; +#else +CFURLSessionInfo const CFURLSessionInfoCAINFO = { CURLINFO_NONE }; #endif CFURLSessionInfo const CFURLSessionInfoCERTINFO = { CURLINFO_CERTINFO }; CFURLSessionInfo const CFURLSessionInfoCONDITION_UNMET = { CURLINFO_CONDITION_UNMET }; @@ -607,11 +611,12 @@ CFURLSessionMultiOption const CFURLSessionMultiOptionPIPELINING = { CURLMOPT_PIP CFURLSessionMultiOption const CFURLSessionMultiOptionTIMERFUNCTION = { CURLMOPT_TIMERFUNCTION }; CFURLSessionMultiOption const CFURLSessionMultiOptionTIMERDATA = { CURLMOPT_TIMERDATA }; CFURLSessionMultiOption const CFURLSessionMultiOptionMAXCONNECTS = { CURLMOPT_MAXCONNECTS }; -#if !NS_CURL_MISSING_MAX_HOST_CONNECTIONS +#if NS_CURL_MAX_HOST_CONNECTIONS_SUPPORTED CFURLSessionMultiOption const CFURLSessionMultiOptionMAX_HOST_CONNECTIONS = { CURLMOPT_MAX_HOST_CONNECTIONS }; +#else +CFURLSessionMultiOption const CFURLSessionMultiOptionMAX_HOST_CONNECTIONS = { 0 }; #endif - CFURLSessionMultiCode const CFURLSessionMultiCodeCALL_MULTI_PERFORM = { CURLM_CALL_MULTI_PERFORM }; CFURLSessionMultiCode const CFURLSessionMultiCodeOK = { CURLM_OK }; CFURLSessionMultiCode const CFURLSessionMultiCodeBAD_HANDLE = { CURLM_BAD_HANDLE }; diff --git a/Sources/_CFURLSessionInterface/include/CFURLSessionInterface.h b/Sources/_CFURLSessionInterface/include/CFURLSessionInterface.h index ec389c2b75..7a218835d0 100644 --- a/Sources/_CFURLSessionInterface/include/CFURLSessionInterface.h +++ b/Sources/_CFURLSessionInterface/include/CFURLSessionInterface.h @@ -34,6 +34,27 @@ #include #endif +// 7.84.0 or later +#if LIBCURL_VERSION_MAJOR > 7 || (LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR > 84) || (LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR == 84 && LIBCURL_VERSION_PATCH >= 0) +#define NS_CURL_CURLINFO_CAINFO_SUPPORTED 1 +#else +#define NS_CURL_CURLINFO_CAINFO_SUPPORTED 0 +#endif + +// 7.30.0 or later +#if LIBCURL_VERSION_MAJOR > 7 || (LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR > 30) || (LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR == 30 && LIBCURL_VERSION_PATCH >= 0) +#define NS_CURL_MAX_HOST_CONNECTIONS_SUPPORTED 1 +#else +#define NS_CURL_MAX_HOST_CONNECTIONS_SUPPORTED 0 +#endif + +// 7.32.0 or later +#if LIBCURL_VERSION_MAJOR > 7 || (LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR > 32) || (LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR == 32 && LIBCURL_VERSION_PATCH >= 0) +#define NS_CURL_XFERINFOFUNCTION_SUPPORTED 1 +#else +#define NS_CURL_XFERINFOFUNCTION_SUPPORTED 0 +#endif + CF_IMPLICIT_BRIDGING_ENABLED CF_EXTERN_C_BEGIN