From e489e3c5ba35984f7b52737219ca5dcd37d04c4e Mon Sep 17 00:00:00 2001 From: k1ee Date: Thu, 8 Apr 2021 13:40:52 +0800 Subject: [PATCH 1/6] Unify design, abandon WPAD, manually detects IE Proxy at "tls12-download.c", "vcpkg/base/downloads.cpp". Add an helper code in "build.cpp:409" to make setting proxy easier. --- include/vcpkg/base/system.proxy.h | 18 +++++++++++++ src/tls12-download.c | 28 ++++++++++++++++++-- src/vcpkg/base/downloads.cpp | 44 +++++++++++-------------------- src/vcpkg/base/system.proxy.cpp | 43 ++++++++++++++++++++++++++++++ src/vcpkg/build.cpp | 23 ++++++++++++++++ 5 files changed, 125 insertions(+), 31 deletions(-) create mode 100644 include/vcpkg/base/system.proxy.h create mode 100644 src/vcpkg/base/system.proxy.cpp diff --git a/include/vcpkg/base/system.proxy.h b/include/vcpkg/base/system.proxy.h new file mode 100644 index 0000000000..d3432be2aa --- /dev/null +++ b/include/vcpkg/base/system.proxy.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +/* + * This is a helper class. It reads IE Proxy settings. + * For coherence of vcpkg design "using HTTP(S)_PROXY not WPAD", it is a user-friendly design to manually + * read the IE Proxy settings on Windows, and set the environment variables HTTP(S)_PROXY to the same + * when starting an external program (like CMake, which file(DOWNLOAD) only accept proxy settings + * by HTTP(S)_PROXY variables). + */ + +namespace vcpkg::System +{ + bool get_windows_ie_proxy_enabled(); + std::optional get_windows_ie_proxy_server(); +} \ No newline at end of file diff --git a/src/tls12-download.c b/src/tls12-download.c index 0a3a03fb4c..6f34bbfbd6 100644 --- a/src/tls12-download.c +++ b/src/tls12-download.c @@ -1,6 +1,7 @@ #include #include #include + /* * This program must be as small as possible, because it is committed in binary form to the * vcpkg github repo to enable downloading the main vcpkg program on Windows 7, where TLS 1.2 is @@ -208,8 +209,6 @@ int __stdcall entry() abort_api_failure(std_out, L"GetEnvironmentVariableW"); } - write_message(std_out, L"\r\n"); - const HANDLE out_file = CreateFileW(out_file_path, FILE_WRITE_DATA, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (out_file == INVALID_HANDLE_VALUE) { @@ -223,6 +222,31 @@ int __stdcall entry() abort_api_failure(std_out, L"WinHttpOpen"); } + // If HTTPS_PROXY not found, try use IE Proxy. This works on Windows 10 20H2, so there's no need to determine + // the OS version >= 8.1. + if (access_type == WINHTTP_ACCESS_TYPE_NO_PROXY) + { + WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxy; + if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxy) && ieProxy.lpszProxy != NULL) + { + WINHTTP_PROXY_INFO proxy; + proxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; + proxy.lpszProxy = ieProxy.lpszProxy; + proxy.lpszProxyBypass = ieProxy.lpszProxyBypass; + WinHttpSetOption(session, WINHTTP_OPTION_PROXY, &proxy, sizeof(proxy)); + + write_message(std_out, L" (using IE proxy: "); + write_message(std_out, proxy.lpszProxy); + write_message(std_out, L")"); + + GlobalFree(ieProxy.lpszProxy); + GlobalFree(ieProxy.lpszProxyBypass); + GlobalFree(ieProxy.lpszAutoConfigUrl); + } + } + + write_message(std_out, L"\r\n"); + unsigned long secure_protocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2; if (!WinHttpSetOption(session, WINHTTP_OPTION_SECURE_PROTOCOLS, &secure_protocols, sizeof(DWORD))) { diff --git a/src/vcpkg/base/downloads.cpp b/src/vcpkg/base/downloads.cpp index 9fd3351d0e..85a0104231 100644 --- a/src/vcpkg/base/downloads.cpp +++ b/src/vcpkg/base/downloads.cpp @@ -8,10 +8,6 @@ #include #include -#if defined(_WIN32) -#include -#endif - namespace vcpkg::Downloads { #if defined(_WIN32) @@ -93,8 +89,7 @@ namespace vcpkg::Downloads static ExpectedS make() { auto h = WinHttpOpen(L"vcpkg/1.0", - IsWindows8Point1OrGreater() ? WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY - : WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, + WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); @@ -116,31 +111,22 @@ namespace vcpkg::Downloads WinHttpSetOption(ret.m_hSession.get(), WINHTTP_OPTION_PROXY, &proxy, sizeof(proxy)); } - // Win7 IE Proxy fallback - else if (IsWindows7OrGreater() && !IsWindows8Point1OrGreater()) + // IE Proxy fallback, this works on Windows 10 + else { - // First check if any proxy has been found automatically - WINHTTP_PROXY_INFO proxyInfo; - DWORD proxyInfoSize = sizeof(WINHTTP_PROXY_INFO); - auto noProxyFound = - !WinHttpQueryOption(ret.m_hSession.get(), WINHTTP_OPTION_PROXY, &proxyInfo, &proxyInfoSize) || - proxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NO_PROXY; - - // If no proxy was found automatically, use IE's proxy settings, if any - if (noProxyFound) + // We do not use WPAD anymore + // Directly read IE Proxy setting + WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxy; + if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxy) && ieProxy.lpszProxy != nullptr) { - WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxy; - if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxy) && ieProxy.lpszProxy != nullptr) - { - WINHTTP_PROXY_INFO proxy; - proxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; - proxy.lpszProxy = ieProxy.lpszProxy; - proxy.lpszProxyBypass = ieProxy.lpszProxyBypass; - WinHttpSetOption(ret.m_hSession.get(), WINHTTP_OPTION_PROXY, &proxy, sizeof(proxy)); - GlobalFree(ieProxy.lpszProxy); - GlobalFree(ieProxy.lpszProxyBypass); - GlobalFree(ieProxy.lpszAutoConfigUrl); - } + WINHTTP_PROXY_INFO proxy; + proxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; + proxy.lpszProxy = ieProxy.lpszProxy; + proxy.lpszProxyBypass = ieProxy.lpszProxyBypass; + WinHttpSetOption(ret.m_hSession.get(), WINHTTP_OPTION_PROXY, &proxy, sizeof(proxy)); + GlobalFree(ieProxy.lpszProxy); + GlobalFree(ieProxy.lpszProxyBypass); + GlobalFree(ieProxy.lpszAutoConfigUrl); } } diff --git a/src/vcpkg/base/system.proxy.cpp b/src/vcpkg/base/system.proxy.cpp new file mode 100644 index 0000000000..92dd6e2999 --- /dev/null +++ b/src/vcpkg/base/system.proxy.cpp @@ -0,0 +1,43 @@ +#include + +std::optional vcpkg::System::get_windows_ie_proxy_server() +{ +#if defined(_WIN32) + WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxy; + if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxy) && ieProxy.lpszProxy != nullptr) + { + // Cast wstring to string, as proxy typically doesn't contain non-ascii characters. + // So just mute C4244 for once. + std::wstring w_proxy(ieProxy.lpszProxy); +#pragma warning(disable : 4244) + std::string proxy = std::string(w_proxy.begin(), w_proxy.end()); +#pragma warning(default : 4244) + + GlobalFree(ieProxy.lpszProxy); + GlobalFree(ieProxy.lpszProxyBypass); + GlobalFree(ieProxy.lpszAutoConfigUrl); + + return proxy; + } + return nullptr; +#else + return nullptr; +#endif +} + +bool vcpkg::System::get_windows_ie_proxy_enabled() +{ +#if defined(_WIN32) + WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxy; + if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxy) && ieProxy.lpszProxy != nullptr) + { + GlobalFree(ieProxy.lpszProxy); + GlobalFree(ieProxy.lpszProxyBypass); + GlobalFree(ieProxy.lpszAutoConfigUrl); + return true; + } + return false; +#else + return false; +#endif +} \ No newline at end of file diff --git a/src/vcpkg/build.cpp b/src/vcpkg/build.cpp index 0a22425f3e..eec2364b4e 100644 --- a/src/vcpkg/build.cpp +++ b/src/vcpkg/build.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -396,6 +397,28 @@ namespace vcpkg::Build if (auto p_val = val.get()) env.emplace(var, *p_val); } + /* + * On Windows 10 (>= 8.1) it is a user-friendly way to automatically set HTTP_PROXY and HTTPS_PROXY + * environment variables by reading proxy settings via WinHttpGetIEProxyConfigForCurrentUser, preventing users + * set and unset these variables manually (which is not a decent way). + * It is common in China or any other regions that needs an proxy software (v2ray, shadowsocks, etc.), which + * sets the IE Proxy Settings, but not setting environment variables. This will make vcpkg easier to use, + * specially when use vcpkg in Visual Studio, we even cannot set HTTP(S)_PROXY in CLI, if we want to open or + * close Proxy we need to restart VS. + */ + if (System::get_windows_ie_proxy_enabled()) + { + auto proxy = System::get_windows_ie_proxy_server(); + if (proxy.has_value()) + { + // Most HTTP proxy DOES proxy HTTPS requests. + env.emplace("HTTP_PROXY", proxy.value().c_str()); + env.emplace("HTTPS_PROXY", proxy.value().c_str()); + + System::print2( + "-- Automatically setting HTTP(S)_PROXY environment variables to ", proxy.value(), "\n"); + } + } return {env}; }); From 54b412a4253422ed3c5512a684d2bed01f4d32ac Mon Sep 17 00:00:00 2001 From: k1ee Date: Fri, 9 Apr 2021 10:47:15 +0800 Subject: [PATCH 2/6] Meet @BillyONeal's review --- include/vcpkg/base/system.proxy.h | 9 ++++++-- src/vcpkg/base/downloads.cpp | 12 +++++------ src/vcpkg/base/system.proxy.cpp | 35 ++++++++----------------------- src/vcpkg/build.cpp | 18 +++++++--------- 4 files changed, 29 insertions(+), 45 deletions(-) diff --git a/include/vcpkg/base/system.proxy.h b/include/vcpkg/base/system.proxy.h index d3432be2aa..8b395799f0 100644 --- a/include/vcpkg/base/system.proxy.h +++ b/include/vcpkg/base/system.proxy.h @@ -13,6 +13,11 @@ namespace vcpkg::System { - bool get_windows_ie_proxy_enabled(); - std::optional get_windows_ie_proxy_server(); + struct IEProxySetting + { + std::wstring server; + std::wstring bypass; + }; + + vcpkg::Optional get_windows_ie_proxy_server(); } \ No newline at end of file diff --git a/src/vcpkg/base/downloads.cpp b/src/vcpkg/base/downloads.cpp index 85a0104231..83ad80a2d8 100644 --- a/src/vcpkg/base/downloads.cpp +++ b/src/vcpkg/base/downloads.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace vcpkg::Downloads @@ -116,17 +117,14 @@ namespace vcpkg::Downloads { // We do not use WPAD anymore // Directly read IE Proxy setting - WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxy; - if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxy) && ieProxy.lpszProxy != nullptr) + auto ieProxy = System::get_windows_ie_proxy_server(); + if (ieProxy.has_value()) { WINHTTP_PROXY_INFO proxy; proxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; - proxy.lpszProxy = ieProxy.lpszProxy; - proxy.lpszProxyBypass = ieProxy.lpszProxyBypass; + proxy.lpszProxy = ieProxy.get()->server.data(); + proxy.lpszProxyBypass = ieProxy.get()->bypass.data(); WinHttpSetOption(ret.m_hSession.get(), WINHTTP_OPTION_PROXY, &proxy, sizeof(proxy)); - GlobalFree(ieProxy.lpszProxy); - GlobalFree(ieProxy.lpszProxyBypass); - GlobalFree(ieProxy.lpszAutoConfigUrl); } } diff --git a/src/vcpkg/base/system.proxy.cpp b/src/vcpkg/base/system.proxy.cpp index 92dd6e2999..2c23f1f738 100644 --- a/src/vcpkg/base/system.proxy.cpp +++ b/src/vcpkg/base/system.proxy.cpp @@ -1,43 +1,26 @@ #include -std::optional vcpkg::System::get_windows_ie_proxy_server() +vcpkg::Optional vcpkg::System::get_windows_ie_proxy_server() { #if defined(_WIN32) WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxy; if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxy) && ieProxy.lpszProxy != nullptr) { - // Cast wstring to string, as proxy typically doesn't contain non-ascii characters. - // So just mute C4244 for once. - std::wstring w_proxy(ieProxy.lpszProxy); -#pragma warning(disable : 4244) - std::string proxy = std::string(w_proxy.begin(), w_proxy.end()); -#pragma warning(default : 4244) + vcpkg::System::IEProxySetting ieProxySetting; - GlobalFree(ieProxy.lpszProxy); - GlobalFree(ieProxy.lpszProxyBypass); - GlobalFree(ieProxy.lpszAutoConfigUrl); + ieProxySetting.server = ieProxy.lpszProxy; - return proxy; - } - return nullptr; -#else - return nullptr; -#endif -} + if(ieProxy.lpszProxyBypass != nullptr) + ieProxySetting.bypass = ieProxy.lpszProxyBypass; -bool vcpkg::System::get_windows_ie_proxy_enabled() -{ -#if defined(_WIN32) - WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxy; - if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxy) && ieProxy.lpszProxy != nullptr) - { GlobalFree(ieProxy.lpszProxy); GlobalFree(ieProxy.lpszProxyBypass); GlobalFree(ieProxy.lpszAutoConfigUrl); - return true; + + return ieProxySetting; } - return false; + return vcpkg::Optional(); #else - return false; + return vcpkg::Optional(); #endif } \ No newline at end of file diff --git a/src/vcpkg/build.cpp b/src/vcpkg/build.cpp index eec2364b4e..c55eea6a2a 100644 --- a/src/vcpkg/build.cpp +++ b/src/vcpkg/build.cpp @@ -406,18 +406,16 @@ namespace vcpkg::Build * specially when use vcpkg in Visual Studio, we even cannot set HTTP(S)_PROXY in CLI, if we want to open or * close Proxy we need to restart VS. */ - if (System::get_windows_ie_proxy_enabled()) + auto ieProxy = System::get_windows_ie_proxy_server(); + if (ieProxy.has_value()) { - auto proxy = System::get_windows_ie_proxy_server(); - if (proxy.has_value()) - { - // Most HTTP proxy DOES proxy HTTPS requests. - env.emplace("HTTP_PROXY", proxy.value().c_str()); - env.emplace("HTTPS_PROXY", proxy.value().c_str()); + std::string server = Strings::to_utf8(ieProxy.get()->server); - System::print2( - "-- Automatically setting HTTP(S)_PROXY environment variables to ", proxy.value(), "\n"); - } + System::print2( + "-- Automatically setting HTTP(S)_PROXY environment variables to ", server, "\n"); + + env.emplace("HTTP_PROXY", server.c_str()); + env.emplace("HTTPS_PROXY", server.c_str()); } return {env}; }); From 39d317caf5313551c2b1db9e0b24a306b37c1cd6 Mon Sep 17 00:00:00 2001 From: k1ee Date: Fri, 9 Apr 2021 10:52:05 +0800 Subject: [PATCH 3/6] Formatting --- include/vcpkg/base/system.proxy.h | 44 +++++++++++++-------------- src/vcpkg/base/downloads.cpp | 7 ++--- src/vcpkg/base/system.proxy.cpp | 49 +++++++++++++++---------------- src/vcpkg/build.cpp | 15 +++++----- 4 files changed, 55 insertions(+), 60 deletions(-) diff --git a/include/vcpkg/base/system.proxy.h b/include/vcpkg/base/system.proxy.h index 8b395799f0..d03f047dd7 100644 --- a/include/vcpkg/base/system.proxy.h +++ b/include/vcpkg/base/system.proxy.h @@ -1,23 +1,23 @@ -#pragma once - -#include -#include - -/* - * This is a helper class. It reads IE Proxy settings. - * For coherence of vcpkg design "using HTTP(S)_PROXY not WPAD", it is a user-friendly design to manually - * read the IE Proxy settings on Windows, and set the environment variables HTTP(S)_PROXY to the same - * when starting an external program (like CMake, which file(DOWNLOAD) only accept proxy settings - * by HTTP(S)_PROXY variables). - */ - -namespace vcpkg::System -{ - struct IEProxySetting - { - std::wstring server; - std::wstring bypass; - }; - - vcpkg::Optional get_windows_ie_proxy_server(); +#pragma once + +#include +#include + +/* + * This is a helper class. It reads IE Proxy settings. + * For coherence of vcpkg design "using HTTP(S)_PROXY not WPAD", it is a user-friendly design to manually + * read the IE Proxy settings on Windows, and set the environment variables HTTP(S)_PROXY to the same + * when starting an external program (like CMake, which file(DOWNLOAD) only accept proxy settings + * by HTTP(S)_PROXY variables). + */ + +namespace vcpkg::System +{ + struct IEProxySetting + { + std::wstring server; + std::wstring bypass; + }; + + vcpkg::Optional get_windows_ie_proxy_server(); } \ No newline at end of file diff --git a/src/vcpkg/base/downloads.cpp b/src/vcpkg/base/downloads.cpp index 83ad80a2d8..5cf9fefd58 100644 --- a/src/vcpkg/base/downloads.cpp +++ b/src/vcpkg/base/downloads.cpp @@ -89,11 +89,8 @@ namespace vcpkg::Downloads { static ExpectedS make() { - auto h = WinHttpOpen(L"vcpkg/1.0", - WINHTTP_ACCESS_TYPE_NO_PROXY, - WINHTTP_NO_PROXY_NAME, - WINHTTP_NO_PROXY_BYPASS, - 0); + auto h = WinHttpOpen( + L"vcpkg/1.0", WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (!h) return Strings::concat("WinHttpOpen() failed: ", GetLastError()); WinHttpSession ret; ret.m_hSession.reset(h); diff --git a/src/vcpkg/base/system.proxy.cpp b/src/vcpkg/base/system.proxy.cpp index 2c23f1f738..f7cd1e7a04 100644 --- a/src/vcpkg/base/system.proxy.cpp +++ b/src/vcpkg/base/system.proxy.cpp @@ -1,26 +1,25 @@ -#include - -vcpkg::Optional vcpkg::System::get_windows_ie_proxy_server() -{ -#if defined(_WIN32) - WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxy; - if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxy) && ieProxy.lpszProxy != nullptr) - { - vcpkg::System::IEProxySetting ieProxySetting; - - ieProxySetting.server = ieProxy.lpszProxy; - - if(ieProxy.lpszProxyBypass != nullptr) - ieProxySetting.bypass = ieProxy.lpszProxyBypass; - - GlobalFree(ieProxy.lpszProxy); - GlobalFree(ieProxy.lpszProxyBypass); - GlobalFree(ieProxy.lpszAutoConfigUrl); - - return ieProxySetting; - } - return vcpkg::Optional(); -#else - return vcpkg::Optional(); -#endif +#include + +vcpkg::Optional vcpkg::System::get_windows_ie_proxy_server() +{ +#if defined(_WIN32) + WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxy; + if (WinHttpGetIEProxyConfigForCurrentUser(&ieProxy) && ieProxy.lpszProxy != nullptr) + { + vcpkg::System::IEProxySetting ieProxySetting; + + ieProxySetting.server = ieProxy.lpszProxy; + + if (ieProxy.lpszProxyBypass != nullptr) ieProxySetting.bypass = ieProxy.lpszProxyBypass; + + GlobalFree(ieProxy.lpszProxy); + GlobalFree(ieProxy.lpszProxyBypass); + GlobalFree(ieProxy.lpszAutoConfigUrl); + + return ieProxySetting; + } + return vcpkg::Optional(); +#else + return vcpkg::Optional(); +#endif } \ No newline at end of file diff --git a/src/vcpkg/build.cpp b/src/vcpkg/build.cpp index c55eea6a2a..a01ea082cf 100644 --- a/src/vcpkg/build.cpp +++ b/src/vcpkg/build.cpp @@ -399,20 +399,19 @@ namespace vcpkg::Build /* * On Windows 10 (>= 8.1) it is a user-friendly way to automatically set HTTP_PROXY and HTTPS_PROXY - * environment variables by reading proxy settings via WinHttpGetIEProxyConfigForCurrentUser, preventing users - * set and unset these variables manually (which is not a decent way). - * It is common in China or any other regions that needs an proxy software (v2ray, shadowsocks, etc.), which - * sets the IE Proxy Settings, but not setting environment variables. This will make vcpkg easier to use, - * specially when use vcpkg in Visual Studio, we even cannot set HTTP(S)_PROXY in CLI, if we want to open or - * close Proxy we need to restart VS. + * environment variables by reading proxy settings via WinHttpGetIEProxyConfigForCurrentUser, preventing + * users set and unset these variables manually (which is not a decent way). It is common in China or any + * other regions that needs an proxy software (v2ray, shadowsocks, etc.), which sets the IE Proxy Settings, + * but not setting environment variables. This will make vcpkg easier to use, specially when use vcpkg in + * Visual Studio, we even cannot set HTTP(S)_PROXY in CLI, if we want to open or close Proxy we need to + * restart VS. */ auto ieProxy = System::get_windows_ie_proxy_server(); if (ieProxy.has_value()) { std::string server = Strings::to_utf8(ieProxy.get()->server); - System::print2( - "-- Automatically setting HTTP(S)_PROXY environment variables to ", server, "\n"); + System::print2("-- Automatically setting HTTP(S)_PROXY environment variables to ", server, "\n"); env.emplace("HTTP_PROXY", server.c_str()); env.emplace("HTTPS_PROXY", server.c_str()); From fd6e051250de8f4bfc1a2a8479adfef692fa9cde Mon Sep 17 00:00:00 2001 From: k1ee Date: Fri, 9 Apr 2021 11:25:15 +0800 Subject: [PATCH 4/6] Python's proxy detection --- src/vcpkg/build.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/src/vcpkg/build.cpp b/src/vcpkg/build.cpp index a01ea082cf..01b1f9e75d 100644 --- a/src/vcpkg/build.cpp +++ b/src/vcpkg/build.cpp @@ -411,10 +411,54 @@ namespace vcpkg::Build { std::string server = Strings::to_utf8(ieProxy.get()->server); - System::print2("-- Automatically setting HTTP(S)_PROXY environment variables to ", server, "\n"); + // Separate settings in IE Proxy Settings, which is rare? + // Python implementation: + // https://github.com/python/cpython/blob/7215d1ae25525c92b026166f9d5cac85fb1defe1/Lib/urllib/request.py#L2655 + if (Strings::contains(server, "=")) + { + auto proxy_settings = Strings::split(server, ';'); + for (auto& s : proxy_settings) + { + auto kvp = Strings::split(s, '='); + if (kvp.size() == 2) + { + auto protocol = kvp[0]; + auto address = kvp[1]; + if (!Strings::starts_with(address, protocol + "://")) + { + address = Strings::concat(protocol, "://", address); + } + protocol = Strings::concat(Strings::ascii_to_uppercase(protocol.c_str()), "_PROXY"); + env.emplace(protocol, address); + System::print2("-- Setting ", protocol, " environment variables to ", address, "\n"); + } + } + } + // Specified http:// prefix + else if (Strings::starts_with(server, "http://")) + { + System::print2("-- Setting HTTP_PROXY environment variables to ", server, "\n"); + env.emplace("HTTP_PROXY", server); + } + // Specified https:// prefix + else if (Strings::starts_with(server, "https://")) + { + System::print2("-- Setting HTTPS_PROXY environment variables to ", server, "\n"); + env.emplace("HTTPS_PROXY", server); + } + // Most common case: "ip:port" style, apply to HTTP and HTTPS proxies. + // An HTTP(S)_PROXY means https requests go through that, it can be: + // http:// prefixed: the request go through an HTTP proxy without end-to-end security. + // https:// prefixed: the request go through an HTTPS proxy with end-to-end security. + // Nothing prefixed: don't know the default behaviour, seems considering HTTP proxy as default. + // We simply set "ip:port" to HTTP(S)_PROXY variables because it works on most common cases. + else + { + System::print2("-- Automatically setting HTTP(S)_PROXY environment variables to ", server, "\n"); - env.emplace("HTTP_PROXY", server.c_str()); - env.emplace("HTTPS_PROXY", server.c_str()); + env.emplace("HTTP_PROXY", server.c_str()); + env.emplace("HTTPS_PROXY", server.c_str()); + } } return {env}; }); From e200ad9ceae40458a950b2752d425c305d9fc27a Mon Sep 17 00:00:00 2001 From: k1ee Date: Fri, 9 Apr 2021 11:27:25 +0800 Subject: [PATCH 5/6] Use vcpkg::Optional --- include/vcpkg/base/system.proxy.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/vcpkg/base/system.proxy.h b/include/vcpkg/base/system.proxy.h index d03f047dd7..cbac576ead 100644 --- a/include/vcpkg/base/system.proxy.h +++ b/include/vcpkg/base/system.proxy.h @@ -1,6 +1,7 @@ #pragma once -#include +#include + #include /* From f4987f3da4a3c3b227f4398777d9373005212a4c Mon Sep 17 00:00:00 2001 From: k1ee Date: Fri, 9 Apr 2021 11:33:18 +0800 Subject: [PATCH 6/6] Allow mismatches protocol and address prefix --- src/vcpkg/build.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vcpkg/build.cpp b/src/vcpkg/build.cpp index 01b1f9e75d..7692cac354 100644 --- a/src/vcpkg/build.cpp +++ b/src/vcpkg/build.cpp @@ -424,7 +424,7 @@ namespace vcpkg::Build { auto protocol = kvp[0]; auto address = kvp[1]; - if (!Strings::starts_with(address, protocol + "://")) + if (!Strings::contains(address, "://")) { address = Strings::concat(protocol, "://", address); }