http://blog.csdn.net/cnjet/article/details/8284127
所有的网络程序使用HTTP服务时,必然会遇到可能需要检测代理服务器的情况,程序可以提供界面供玩家设置,但是更常用的一种方式是自动检测IE浏览器的代理设置,并以此为代理来设置应用程序的代理信息,Opera, Firefox, Chrome等主流浏览器都是如此。以下程序使用WinHTTP的API实现自动的代理检测,支持“自动检测”,“自动检测代理文件”,“手动设置”,无代理等各种情况。
[cpp] view plaincopy
- int GetHTTPProxyFromIE(const WCHAR* url, /*out*/std::wstring &server )
- {
- BOOL auto_proxy = FALSE;
- WINHTTP_AUTOPROXY_OPTIONS auto_proxy_option;
- WINHTTP_PROXY_INFO auto_proxy_info;
- ZeroMemory( &auto_proxy_option, sizeof(WINHTTP_AUTOPROXY_OPTIONS) );
- ZeroMemory( &auto_proxy_info, sizeof(WINHTTP_PROXY_INFO) );
- //
- // convert URL from mbs to wchar
- //
- const WCHAR* url_request = L"http://www.youtube.com";
- if( NULL!=url && wcslen(url)>0 )
- url_request = url;
- server = L"";
- //
- // Create the WinHTTP session.
- //
- HINTERNET http_session = WinHttpOpen( L"ProxyDetect/1.0",
- WINHTTP_ACCESS_TYPE_NO_PROXY,
- WINHTTP_NO_PROXY_NAME,
- WINHTTP_NO_PROXY_BYPASS,
- 0 );
- if( NULL==http_session ) {
- return -2;
- }
- if (!WinHttpSetTimeouts( http_session, 30000, 30000, 0, 0)) {
- printf( "Error %u in WinHttpSetTimeouts.\n", GetLastError());
- WinHttpCloseHandle(http_session);
- return -3;
- }
- //
- // Check if need auto proxy.
- //
- WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_config;
- if( WinHttpGetIEProxyConfigForCurrentUser(&ie_config) ) {
- if( ie_config.fAutoDetect )
- auto_proxy = TRUE;
- if( NULL!=ie_config.lpszAutoConfigUrl ) {
- auto_proxy = TRUE;
- auto_proxy_option.lpszAutoConfigUrl = ie_config.lpszAutoConfigUrl;
- }
- } else {
- // Error, Try to auto proxy.
- auto_proxy = TRUE;
- }
- //
- // request auto detect to get proxy info.
- //
- if( auto_proxy ) {
- // Setting auto detect options
- if( NULL!=auto_proxy_option.lpszAutoConfigUrl ) {
- auto_proxy_option.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
- } else {
- auto_proxy_option.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
- auto_proxy_option.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP|WINHTTP_AUTO_DETECT_TYPE_DNS_A;
- }
- // basic flags you almost always want
- auto_proxy_option.fAutoLogonIfChallenged = TRUE;
- // here we reset fAutoProxy in case an auto-proxy isn‘t actually
- // configured for this URL
- auto_proxy = WinHttpGetProxyForUrl(http_session, url_request, &auto_proxy_option, &auto_proxy_info );
- }
- //
- // Output result
- //
- if( auto_proxy ) {
- // set proxy options based on auto proxy info.
- server = auto_proxy_info.lpszProxy;
- } else if( NULL!=ie_config.lpszProxy ) {
- // IE has an explicit proxy. set proxy options for libcurl here
- // based on ieProxyConfig
- //
- // note that sometimes IE gives just a single or double colon
- // for proxy or bypass list, which means "no proxy"
- server = ie_config.lpszProxy;
- } else {
- // there is no auto proxy and no manually configured proxy
- }
- //
- // Clean up.
- //
- if( ie_config.lpszAutoConfigUrl != NULL )
- GlobalFree(ie_config.lpszAutoConfigUrl);
- if( auto_proxy_info.lpszProxy != NULL )
- GlobalFree(auto_proxy_info.lpszProxy);
- if( auto_proxy_info.lpszProxyBypass != NULL )
- GlobalFree( auto_proxy_info.lpszProxyBypass );
- if( http_session != NULL )
- WinHttpCloseHandle( http_session );
- return 0;
- }
源代码
----------------------------------------
int GetHTTPProxyFromIE(const WCHAR* url, /*out*/std::wstring &server )
{
BOOL auto_proxy = FALSE;
WINHTTP_AUTOPROXY_OPTIONS auto_proxy_option;
WINHTTP_PROXY_INFO auto_proxy_info;
ZeroMemory( &auto_proxy_option, sizeof(WINHTTP_AUTOPROXY_OPTIONS) );
ZeroMemory( &auto_proxy_info, sizeof(WINHTTP_PROXY_INFO) );
//
// convert URL from mbs to wchar
//
const WCHAR* url_request = L"http://www.youtube.com";
if( NULL!=url && wcslen(url)>0 )
url_request = url;
server = L"";
//
// Create the WinHTTP session.
//
HINTERNET http_session = WinHttpOpen( L"ProxyDetect/1.0",
WINHTTP_ACCESS_TYPE_NO_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
0 );
if( NULL==http_session ) {
return -2;
}
if (!WinHttpSetTimeouts( http_session, 30000, 30000, 0, 0)) {
printf( "Error %u in WinHttpSetTimeouts.\n", GetLastError());
WinHttpCloseHandle(http_session);
return -3;
}
//
// Check if need auto proxy.
//
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_config;
if( WinHttpGetIEProxyConfigForCurrentUser(&ie_config) ) {
if( ie_config.fAutoDetect )
auto_proxy = TRUE;
if( NULL!=ie_config.lpszAutoConfigUrl ) {
auto_proxy = TRUE;
auto_proxy_option.lpszAutoConfigUrl = ie_config.lpszAutoConfigUrl;
}
} else {
// Error, Try to auto proxy.
auto_proxy = TRUE;
}
//
// request auto detect to get proxy info.
//
if( auto_proxy ) {
// Setting auto detect options
if( NULL!=auto_proxy_option.lpszAutoConfigUrl ) {
auto_proxy_option.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
} else {
auto_proxy_option.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
auto_proxy_option.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP|WINHTTP_AUTO_DETECT_TYPE_DNS_A;
}
// basic flags you almost always want
auto_proxy_option.fAutoLogonIfChallenged = TRUE;
// here we reset fAutoProxy in case an auto-proxy isn‘t actually
// configured for this URL
auto_proxy = WinHttpGetProxyForUrl(http_session, url_request, &auto_proxy_option, &auto_proxy_info );
}
//
// Output result
//
if( auto_proxy ) {
// set proxy options based on auto proxy info.
server = auto_proxy_info.lpszProxy;
} else if( NULL!=ie_config.lpszProxy ) {
// IE has an explicit proxy. set proxy options for libcurl here
// based on ieProxyConfig
//
// note that sometimes IE gives just a single or double colon
// for proxy or bypass list, which means "no proxy"
server = ie_config.lpszProxy;
} else {
// there is no auto proxy and no manually configured proxy
}
//
// Clean up.
//
if( ie_config.lpszAutoConfigUrl != NULL )
GlobalFree(ie_config.lpszAutoConfigUrl);
if( auto_proxy_info.lpszProxy != NULL )
GlobalFree(auto_proxy_info.lpszProxy);
if( auto_proxy_info.lpszProxyBypass != NULL )
GlobalFree( auto_proxy_info.lpszProxyBypass );
if( http_session != NULL )
WinHttpCloseHandle( http_session );
return 0;
}
参考信息:
http://curl.haxx.se/mail/lib-2001-08/att-0170/winproxy.c
http://stackoverflow.com/questions/202547/how-do-i-find-out-the-browsers-proxy-settings