Add support to fetch windows proxy config for use with curl

Fix https://gitlab.com/kicad/code/kicad/-/issues/9594
This commit is contained in:
Marek Roszko 2021-11-11 09:29:25 -05:00
parent 8777135d9f
commit e2926f69a5
6 changed files with 146 additions and 0 deletions

View File

@ -38,6 +38,7 @@
#include <build_version.h> #include <build_version.h>
#include <ki_exception.h> // THROW_IO_ERROR #include <ki_exception.h> // THROW_IO_ERROR
#include <kiplatform/app.h> #include <kiplatform/app.h>
#include <kiplatform/environment.h>
#include <pgm_base.h> #include <pgm_base.h>
@ -202,6 +203,24 @@ bool KICAD_CURL_EASY::SetURL( const std::string& aURL )
{ {
if( setOption<const char*>( CURLOPT_URL, aURL.c_str() ) == CURLE_OK ) if( setOption<const char*>( CURLOPT_URL, aURL.c_str() ) == CURLE_OK )
{ {
KIPLATFORM::ENV::PROXY_CONFIG cfg;
// Unforunately on Windows land, proxies can be configured depending on destination url
// So we also check and set any proxy config here
if( KIPLATFORM::ENV::GetSystemProxyConfig( aURL, cfg ) )
{
curl_easy_setopt( m_CURL, CURLOPT_PROXY, cfg.host.c_str() );
if( cfg.username != "" )
{
curl_easy_setopt( m_CURL, CURLOPT_PROXYUSERNAME, cfg.username.c_str() );
}
if( cfg.password != "" )
{
curl_easy_setopt( m_CURL, CURLOPT_PROXYPASSWORD, cfg.password.c_str() );
}
}
return true; return true;
} }

View File

@ -29,6 +29,7 @@ elseif( WIN32 )
set( PLATFORM_LIBS set( PLATFORM_LIBS
"Shlwapi" "Shlwapi"
"winhttp"
) )
elseif( UNIX ) elseif( UNIX )
set( PLATFORM_SRCS set( PLATFORM_SRCS

View File

@ -105,3 +105,9 @@ wxString KIPLATFORM::ENV::GetUserCachePath()
{ {
return g_get_user_cache_dir(); return g_get_user_cache_dir();
} }
bool KIPLATFORM::ENV::GetSystemProxyConfig( const wxString& aURL, PROXY_CONFIG& aCfg )
{
return false;
}

View File

@ -71,5 +71,22 @@ namespace KIPLATFORM
* @return User cache path * @return User cache path
*/ */
wxString GetUserCachePath(); wxString GetUserCachePath();
struct PROXY_CONFIG
{
wxString host;
wxString username;
wxString password;
};
/**
* Retrieves platform level proxying requirements to reach the given url
*
* @param aURL The target url we will be requesting over http
* @param aCfg The proxy config struct that will be populated
*
* @return True if successful fetched proxy info
*/
bool GetSystemProxyConfig( const wxString& aURL, PROXY_CONFIG& aCfg );
} }
} }

View File

@ -23,11 +23,13 @@
#include <wx/filename.h> #include <wx/filename.h>
#include <wx/stdpaths.h> #include <wx/stdpaths.h>
#include <wx/string.h> #include <wx/string.h>
#include <wx/tokenzr.h>
#include <wx/app.h> #include <wx/app.h>
#include <Windows.h> #include <Windows.h>
#include <shellapi.h> #include <shellapi.h>
#include <shlwapi.h> #include <shlwapi.h>
#include <winhttp.h>
void KIPLATFORM::ENV::Init() void KIPLATFORM::ENV::Init()
@ -116,3 +118,98 @@ wxString KIPLATFORM::ENV::GetUserCachePath()
return wxStandardPaths::Get().GetUserLocalDataDir(); return wxStandardPaths::Get().GetUserLocalDataDir();
} }
bool KIPLATFORM::ENV::GetSystemProxyConfig( const wxString& aURL, PROXY_CONFIG& aCfg )
{
bool autoProxy = false;
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxyConfig = { 0 };
WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions = { 0 };
WINHTTP_PROXY_INFO autoProxyInfo = { 0 };
HINTERNET session = NULL;
if( WinHttpGetIEProxyConfigForCurrentUser( &ieProxyConfig ) )
{
// welcome to the wonderful world of IE
// we use the ie config simply to handle it off to the other win32 api
if( ieProxyConfig.fAutoDetect )
{
autoProxy = true;
}
if( ieProxyConfig.lpszAutoConfigUrl != NULL )
{
autoProxy = true;
autoProxyOptions.lpszAutoConfigUrl = ieProxyConfig.lpszAutoConfigUrl;
}
}
else
{
autoProxy = true;
}
if( autoProxy )
{
// either we use the ie url or we set the auto detect mode
if( autoProxyOptions.lpszAutoConfigUrl != NULL )
{
autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
}
else
{
autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
autoProxyOptions.dwAutoDetectFlags =
WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
}
autoProxyOptions.fAutoLogonIfChallenged = TRUE;
autoProxy =
WinHttpGetProxyForUrl( session, aURL.c_str(), &autoProxyOptions, &autoProxyInfo );
if( session )
{
WinHttpCloseHandle( session );
}
}
if( autoProxy )
{
if( autoProxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY )
{
// autoProxyInfo will return a list of proxies that are semicolon delimited
// todo...maybe figure out better selection logic
wxString proxyList = autoProxyInfo.lpszProxy;
wxStringTokenizer tokenizer( proxyList, ";" );
if( tokenizer.HasMoreTokens() )
{
aCfg.host = tokenizer.GetNextToken();
}
return true;
}
return false;
}
else
{
if( ieProxyConfig.lpszProxy != NULL )
{
// ie proxy configs may return : or :: for an empty proxy
aCfg.host = ieProxyConfig.lpszProxy;
if(aCfg.host != ":" && aCfg.host != "::")
{
return true;
}
}
else
{
return false;
}
}
return false;
}

View File

@ -94,3 +94,9 @@ wxString KIPLATFORM::ENV::GetUserCachePath()
return wxCFStringRef::AsString( ( CFStringRef) url.path ); return wxCFStringRef::AsString( ( CFStringRef) url.path );
} }
bool KIPLATFORM::ENV::GetSystemProxyConfig( const wxString& aURL, PROXY_CONFIG& aCfg )
{
return false;
}