Skip to content

[5.2] Support Linux variants with older libcurl #2770

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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ if(CMAKE_VERSION VERSION_LESS 3.16.0)
endif()

option(BUILD_SHARED_LIBS "build shared libraries" ON)
option(NS_CURL_ASSUME_FEATURES_MISSING "Assume that optional libcurl features are missing rather than test the library's version, for build debugging" NO)

find_package(CURL CONFIG)
if(CURL_FOUND)
Expand Down
10 changes: 10 additions & 0 deletions CoreFoundation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,16 @@ if(CMAKE_SYSTEM_NAME STREQUAL Android)
log)
endif()

if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
if((NS_CURL_ASSUME_FEATURES_MISSING) OR (CURL_VERSION_STRING VERSION_LESS "7.32.0"))
add_compile_definitions($<$<COMPILE_LANGUAGE:C>:NS_CURL_MISSING_XFERINFOFUNCTION>)
endif()

if((NS_CURL_ASSUME_FEATURES_MISSING) OR (CURL_VERSION_STRING VERSION_LESS "7.30.0"))
add_compile_definitions($<$<COMPILE_LANGUAGE:C>:NS_CURL_MISSING_MAX_HOST_CONNECTIONS>)
endif()
endif()

add_framework(CFURLSessionInterface
${FRAMEWORK_LIBRARY_TYPE}
FRAMEWORK_DIRECTORY
Expand Down
46 changes: 4 additions & 42 deletions CoreFoundation/URL.subproj/CFURLSessionInterface.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ CFURLSessionEasyCode const CFURLSessionEasyCodeFTP_ACCEPT_TIMEOUT = { CURLE_FTP_
CFURLSessionEasyCode const CFURLSessionEasyCodeFTP_WEIRD_PASV_REPLY = { CURLE_FTP_WEIRD_PASV_REPLY };
CFURLSessionEasyCode const CFURLSessionEasyCodeFTP_WEIRD_227_FORMAT = { CURLE_FTP_WEIRD_227_FORMAT };
CFURLSessionEasyCode const CFURLSessionEasyCodeFTP_CANT_GET_HOST = { CURLE_FTP_CANT_GET_HOST };
//CFURLSessionEasyCode const CFURLSessionEasyCodeHTTP2 = { CURLE_HTTP2 };
CFURLSessionEasyCode const CFURLSessionEasyCodeFTP_COULDNT_SET_TYPE = { CURLE_FTP_COULDNT_SET_TYPE };
CFURLSessionEasyCode const CFURLSessionEasyCodePARTIAL_FILE = { CURLE_PARTIAL_FILE };
CFURLSessionEasyCode const CFURLSessionEasyCodeFTP_COULDNT_RETR_FILE = { CURLE_FTP_COULDNT_RETR_FILE };
Expand Down Expand Up @@ -185,7 +184,6 @@ CFURLSessionEasyCode const CFURLSessionEasyCodeBAD_DOWNLOAD_RESUME = { CURLE_BAD
CFURLSessionEasyCode const CFURLSessionEasyCodeFILE_COULDNT_READ_FILE = { CURLE_FILE_COULDNT_READ_FILE };
CFURLSessionEasyCode const CFURLSessionEasyCodeLDAP_CANNOT_BIND = { CURLE_LDAP_CANNOT_BIND };
CFURLSessionEasyCode const CFURLSessionEasyCodeLDAP_SEARCH_FAILED = { CURLE_LDAP_SEARCH_FAILED };
//CFURLSessionEasyCode const CFURLSessionEasyCodeOBSOLETE40 = { CURLE_OBSOLETE40 };
CFURLSessionEasyCode const CFURLSessionEasyCodeFUNCTION_NOT_FOUND = { CURLE_FUNCTION_NOT_FOUND };
CFURLSessionEasyCode const CFURLSessionEasyCodeABORTED_BY_CALLBACK = { CURLE_ABORTED_BY_CALLBACK };
CFURLSessionEasyCode const CFURLSessionEasyCodeBAD_FUNCTION_ARGUMENT = { CURLE_BAD_FUNCTION_ARGUMENT };
Expand Down Expand Up @@ -234,10 +232,6 @@ CFURLSessionEasyCode const CFURLSessionEasyCodeRTSP_CSEQ_ERROR = { CURLE_RTSP_CS
CFURLSessionEasyCode const CFURLSessionEasyCodeRTSP_SESSION_ERROR = { CURLE_RTSP_SESSION_ERROR };
CFURLSessionEasyCode const CFURLSessionEasyCodeFTP_BAD_FILE_LIST = { CURLE_FTP_BAD_FILE_LIST };
CFURLSessionEasyCode const CFURLSessionEasyCodeCHUNK_FAILED = { CURLE_CHUNK_FAILED };
CFURLSessionEasyCode const CFURLSessionEasyCodeNO_CONNECTION_AVAILABLE = { CURLE_NO_CONNECTION_AVAILABLE };
//CFURLSessionEasyCode const CFURLSessionEasyCodeSSL_PINNEDPUBKEYNOTMATCH = { CURLE_SSL_PINNEDPUBKEYNOTMATCH };
//CFURLSessionEasyCode const CFURLSessionEasyCodeSSL_INVALIDCERTSTATUS = { CURLE_SSL_INVALIDCERTSTATUS };


CFURLSessionProtocol const CFURLSessionProtocolHTTP = CURLPROTO_HTTP;
CFURLSessionProtocol const CFURLSessionProtocolHTTPS = CURLPROTO_HTTPS;
Expand Down Expand Up @@ -265,8 +259,6 @@ CFURLSessionProtocol const CFURLSessionProtocolRTMPTE = CURLPROTO_RTMPTE;
CFURLSessionProtocol const CFURLSessionProtocolRTMPS = CURLPROTO_RTMPS;
CFURLSessionProtocol const CFURLSessionProtocolRTMPTS = CURLPROTO_RTMPTS;
CFURLSessionProtocol const CFURLSessionProtocolGOPHER = CURLPROTO_GOPHER;
//CFURLSessionProtocol const CFURLSessionProtocolSMB = CURLPROTO_SMB;
//CFURLSessionProtocol const CFURLSessionProtocolSMBS = CURLPROTO_SMBS;
CFURLSessionProtocol const CFURLSessionProtocolALL = CURLPROTO_ALL;


Expand Down Expand Up @@ -308,7 +300,6 @@ CFURLSessionOption const CFURLSessionOptionTIMEVALUE = { CURLOPT_TIMEVALUE };
CFURLSessionOption const CFURLSessionOptionCUSTOMREQUEST = { CURLOPT_CUSTOMREQUEST };
CFURLSessionOption const CFURLSessionOptionSTDERR = { CURLOPT_STDERR };
CFURLSessionOption const CFURLSessionOptionPOSTQUOTE = { CURLOPT_POSTQUOTE };
/*CFURLSessionOption const CFURLSessionOptionOBSOLETE40 = { CURLOPT_OBSOLETE40 };*/
CFURLSessionOption const CFURLSessionOptionVERBOSE = { CURLOPT_VERBOSE };
CFURLSessionOption const CFURLSessionOptionHEADER = { CURLOPT_HEADER };
CFURLSessionOption const CFURLSessionOptionNOPROGRESS = { CURLOPT_NOPROGRESS };
Expand Down Expand Up @@ -336,7 +327,6 @@ CFURLSessionOption const CFURLSessionOptionMAXREDIRS = { CURLOPT_MAXREDIRS };
CFURLSessionOption const CFURLSessionOptionFILETIME = { CURLOPT_FILETIME };
CFURLSessionOption const CFURLSessionOptionTELNETOPTIONS = { CURLOPT_TELNETOPTIONS };
CFURLSessionOption const CFURLSessionOptionMAXCONNECTS = { CURLOPT_MAXCONNECTS };
//CFURLSessionOption const CFURLSessionOptionOBSOLETE72 = { CURLOPT_OBSOLETE72 };
CFURLSessionOption const CFURLSessionOptionFRESH_CONNECT = { CURLOPT_FRESH_CONNECT };
CFURLSessionOption const CFURLSessionOptionFORBID_REUSE = { CURLOPT_FORBID_REUSE };
CFURLSessionOption const CFURLSessionOptionRANDOM_FILE = { CURLOPT_RANDOM_FILE };
Expand Down Expand Up @@ -472,30 +462,9 @@ 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 };
CFURLSessionOption const CFURLSessionOptionSASL_IR = { CURLOPT_SASL_IR };
#if !NS_CURL_MISSING_XFERINFOFUNCTION
CFURLSessionOption const CFURLSessionOptionXFERINFOFUNCTION = { CURLOPT_XFERINFOFUNCTION };
CFURLSessionOption const CFURLSessionOptionXFERINFODATA = { CURLOPT_XFERINFODATA };
CFURLSessionOption const CFURLSessionOptionXOAUTH2_BEARER = { CURLOPT_XOAUTH2_BEARER };
CFURLSessionOption const CFURLSessionOptionDNS_INTERFACE = { CURLOPT_DNS_INTERFACE };
CFURLSessionOption const CFURLSessionOptionDNS_LOCAL_IP4 = { CURLOPT_DNS_LOCAL_IP4 };
CFURLSessionOption const CFURLSessionOptionDNS_LOCAL_IP6 = { CURLOPT_DNS_LOCAL_IP6 };
CFURLSessionOption const CFURLSessionOptionLOGIN_OPTIONS = { CURLOPT_LOGIN_OPTIONS };

//Options unavailable on Ubuntu 14.04
/*CFURLSessionOption const CFURLSessionOptionSSL_ENABLE_NPN = { CURLOPT_SSL_ENABLE_NPN };
CFURLSessionOption const CFURLSessionOptionSSL_ENABLE_ALPN = { CURLOPT_SSL_ENABLE_ALPN };
CFURLSessionOption const CFURLSessionOptionEXPECT_100_TIMEOUT_MS = { CURLOPT_EXPECT_100_TIMEOUT_MS };
CFURLSessionOption const CFURLSessionOptionPROXYHEADER = { CURLOPT_PROXYHEADER };
CFURLSessionOption const CFURLSessionOptionHEADEROPT = { CURLOPT_HEADEROPT };
CFURLSessionOption const CFURLSessionOptionPINNEDPUBLICKEY = { CURLOPT_PINNEDPUBLICKEY };
CFURLSessionOption const CFURLSessionOptionUNIX_SOCKET_PATH = { CURLOPT_UNIX_SOCKET_PATH };
CFURLSessionOption const CFURLSessionOptionSSL_VERIFYSTATUS = { CURLOPT_SSL_VERIFYSTATUS };
CFURLSessionOption const CFURLSessionOptionSSL_FALSESTART = { CURLOPT_SSL_FALSESTART };
CFURLSessionOption const CFURLSessionOptionPATH_AS_IS = { CURLOPT_PATH_AS_IS };
CFURLSessionOption const CFURLSessionOptionPROXY_SERVICE_NAME = { CURLOPT_PROXY_SERVICE_NAME };
CFURLSessionOption const CFURLSessionOptionSERVICE_NAME = { CURLOPT_SERVICE_NAME };
CFURLSessionOption const CFURLSessionOptionPIPEWAIT = { CURLOPT_PIPEWAIT };*/

#endif

CFURLSessionInfo const CFURLSessionInfoTEXT = { CURLINFO_TEXT };
CFURLSessionInfo const CFURLSessionInfoHEADER_IN = { CURLINFO_HEADER_IN };
Expand Down Expand Up @@ -548,7 +517,6 @@ CFURLSessionInfo const CFURLSessionInfoRTSP_CSEQ_RECV = { CURLINFO_RTSP_CSEQ_REC
CFURLSessionInfo const CFURLSessionInfoPRIMARY_PORT = { CURLINFO_PRIMARY_PORT };
CFURLSessionInfo const CFURLSessionInfoLOCAL_IP = { CURLINFO_LOCAL_IP };
CFURLSessionInfo const CFURLSessionInfoLOCAL_PORT = { CURLINFO_LOCAL_PORT };
CFURLSessionInfo const CFURLSessionInfoTLS_SESSION = { CURLINFO_TLS_SESSION };
CFURLSessionInfo const CFURLSessionInfoLASTONE = { CURLINFO_LASTONE };


Expand All @@ -558,14 +526,9 @@ 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
CFURLSessionMultiOption const CFURLSessionMultiOptionMAX_HOST_CONNECTIONS = { CURLMOPT_MAX_HOST_CONNECTIONS };
CFURLSessionMultiOption const CFURLSessionMultiOptionMAX_PIPELINE_LENGTH = { CURLMOPT_MAX_PIPELINE_LENGTH };
CFURLSessionMultiOption const CFURLSessionMultiOptionCONTENT_LENGTH_PENALTY_SIZE = { CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE };
CFURLSessionMultiOption const CFURLSessionMultiOptionCHUNK_LENGTH_PENALTY_SIZE = { CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE };
CFURLSessionMultiOption const CFURLSessionMultiOptionPIPELINING_SITE_BL = { CURLMOPT_PIPELINING_SITE_BL };
CFURLSessionMultiOption const CFURLSessionMultiOptionPIPELINING_SERVER_BL = { CURLMOPT_PIPELINING_SERVER_BL };
CFURLSessionMultiOption const CFURLSessionMultiOptionMAX_TOTAL_CONNECTIONS = { CURLMOPT_MAX_TOTAL_CONNECTIONS };

#endif

CFURLSessionMultiCode const CFURLSessionMultiCodeCALL_MULTI_PERFORM = { CURLM_CALL_MULTI_PERFORM };
CFURLSessionMultiCode const CFURLSessionMultiCodeOK = { CURLM_OK };
Expand All @@ -575,7 +538,6 @@ CFURLSessionMultiCode const CFURLSessionMultiCodeOUT_OF_MEMORY = { CURLM_OUT_OF_
CFURLSessionMultiCode const CFURLSessionMultiCodeINTERNAL_ERROR = { CURLM_INTERNAL_ERROR };
CFURLSessionMultiCode const CFURLSessionMultiCodeBAD_SOCKET = { CURLM_BAD_SOCKET };
CFURLSessionMultiCode const CFURLSessionMultiCodeUNKNOWN_OPTION = { CURLM_UNKNOWN_OPTION };
CFURLSessionMultiCode const CFURLSessionMultiCodeADDED_ALREADY = { CURLM_ADDED_ALREADY };
CFURLSessionMultiCode const CFURLSessionMultiCodeLAST = { CURLM_LAST };


Expand Down
16 changes: 16 additions & 0 deletions Foundation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,22 @@ set_target_properties(Foundation PROPERTIES
Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}/swift)

if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
find_package(CURL CONFIG)
if(NOT CURL_FOUND)
find_package(CURL REQUIRED)
endif()
endif()

if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
if((NS_CURL_ASSUME_FEATURES_MISSING) OR (CURL_VERSION_STRING VERSION_LESS "7.32.0"))
add_compile_definitions(NS_CURL_MISSING_XFERINFOFUNCTION)
endif()

if((NS_CURL_ASSUME_FEATURES_MISSING) OR (CURL_VERSION_STRING VERSION_LESS "7.30.0"))
add_compile_definitions(NS_CURL_MISSING_MAX_HOST_CONNECTIONS)
endif()
endif()

add_library(FoundationNetworking
Boxing.swift
Expand Down
9 changes: 5 additions & 4 deletions Foundation/URLSession/NativeProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,11 @@ internal class _NativeProtocol: URLProtocol, _EasyHandleDelegate {
}
}

func updateProgressMeter(with propgress: _EasyHandle._Progress) {
//TODO: Update progress. Note that a single URLSessionTask might
// perform multiple transfers. The values in `progress` are only for
// the current transfer.
func updateProgressMeter(with progress: _EasyHandle._Progress) {
guard let progressReporter = self.task?.progress else { return }

progressReporter.totalUnitCount = progress.totalBytesExpectedToReceive + progress.totalBytesExpectedToSend
progressReporter.completedUnitCount = progress.totalBytesReceived + progress.totalBytesSent
}

/// The data drain.
Expand Down
8 changes: 7 additions & 1 deletion Foundation/URLSession/URLSessionConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,15 @@ open class URLSessionConfiguration : NSObject, NSCopying {
/* Specifies additional headers which will be set on outgoing requests.
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 does not support selecting the maximum number of simultaneous persistent connections per host. 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
7 changes: 6 additions & 1 deletion Foundation/URLSession/URLSessionTask.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,13 @@ open class URLSessionTask : NSObject, NSCopying {
open var countOfBytesClientExpectsToSend: Int64 = NSURLSessionTransferSizeUnknown {
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.")
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
4 changes: 3 additions & 1 deletion Foundation/URLSession/libcurl/EasyHandle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -498,12 +498,14 @@ fileprivate extension _EasyHandle {
try! CFURLSession_easy_setopt_long(rawHandle, CFURLSessionOptionNOPROGRESS, 0).asError()

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

}
/// This callback function gets called by libcurl when it receives body
Expand Down
3 changes: 3 additions & 0 deletions Foundation/URLSession/libcurl/MultiHandle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ extension URLSession {

extension URLSession._MultiHandle {
func configure(with configuration: URLSession._Configuration) {
#if !NS_CURL_MISSING_XFERINFOFUNCTION
try! CFURLSession_multi_setopt_l(rawHandle, CFURLSessionMultiOptionMAX_HOST_CONNECTIONS, numericCast(configuration.httpMaximumConnectionsPerHost)).asError()
#endif

try! CFURLSession_multi_setopt_l(rawHandle, CFURLSessionMultiOptionPIPELINING, configuration.httpShouldUsePipelining ? 3 : 2).asError()
//TODO: We may want to set
// CFURLSessionMultiOptionMAXCONNECTS
Expand Down