Change cancel method for wxWebRequestCURL objects

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.
This commit is contained in:
New Pagodi
2021-02-07 16:34:07 -06:00
parent 774a752bed
commit 88dca37b3f
2 changed files with 66 additions and 0 deletions

View File

@@ -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);

View File

@@ -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<curl_socket_t>(longSocket);
}
else
{
closeActiveSocket = false;
}
}
}
if ( closeActiveSocket )
{
#ifdef __WINDOWS__
closesocket(activeSocket);
#else
close(activeSocket);
#endif
}
}
#endif // wxUSE_WEBREQUEST_CURL