• 获取IE代理服务器信息


      “局域网设置”里有自动配置、代理服务器的设置项目,在进行网络通讯相关的开发时,需要使用到它们,下边介绍如何将这些设置信息读取出来。

      当“使用自动配置脚本”不使用时,使用WinHttpGetIEProxyConfigForCurrentUser函数来获取用户的代理配置。如果发现用户使用了自动配置脚本,那么就需要使用API
    WinHttpGetProxyForUrl去获取某个url对应的代理。获取到代理之后需要考虑:1、是否需要拆分http、https、ftp、socks;2、hostname是否在“例外”中,需要考虑bypass有"<local>"的处理。

        补充:使用自动配置脚本(也就是使用PAC文件)注意:1、IE设置里的pac文件路径不能是本地磁盘路径,否则WinHttpGetProxyForUrl函数无法正确执行;2、WinHttpGetProxyForUrl的第二个参数必须是http/https开头的完整路径。

      核心API就仅仅是WinHttpGetIEProxyConfigForCurrentUser和WinHttpGetProxyForUrl,可以在chromium中搜索这两关键函数获取chromium的实现代码。

      我使用的部分代码:

    std::wstring CIEProxy::GetIEProxy( const std::wstring& strURL, const E_proxy_type& eProxyType )
        {
            std::wstring strRet_cswuyg;
            WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions = {0};
            WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxyConfig = {0};
            BOOL bAutoDetect = FALSE; //“自动检测设置”,但有时候即便选择上也会返回0,所以需要根据url判断
            if(::WinHttpGetIEProxyConfigForCurrentUser(&ieProxyConfig))
            {
                if(ieProxyConfig.fAutoDetect)
                {
                    bAutoDetect = TRUE;
                }
                if( ieProxyConfig.lpszAutoConfigUrl != NULL )
                {
                    bAutoDetect = TRUE;
                    autoProxyOptions.lpszAutoConfigUrl = ieProxyConfig.lpszAutoConfigUrl;
                }
            }
            else
            {
                // error
                return strRet_cswuyg;
            }
    
            if(bAutoDetect)
            {
                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;
                HINTERNET hSession = ::WinHttpOpen(0, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, 
                    WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_ASYNC);
                if (hSession != NULL)
                {
                    WINHTTP_PROXY_INFO autoProxyInfo = {0};
                    bAutoDetect = ::WinHttpGetProxyForUrl(hSession, strURL.c_str(), &autoProxyOptions, &autoProxyInfo);
                    if (hSession!= NULL) 
                    {
                        ::WinHttpCloseHandle(hSession);
                    }
                    if(autoProxyInfo.lpszProxy)
                    {
                        if (autoProxyInfo.lpszProxyBypass == NULL || CheckPassBy(strURL, autoProxyInfo.lpszProxyBypass))
                        {
                            std::wstring strProxyAddr = autoProxyInfo.lpszProxy;
                            strRet_cswuyg = GetProxyFromString(eProxyType, strProxyAddr);
                        }
                        if(autoProxyInfo.lpszProxy != NULL)
                        {
                            GlobalFree(autoProxyInfo.lpszProxy);
                        }
                        if(autoProxyInfo.lpszProxyBypass !=NULL) 
                        {
                            GlobalFree(autoProxyInfo.lpszProxyBypass); 
                        }
                    }
                }
            }
            else
            {
                if(ieProxyConfig.lpszProxy != NULL)
                {
                    if(ieProxyConfig.lpszProxyBypass == NULL || CheckPassBy(strURL, ieProxyConfig.lpszProxyBypass))
                    {
                        std::wstring strProxyAddr = ieProxyConfig.lpszProxy;
                        strRet_cswuyg = GetProxyFromString(eProxyType, strProxyAddr);
                    }
                }
            }
    
            if(ieProxyConfig.lpszAutoConfigUrl != NULL)
            {
                ::GlobalFree(ieProxyConfig.lpszAutoConfigUrl);
            }
            if(ieProxyConfig.lpszProxy != NULL)
            {
                ::GlobalFree(ieProxyConfig.lpszProxy);
            }
            if(ieProxyConfig.lpszProxyBypass != NULL)
            {
                ::GlobalFree(ieProxyConfig.lpszProxyBypass);
            }
    
            return strRet_cswuyg;
        }

       插入:WinHTTP部分,WinHttpGetDefaultProxyConfiguration 用于从注册表获取WinHTTP的代理设置。这个代理设置是通过WinHttpSetDefaultProxyConfiguration或者ProxyCfg.exe设置的。跟IE代理不同。

    参考:

    1、chromium源码:

    chromium/src/net/proxy/proxy_resolver_winhttp.cc

    chromium/src/net/proxy/proxy_config.cc

    chromium/src/net/proxy/proxy_bypass_rules.h

    2、MSDN:

    3、零碎资源:

    http://stackoverflow.com/questions/202547/how-do-i-find-out-the-browsers-proxy-settings

    http://www.cnblogs.com/chang290/archive/2013/01/12/2857426.html

  • 相关阅读:
    sqlalchemy 转json 的几种常用方式
    程序员的思维模型指南
    软件的本质
    Python数据模型及Pythonic编程
    Linux Kernel C语言编程范式
    U-Boot内存管理
    Linux网络文件系统的实现与调试
    Linux内核内存管理架构
    Linux多核并行编程关键技术
    Go/Python/Erlang编程语言对比分析及示例
  • 原文地址:https://www.cnblogs.com/cswuyg/p/3164207.html
Copyright © 2020-2023  润新知