Testing my app on few machines show that WinApi HttpSendRequest
performs slow sometimes. On non virtual machine it takes ~100-~300 ms, same results on virtual machine sending the same request through curl
. But sending request with HttpSendRequest
on virtual machine with Win10 takes ~5s and on Win7 - ~20s.
Here is a sample code:
...
auto success = OpenInternet();
if (success) {
success = AssignHandles(request);
}
if (success) {
success = SendHttpRequest(request);
}
...
bool OpenInternet(bool reset)
{
if (openHandle == NULL) {
openHandle = InternetOpen(userAgent.c_str(), openAccessType, proxyConfigString, NULL, 0);
if (openHandle != NULL) {
if (IsWindowsVistaOrGreater()) {
BOOL enable = TRUE;
InternetSetOption(openHandle, INTERNET_OPTION_HTTP_DECODING, &enable, sizeof(enable));
}
}
}
return (openHandle == NULL);
}
bool AssignHandles(Request& request)
{
bool success = AssignConnectHandle(request);
if (success) {
success = AssignRequestHandle(request);
if (!success) {
InternetCloseHandle(request.connectHandle);
}
}
return success;
}
bool AssignConnectHandle(Request& request)
{
request.connectHandle = InternetConnect(
openHandle,
request.host.c_str(),
(request.secure ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT),
NULL,
NULL,
INTERNET_SERVICE_HTTP,
0,
INTERNET_NO_CALLBACK);
return (request.connectHandle == NULL);
}
bool AssignRequestHandle(Request& request)
{
LPCWSTR pszAcceptTypes[] = {acceptTypeHeader.c_str(), NULL};
request.requestHandle = HttpOpenRequest(
request.connectHandle,
GetRequestMethod(request.type).c_str(),
request.path.c_str(),
httpVersion.c_str(),
NULL,
pszAcceptTypes,
GetRequestFlags(request.secure),
NULL);
return (request.connectHandle == NULL);
}
bool SendHttpRequest(Request& request)
{
std::wstring headers = PrepareHeaders(request);
bool success = HttpSendRequest(
request.requestHandle,
headers.empty() ? NULL : headers.c_str(),
(uint32_t)headers.size(),
(request.data != NULL) ? (void*)request.data->c_str() : NULL,
(request.data != NULL) ? (uint32_t)request.data->length() : 0)
!= 0;
return success;
}
CodePudding user response:
Probably because VirtualBox has a network implementation that's a little bulky(ish). For me, it made a whole new network adapter (Virtual Ethernet, basically). What it does is, the VM thinks it's connected to Ethernet. Then the VirtualBox backend redirects it through my normal Wi-Fi. These kinds of things are very complicated, so it must be just the overhead of translating the virtual Ethernet to Wi-Fi.
(If you are actually using Ethernet physically, replace all my "Wi-Fi" words with "physical Ethernet")
EDIT: curl
probably uses a different API for network calling that doesn't use WinAPI, so it could just be a WinAPI problem as well