Beispiel #1
0
bool Proxy::ParseWinHttpProxy(LPWSTR lpszProxy, Address &addr)
{
	Assert(lpszProxy);
	String proxy(lpszProxy, lpszProxy + std::char_traits<wchar_t>::length(lpszProxy));
	proxy.toLower();
	size_t pos = proxy.find("http://");
	if(pos != String::NotFound) proxy = proxy.substr(pos + 7);
	else {
		pos = proxy.find("http=");
		if(pos != String::NotFound) proxy = proxy.substr(pos + 5);
	}
	proxy.cut('/'); proxy.cut(','); proxy.cut(' ');

	if(!proxy.empty())
	{
		try {
			addr.fromString(proxy);
			return true;
		}
		catch(...)
		{
			LogDebug("Proxy::ParseWinHtppProxy", "Got invalid proxy address: " + proxy);
		}
	}

	return false;
}
Beispiel #2
0
bool Proxy::GetProxyForUrl(const String &url, Address &addr)
{
	if(HttpProxy == "none")
                return false;

        if(!HttpProxy.empty() && HttpProxy != "auto")
        {
                addr.fromString(HttpProxy);
                return true;
        }
        
#ifdef WINDOWS
	typedef LPVOID HINTERNET;
	
	typedef struct {
		DWORD  dwAccessType;
		LPWSTR lpszProxy;
		LPWSTR lpszProxyBypass;
	} WINHTTP_PROXY_INFO;
	
	typedef struct {
		BOOL   fAutoDetect;
		LPWSTR lpszAutoConfigUrl;
		LPWSTR lpszProxy;
		LPWSTR lpszProxyBypass;
	} WINHTTP_CURRENT_USER_IE_PROXY_CONFIG;
	
	typedef struct {
		DWORD   dwFlags;
		DWORD   dwAutoDetectFlags;
		LPCWSTR lpszAutoConfigUrl;
		LPVOID  lpvReserved;
		DWORD   dwReserved;
		BOOL    fAutoLogonIfChallenged;
	} WINHTTP_AUTOPROXY_OPTIONS;
	
	#define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY	0
	#define WINHTTP_ACCESS_TYPE_NO_PROXY		1
	#define WINHTTP_ACCESS_TYPE_NAMED_PROXY		3
	#define WINHTTP_AUTOPROXY_AUTO_DETECT		0x00000001
	#define WINHTTP_AUTOPROXY_CONFIG_URL		0x00000002
	#define WINHTTP_AUTO_DETECT_TYPE_DHCP		0x00000001
	#define WINHTTP_AUTO_DETECT_TYPE_DNS_A		0x00000002
	#define WINHTTP_ERROR_BASE                      12000
	#define ERROR_WINHTTP_LOGIN_FAILURE             (WINHTTP_ERROR_BASE + 15)
	#define ERROR_WINHTTP_AUTODETECTION_FAILED      (WINHTTP_ERROR_BASE + 180)
	
	typedef HINTERNET (WINAPI *WINHTTPOPEN)(LPCWSTR pwszUserAgent, DWORD dwAccessType, LPCWSTR pwszProxyName, LPCWSTR pwszProxyBypass, DWORD dwFlags);
	typedef BOOL (WINAPI *WINHTTPGETPROXYFORURL)(HINTERNET hSession, LPCWSTR lpcwszUrl, WINHTTP_AUTOPROXY_OPTIONS *pAutoProxyOptions, WINHTTP_PROXY_INFO *pProxyInfo);
	typedef BOOL (WINAPI *WINHTTPGETDEFAULTPROXYCONFIGURATION)(WINHTTP_PROXY_INFO *pProxyInfo);
	typedef BOOL (WINAPI *WINHTTPGETIEPROXYCONFIGFORCURRENTUSER)(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG *pProxyConfig);
	typedef BOOL (WINAPI *WINHTTPCLOSEHANDLE)(HINTERNET hInternet);

	static HMODULE hWinHttp = NULL;
	static WINHTTPOPEN				WinHttpOpen;
	static WINHTTPGETPROXYFORURL			WinHttpGetProxyForUrl;
	static WINHTTPGETDEFAULTPROXYCONFIGURATION	WinHttpGetDefaultProxyConfiguration;
	static WINHTTPGETIEPROXYCONFIGFORCURRENTUSER	WinHttpGetIEProxyConfigForCurrentUser;
	static WINHTTPCLOSEHANDLE			WinHttpCloseHandle;
	
	if(!hWinHttp)
	{
		hWinHttp = LoadLibrary("winhttp.dll");
		if(!hWinHttp) return false;
		
		WinHttpOpen				= (WINHTTPOPEN)					GetProcAddress(hWinHttp, "WinHttpOpen");
		WinHttpGetProxyForUrl			= (WINHTTPGETPROXYFORURL)			GetProcAddress(hWinHttp, "WinHttpGetProxyForUrl");
		WinHttpGetDefaultProxyConfiguration	= (WINHTTPGETDEFAULTPROXYCONFIGURATION)		GetProcAddress(hWinHttp, "WinHttpGetDefaultProxyConfiguration");
		WinHttpGetIEProxyConfigForCurrentUser	= (WINHTTPGETIEPROXYCONFIGFORCURRENTUSER)	GetProcAddress(hWinHttp, "WinHttpGetIEProxyConfigForCurrentUser");
		WinHttpCloseHandle			= (WINHTTPCLOSEHANDLE)				GetProcAddress(hWinHttp, "WinHttpCloseHandle");
	}
	
	bool hasProxy = false;
	std::string ua(Http::UserAgent);
	std::wstring wua(ua.begin(), ua.end());
	HINTERNET hSession = WinHttpOpen(wua.c_str(), WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, NULL, NULL, 0);
	if(hSession)
	{
		WINHTTP_CURRENT_USER_IE_PROXY_CONFIG userProxyConfig;
		bool hasUserProxyConfig = (WinHttpGetIEProxyConfigForCurrentUser(&userProxyConfig) == TRUE);
		
		if(hasUserProxyConfig && !userProxyConfig.fAutoDetect && userProxyConfig.lpszProxy)
		{
			hasProxy = ParseWinHttpProxy(userProxyConfig.lpszProxy, addr);
		}
		else {
			WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions;
			std::memset(&autoProxyOptions, 0, sizeof(autoProxyOptions));
			autoProxyOptions.fAutoLogonIfChallenged = TRUE;
	
			if(hasUserProxyConfig) autoProxyOptions.lpszAutoConfigUrl = userProxyConfig.lpszAutoConfigUrl;
			else autoProxyOptions.lpszAutoConfigUrl = NULL;

			if(autoProxyOptions.lpszAutoConfigUrl)
			{
				autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
				autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP|WINHTTP_AUTO_DETECT_TYPE_DNS_A;
			}
			else {
				autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
				autoProxyOptions.dwAutoDetectFlags = 0;
			}

			WINHTTP_PROXY_INFO proxyInfo;
			std::wstring wurl(url.begin(), url.end());
			if(WinHttpGetProxyForUrl(hSession, wurl.c_str(), &autoProxyOptions, &proxyInfo))
			{
				if(proxyInfo.lpszProxy && proxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY)
					hasProxy = ParseWinHttpProxy(proxyInfo.lpszProxy, addr);

				if(proxyInfo.lpszProxy)         GlobalFree(proxyInfo.lpszProxy);
				if(proxyInfo.lpszProxyBypass)   GlobalFree(proxyInfo.lpszProxyBypass);
			}
			else if(WinHttpGetDefaultProxyConfiguration(&proxyInfo))
			{
				if(proxyInfo.lpszProxy && proxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY)
					hasProxy = ParseWinHttpProxy(proxyInfo.lpszProxy, addr);

				if(proxyInfo.lpszProxy)         GlobalFree(proxyInfo.lpszProxy);
				if(proxyInfo.lpszProxyBypass)   GlobalFree(proxyInfo.lpszProxyBypass);
			}
		}
		
		if(hasUserProxyConfig)
		{
			if(userProxyConfig.lpszProxy)		GlobalFree(userProxyConfig.lpszProxy);
			if(userProxyConfig.lpszProxyBypass)	GlobalFree(userProxyConfig.lpszProxyBypass);
			if(userProxyConfig.lpszAutoConfigUrl)	GlobalFree(userProxyConfig.lpszAutoConfigUrl);
		}

		WinHttpCloseHandle(hSession);
	}
	
	return hasProxy;
#else
	// TODO
	return false;
#endif
}