From 88dca37b3f2ff8572dbbd3e764f0cb2e191c1cf1 Mon Sep 17 00:00:00 2001 From: New Pagodi Date: Sun, 7 Feb 2021 16:34:07 -0600 Subject: [PATCH] Change cancel method for wxWebRequestCURL objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously wxWebRequestCURL objects were canceled by removing their CURL easy handle from the CURLM multihandle. Unfortunately the really only pauses the connection and does not truly cancel it. This commit tries to stop the transfer by retrieving the active socket from the CURL handle for the transfer and closing it. There are some complications in doing this because the option curl uses to get the socket have changed over the years. A combination of compile time and run time checks are used to use the appropriate options to get the socket. However in the case of 64bit windows using a curl version older than 7.45.0 simply won’t have an usable option. In this case, it seems nothing can be done. --- include/wx/private/webrequest_curl.h | 1 + src/common/webrequest_curl.cpp | 65 ++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/include/wx/private/webrequest_curl.h b/include/wx/private/webrequest_curl.h index dd1e4bf4ea..b106cef287 100644 --- a/include/wx/private/webrequest_curl.h +++ b/include/wx/private/webrequest_curl.h @@ -167,6 +167,7 @@ private: void ProcessSocketCallback(curl_socket_t, int); void ProcessSocketPollerResult(wxThreadEvent&); void CheckForCompletedTransfers(); + void StopTransfer(CURL*); WX_DECLARE_HASH_MAP(CURL*, wxWebRequestCURL*, wxPointerHash, \ wxPointerEqual, TransferSet); diff --git a/src/common/webrequest_curl.cpp b/src/common/webrequest_curl.cpp index d608192cc8..3b98f9e992 100644 --- a/src/common/webrequest_curl.cpp +++ b/src/common/webrequest_curl.cpp @@ -1027,6 +1027,8 @@ void wxWebSessionCURL::CancelRequest(wxWebRequestCURL* request) } curl_multi_remove_handle(m_handle, curl); + StopTransfer(curl); + request->SetState(wxWebRequest::State_Cancelled); } @@ -1235,4 +1237,67 @@ void wxWebSessionCURL::CheckForCompletedTransfers() } } +void wxWebSessionCURL::StopTransfer(CURL* curl) +{ + curl_socket_t activeSocket; + bool closeActiveSocket = true; + bool useLastSocket = false; + +#if CURL_AT_LEAST_VERSION(7, 45, 0) + if ( CurlRuntimeAtLeastVersion(7, 45, 0) ) + { + CURLcode code = curl_easy_getinfo(curl, CURLINFO_ACTIVESOCKET, + &activeSocket); + + if ( code != CURLE_OK || activeSocket == CURL_SOCKET_BAD ) + { + closeActiveSocket = false; + } + } + else + { + useLastSocket = true; + } +#else + useLastSocket = true; +#endif //CURL_AT_LEAST_VERSION(7, 45, 0) + + // CURLINFO_ACTIVESOCKET is not available either at compile time or run + // time. So we must use the older CURLINFO_LASTSOCKET instead. + if ( useLastSocket ) + { + #ifdef __WIN64__ + // CURLINFO_LASTSOCKET won't work on 64 bit windows because it + // uses a long to retrive the socket. However sockets will be 64 + // bit values. In this case there is nothing we can do. + closeActiveSocket = false; + #endif //__WIN64__ + + if ( closeActiveSocket ) + { + long longSocket; + CURLcode code = curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, + &longSocket); + + if ( code == CURLE_OK && longSocket!= -1 ) + { + activeSocket = static_cast(longSocket); + } + else + { + closeActiveSocket = false; + } + } + } + + if ( closeActiveSocket ) + { + #ifdef __WINDOWS__ + closesocket(activeSocket); + #else + close(activeSocket); + #endif + } +} + #endif // wxUSE_WEBREQUEST_CURL