95 lines
3.4 KiB
C++
95 lines
3.4 KiB
C++
/*! @file
|
|
|
|
@id $Id$
|
|
*/
|
|
// 1 2 3 4 5 6 7 8
|
|
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
|
|
|
#ifndef PROXY_WINDOZE_HXX
|
|
#define PROXY_WINDOZE_HXX
|
|
|
|
#ifdef DATADIR
|
|
#undef DATADIR
|
|
#endif
|
|
#include <windows.h>
|
|
#include <winhttp.h>
|
|
|
|
#include <iostream> // debug
|
|
|
|
namespace proxy {
|
|
|
|
class Windoze: public Interface {
|
|
|
|
public:
|
|
|
|
Windoze() {}
|
|
|
|
virtual ~Windoze() {}
|
|
|
|
//! Implemented using M$ WinHTTP
|
|
virtual List proxies(const std::string& url) {
|
|
|
|
List res;
|
|
|
|
WINHTTP_PROXY_INFO proxyInfo;
|
|
ZeroMemory(&proxyInfo, sizeof(proxyInfo));
|
|
HINTERNET hHttpSession(WinHttpOpen(L"WinHTTP AutoProxy/1.0",
|
|
WINHTTP_ACCESS_TYPE_NO_PROXY,
|
|
WINHTTP_NO_PROXY_NAME,
|
|
WINHTTP_NO_PROXY_BYPASS,
|
|
0));
|
|
try {
|
|
if (!hHttpSession) throw exc::error();
|
|
|
|
WINHTTP_AUTOPROXY_OPTIONS AutoProxyOptions;
|
|
ZeroMemory(&AutoProxyOptions, sizeof(AutoProxyOptions));
|
|
AutoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
|
|
AutoProxyOptions.dwAutoDetectFlags =
|
|
WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
|
|
AutoProxyOptions.fAutoLogonIfChallenged = FALSE;
|
|
|
|
if (!WinHttpGetProxyForUrl(hHttpSession,
|
|
std::wstring(url.begin(),
|
|
url.end()).data(),
|
|
&AutoProxyOptions, &proxyInfo))
|
|
throw exc::error();
|
|
|
|
std::wstring list(proxyInfo.lpszProxy);
|
|
std::wcout<<"LIST=\""<<list<<"\""<<std::endl;
|
|
for (std::wstring::size_type oldpos(0), pos(0);
|
|
(pos=list.find(L";", oldpos)), oldpos!=std::wstring::npos;
|
|
oldpos=(pos!=std::wstring::npos?pos+1:pos)) {
|
|
std::wstring proxy(list.substr(oldpos, pos-oldpos));
|
|
std::wstring port((oldpos=proxy.rfind(L":"))!=std::wstring::npos
|
|
?proxy.substr(oldpos+1):std::wstring());
|
|
std::wstring host(proxy.substr(0, proxy.rfind(L":")));
|
|
Type type(DIRECT);
|
|
switch (proxyInfo.dwAccessType) { //! @todo use or remove
|
|
case WINHTTP_ACCESS_TYPE_NO_PROXY: type=DIRECT; break;
|
|
case WINHTTP_ACCESS_TYPE_DEFAULT_PROXY: type=DEFAULT; break;
|
|
case WINHTTP_ACCESS_TYPE_NAMED_PROXY: type=HTTP; break;
|
|
}
|
|
if (host.size()>0)
|
|
res.push_back(Proxy(type,
|
|
std::string(host.begin(), host.end()),
|
|
std::string(port.begin(), port.end())));
|
|
}
|
|
if (!res.size()) res.push_back(Proxy());
|
|
|
|
if (proxyInfo.lpszProxy) GlobalFree(proxyInfo.lpszProxy);
|
|
if (proxyInfo.lpszProxyBypass) GlobalFree(proxyInfo.lpszProxyBypass);
|
|
if (hHttpSession) WinHttpCloseHandle(hHttpSession);
|
|
} catch (...) {
|
|
if (proxyInfo.lpszProxy) GlobalFree(proxyInfo.lpszProxy);
|
|
if (proxyInfo.lpszProxyBypass) GlobalFree(proxyInfo.lpszProxyBypass);
|
|
if (hHttpSession) WinHttpCloseHandle(hHttpSession);
|
|
if (!res.size()) res.push_back(Proxy()); // try direct acces
|
|
}
|
|
|
|
return res;
|
|
}
|
|
};
|
|
}
|
|
|
|
#endif
|