Skip to content

Update the way we check for libcurl feature availability #4962

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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.")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We lose this part, but that's the consequence until swiftpm supports something like cmake does here.

/* 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?
Expand Down
6 changes: 1 addition & 5 deletions Sources/FoundationNetworking/URLSession/URLSessionTask.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
75 changes: 37 additions & 38 deletions Sources/FoundationNetworking/URLSession/libcurl/EasyHandle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<Int8>? = 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<Int8>? = 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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 9 additions & 4 deletions Sources/_CFURLSessionInterface/CFURLSessionInterface.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down Expand Up @@ -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 };
Expand All @@ -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 };
Expand Down
21 changes: 21 additions & 0 deletions Sources/_CFURLSessionInterface/include/CFURLSessionInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,27 @@
#include <winsock2.h>
#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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I inverted the sense from "missing" to "supported" because it was a lot easier to understand.

#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

Expand Down