Skip to content

Commit fc20c17

Browse files
authored
Merge pull request #496 from vadz/use-ie-proxy-by-default
Use IE proxy by default
2 parents a7ad987 + b7fa0b1 commit fc20c17

File tree

1 file changed

+75
-26
lines changed

1 file changed

+75
-26
lines changed

Release/src/http/client/http_client_winhttp.cpp

Lines changed: 75 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,24 @@ struct proxy_info : WINHTTP_PROXY_INFO
319319
}
320320
};
321321

322+
struct ie_proxy_config : WINHTTP_CURRENT_USER_IE_PROXY_CONFIG
323+
{
324+
ie_proxy_config()
325+
{
326+
memset( this, 0, sizeof(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG) );
327+
}
328+
329+
~ie_proxy_config()
330+
{
331+
if ( lpszAutoConfigUrl )
332+
::GlobalFree(lpszAutoConfigUrl);
333+
if ( lpszProxy )
334+
::GlobalFree(lpszProxy);
335+
if ( lpszProxyBypass )
336+
::GlobalFree(lpszProxyBypass);
337+
}
338+
};
339+
322340
// WinHTTP client.
323341
class winhttp_client : public _http_client_communicator
324342
{
@@ -380,9 +398,13 @@ class winhttp_client : public _http_client_communicator
380398
// Open session and connection with the server.
381399
virtual unsigned long open() override
382400
{
401+
// This object have lifetime greater than proxy_name and proxy_bypass
402+
// which may point to its elements.
403+
ie_proxy_config proxyIE;
404+
383405
DWORD access_type;
384406
LPCWSTR proxy_name;
385-
utility::string_t proxy_str;
407+
LPCWSTR proxy_bypass = WINHTTP_NO_PROXY_BYPASS;
386408
http::uri uri;
387409

388410
const auto& config = client_config();
@@ -394,43 +416,54 @@ class winhttp_client : public _http_client_communicator
394416
}
395417
else if(config.proxy().is_default() || config.proxy().is_auto_discovery())
396418
{
419+
// Use the default WinHTTP proxy by default.
397420
access_type = WINHTTP_ACCESS_TYPE_DEFAULT_PROXY;
398421
proxy_name = WINHTTP_NO_PROXY_NAME;
422+
399423
#ifndef CPPREST_TARGET_XP
400-
if(IsWindows8Point1OrGreater())
424+
if (IsWindows8Point1OrGreater())
401425
{
402426
access_type = WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY;
403427
}
404-
else
428+
429+
// However, if it is not configured...
430+
proxy_info proxyDefault;
431+
if(!WinHttpGetDefaultProxyConfiguration(&proxyDefault) ||
432+
proxyDefault.dwAccessType == WINHTTP_ACCESS_TYPE_NO_PROXY)
405433
{
406-
struct raii_ie_proxy_config : WINHTTP_CURRENT_USER_IE_PROXY_CONFIG
434+
// ... then try to fall back on the default WinINET proxy, as
435+
// recommended for the desktop applications (if we're not
436+
// running under a user account, the function below will just
437+
// fail, so there is no real need to check for this explicitly)
438+
if(WinHttpGetIEProxyConfigForCurrentUser(&proxyIE))
407439
{
408-
raii_ie_proxy_config()
440+
if(proxyIE.fAutoDetect)
409441
{
410-
memset(this, 0, sizeof(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG));
442+
m_proxy_auto_config = true;
411443
}
412-
413-
~raii_ie_proxy_config()
444+
else if(proxyIE.lpszAutoConfigUrl)
414445
{
415-
if (lpszProxy)
416-
::GlobalFree(lpszProxy);
417-
if (lpszProxyBypass)
418-
::GlobalFree(lpszProxyBypass);
419-
if (lpszAutoConfigUrl)
420-
::GlobalFree(lpszAutoConfigUrl);
446+
m_proxy_auto_config = true;
447+
m_proxy_auto_config_url = proxyIE.lpszAutoConfigUrl;
421448
}
422-
};
449+
else if(proxyIE.lpszProxy)
450+
{
451+
access_type = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
452+
proxy_name = proxyIE.lpszProxy;
423453

424-
raii_ie_proxy_config proxyInfo;
425-
BOOL result = WinHttpGetIEProxyConfigForCurrentUser(&proxyInfo);
426-
if (result && proxyInfo.lpszProxy != nullptr)
427-
{
428-
access_type = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
429-
proxy_str = proxyInfo.lpszProxy;
430-
proxy_name = proxy_str.c_str();
454+
if(proxyIE.lpszProxyBypass)
455+
{
456+
proxy_bypass = proxyIE.lpszProxyBypass;
457+
}
458+
}
431459
}
432460
}
433461
#endif
462+
463+
if (config.proxy().is_auto_discovery())
464+
{
465+
m_proxy_auto_config = true;
466+
}
434467
}
435468
else
436469
{
@@ -445,6 +478,7 @@ class winhttp_client : public _http_client_communicator
445478
}
446479
else
447480
{
481+
utility::string_t proxy_str;
448482
if (uri.port() > 0)
449483
{
450484
utility::ostringstream_t ss;
@@ -465,7 +499,7 @@ class winhttp_client : public _http_client_communicator
465499
NULL,
466500
access_type,
467501
proxy_name,
468-
WINHTTP_NO_PROXY_BYPASS,
502+
proxy_bypass,
469503
WINHTTP_FLAG_ASYNC);
470504
if(!m_hSession)
471505
{
@@ -543,13 +577,22 @@ class winhttp_client : public _http_client_communicator
543577
proxy_info info;
544578
bool proxy_info_required = false;
545579

546-
if( client_config().proxy().is_auto_discovery() )
580+
if(m_proxy_auto_config)
547581
{
548582
WINHTTP_AUTOPROXY_OPTIONS autoproxy_options;
549583
memset( &autoproxy_options, 0, sizeof(WINHTTP_AUTOPROXY_OPTIONS) );
550584

551-
autoproxy_options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
552-
autoproxy_options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
585+
if(m_proxy_auto_config_url.empty())
586+
{
587+
autoproxy_options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
588+
autoproxy_options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
589+
}
590+
else
591+
{
592+
autoproxy_options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
593+
autoproxy_options.lpszAutoConfigUrl = m_proxy_auto_config_url.c_str();
594+
}
595+
553596
autoproxy_options.fAutoLogonIfChallenged = TRUE;
554597

555598
auto result = WinHttpGetProxyForUrl(
@@ -1412,6 +1455,12 @@ class winhttp_client : public _http_client_communicator
14121455
HINTERNET m_hSession;
14131456
HINTERNET m_hConnection;
14141457
bool m_secure;
1458+
1459+
// If auto config is true, dynamically find the proxy for each URL using
1460+
// the proxy configuration script at the given URL if it's not empty or
1461+
// using WPAD otherwise.
1462+
bool m_proxy_auto_config{false};
1463+
utility::string_t m_proxy_auto_config_url;
14151464
};
14161465

14171466
std::shared_ptr<_http_client_communicator> create_platform_final_pipeline_stage(uri&& base_uri, http_client_config&& client_config)

0 commit comments

Comments
 (0)