Skip to content

Commit 60e067e

Browse files
authored
Remove proxy settings detection behavior in "default proxy mode." (#1188)
* Remove proxy settings detection behavior in "default proxy mode." This commit partially reverts eb108ad in order to work around a reliability problem with WinHttpGetProxyForUrl. That function hangs unless there is an available thread pool thread to complete the WPAD request. As a result, if a customer issued ~512 concurrent HTTP requests, or otherwise needed that many thread pool threads, there would not be a thread available for WinHTTP to complete the operation, and the program would deadlock. Moreover this call to WinHttpGetDefaultProxyConfiguration is extremely expensive, taking ~20% of overall CPU for the entire program for some Azure Storage SDK customers. The function WinHttpGetProxyForUrlEx is supposed to help with this problem by being asynchronous, but that function was added in Windows 8, so we can't use it unconditionally. And on Windows 8.1 we already are using WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY instead of trying to do proxy autodetect ourselves.
1 parent bed8fa5 commit 60e067e

File tree

2 files changed

+32
-34
lines changed

2 files changed

+32
-34
lines changed

Release/include/cpprest/details/web_utilities.h

-4
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@
1010
****/
1111
#pragma once
1212

13-
#ifdef _WIN32
14-
#include <Windows.h>
15-
#endif // _WIN32
16-
1713
#include "cpprest/asyncrt_utils.h"
1814
#include "cpprest/uri.h"
1915

Release/src/http/client/http_client_winhttp.cpp

+32-30
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,24 @@ enum msg_body_type
243243
transfer_encoding_chunked
244244
};
245245

246+
static DWORD WinHttpDefaultProxyConstant() CPPREST_NOEXCEPT
247+
{
248+
#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
249+
#if _WIN32_WINNT < _WIN32_WINNT_WINBLUE
250+
if (!IsWindows8Point1OrGreater())
251+
{
252+
// Not Windows 8.1 or later, use the default proxy setting
253+
return WINHTTP_ACCESS_TYPE_DEFAULT_PROXY;
254+
}
255+
#endif // _WIN32_WINNT < _WIN32_WINNT_WINBLUE
256+
257+
// Windows 8.1 or later, use the automatic proxy setting
258+
return WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY;
259+
#else // ^^^ _WIN32_WINNT >= _WIN32_WINNT_VISTA ^^^ // vvv _WIN32_WINNT < _WIN32_WINNT_VISTA vvv
260+
return WINHTTP_ACCESS_TYPE_DEFAULT_PROXY;
261+
#endif // _WIN32_WINNT >= _WIN32_WINNT_VISTA
262+
}
263+
246264
// Additional information necessary to track a WinHTTP request.
247265
class winhttp_request_context final : public request_context
248266
{
@@ -818,38 +836,30 @@ class winhttp_client final : public _http_client_communicator
818836
ie_proxy_config proxyIE;
819837

820838
DWORD access_type;
821-
LPCWSTR proxy_name;
839+
LPCWSTR proxy_name = WINHTTP_NO_PROXY_NAME;
822840
LPCWSTR proxy_bypass = WINHTTP_NO_PROXY_BYPASS;
841+
m_proxy_auto_config = false;
823842
utility::string_t proxy_str;
824843
http::uri uri;
825844

826845
const auto& config = client_config();
827-
828-
if (config.proxy().is_disabled())
846+
const auto& proxy = config.proxy();
847+
if (proxy.is_default())
848+
{
849+
access_type = WinHttpDefaultProxyConstant();
850+
}
851+
else if (proxy.is_disabled())
829852
{
830853
access_type = WINHTTP_ACCESS_TYPE_NO_PROXY;
831-
proxy_name = WINHTTP_NO_PROXY_NAME;
832854
}
833-
else if (config.proxy().is_default() || config.proxy().is_auto_discovery())
855+
else if (proxy.is_auto_discovery())
834856
{
835-
// Use the default WinHTTP proxy by default.
836-
access_type = WINHTTP_ACCESS_TYPE_DEFAULT_PROXY;
837-
proxy_name = WINHTTP_NO_PROXY_NAME;
838-
839-
#if _WIN32_WINNT < _WIN32_WINNT_VISTA
840-
if (config.proxy().is_auto_discovery())
857+
access_type = WinHttpDefaultProxyConstant();
858+
if (access_type != WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY)
841859
{
860+
// Windows 8 or earlier, do proxy autodetection ourselves
842861
m_proxy_auto_config = true;
843-
}
844-
#else // ^^^ _WIN32_WINNT < _WIN32_WINNT_VISTA ^^^ // vvv _WIN32_WINNT >= _WIN32_WINNT_VISTA vvv
845-
if (IsWindows8Point1OrGreater())
846-
{
847-
// Windows 8.1 and newer supports automatic proxy discovery and auto-fallback to IE proxy settings
848-
access_type = WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY;
849-
}
850-
else
851-
{
852-
// However, if it is not configured...
862+
853863
proxy_info proxyDefault;
854864
if (!WinHttpGetDefaultProxyConfiguration(&proxyDefault) ||
855865
proxyDefault.dwAccessType == WINHTTP_ACCESS_TYPE_NO_PROXY)
@@ -881,13 +891,7 @@ class winhttp_client final : public _http_client_communicator
881891
}
882892
}
883893
}
884-
885-
if (config.proxy().is_auto_discovery())
886-
{
887-
m_proxy_auto_config = true;
888-
}
889894
}
890-
#endif // _WIN32_WINNT < _WIN32_WINNT_VISTA
891895
}
892896
else
893897
{
@@ -1007,9 +1011,7 @@ class winhttp_client final : public _http_client_communicator
10071011

10081012
if (m_proxy_auto_config)
10091013
{
1010-
WINHTTP_AUTOPROXY_OPTIONS autoproxy_options;
1011-
memset(&autoproxy_options, 0, sizeof(WINHTTP_AUTOPROXY_OPTIONS));
1012-
1014+
WINHTTP_AUTOPROXY_OPTIONS autoproxy_options {};
10131015
if (m_proxy_auto_config_url.empty())
10141016
{
10151017
autoproxy_options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;

0 commit comments

Comments
 (0)