WinHttpGetProxyForUrl获取到的数据始终为null

问题描述 投票:0回答:1

我有以下代码:

#ifndef UNICODE
#define UNICODE
#endif

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0A00
#endif

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>
#include <winhttp.h>
#include <string>
#include <iostream>

#pragma comment(lib, "winhttp.lib")

int wmain(int argc, wchar_t* argv[]) {
    if (argc != 2) {
        std::wcerr << L"Parameters: <Domain>" << std::endl;
        return 1;
    }

    // Get proxy settings
    WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ProxyConfig;
    ZeroMemory(&ProxyConfig, sizeof(ProxyConfig));
    if (!WinHttpGetIEProxyConfigForCurrentUser(&ProxyConfig)) {
        std::wcerr << L"WinHttpGetIEProxyConfigForCurrentUser failed, error: "
            << GetLastError() << std::endl;
        return 1;
    }

    if (ProxyConfig.lpszProxy != NULL) {
        // Check bypass list
        if (ProxyConfig.lpszProxyBypass != NULL) {
            wchar_t* domain = wcstok(ProxyConfig.lpszProxyBypass, L";");

            while (domain != NULL) {
                if (wcscmp(domain, argv[1]) == 0) {
                    std::wcout << L"Proxy Bypass" << std::endl;
                    GlobalFree(ProxyConfig.lpszProxy);
                    GlobalFree(ProxyConfig.lpszProxyBypass);
                    return 0;
                }

                domain = wcstok(NULL, L";");
            }

            GlobalFree(ProxyConfig.lpszProxyBypass);
        }

        std::wcout << L"Proxy: " << ProxyConfig.lpszProxy << std::endl;
        GlobalFree(ProxyConfig.lpszProxy);
        return 0;
    }

    // Set AUTOPROXY options
    WINHTTP_AUTOPROXY_OPTIONS AutoProxyOptions;
    ZeroMemory(&AutoProxyOptions, sizeof(AutoProxyOptions));
    if (ProxyConfig.fAutoDetect) {
        AutoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
        AutoProxyOptions.dwAutoDetectFlags =
            WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
    }
    if (ProxyConfig.lpszAutoConfigUrl != NULL) {
        AutoProxyOptions.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL;
        AutoProxyOptions.lpszAutoConfigUrl = ProxyConfig.lpszAutoConfigUrl;

    }
    if (AutoProxyOptions.dwFlags == NULL) {
        std::wcout << L"No Proxy" << std::endl;
        return 0;
    }
    AutoProxyOptions.fAutoLogonIfChallenged = TRUE;

    // Create WinHTTP session
    HINTERNET hSession = WinHttpOpen(
        L"Windows",
        WINHTTP_ACCESS_TYPE_NO_PROXY,
        WINHTTP_NO_PROXY_NAME,
        WINHTTP_NO_PROXY_BYPASS,
        0
    );
    if (hSession == NULL) {
        std::wcerr << L"WinHttpOpen failed, error: "
            << GetLastError() << std::endl;
        return 1;
    }

    // Get proxy info from PAC
    std::wstring wurl = L"http://" + (std::wstring)argv[1] + L"/";
    WINHTTP_PROXY_INFO ProxyInfo;
    ZeroMemory(&ProxyInfo, sizeof(ProxyInfo));
    if (!WinHttpGetProxyForUrl(
        hSession,
        wurl.c_str(),
        &AutoProxyOptions,
        &ProxyInfo
    )) {
        std::wcerr << L"WinHttpGetProxyForUrl failed, error: "
            << GetLastError() << std::endl;
        WinHttpCloseHandle(hSession);
        return 1;
    }

    // ProxyInfo.lpszProxy contains the address of the proxy server
    if (ProxyInfo.lpszProxy != NULL) {
        std::wcout << L"Proxy: " << ProxyInfo.lpszProxy << std::endl;
        GlobalFree(ProxyInfo.lpszProxy);
    } else {
        std::wcout << L"Proxy: NULL" << std::endl;
    }

    // Cleanup
    if (ProxyConfig.lpszAutoConfigUrl != NULL) {
        GlobalFree(ProxyConfig.lpszAutoConfigUrl);
    }

    WinHttpCloseHandle(hSession);

    return 0;
}

它使用

WinHttpGetProxyForUrl
函数根据系统设置检索 PAC 文件中指定的代理服务器地址。

WinHttpGetProxyForUrl
函数执行成功,没有返回错误,但给定的
ProxyInfo.lpszProxy
变量值始终为空。

以下是我使用的原始PAC文件的内容:

var pHost = "Proxy.local";
var pPort = "1080";
var Socks5 = "SOCKS5 " + pHost + ":" + pPort + "; ";
var Socks = "SOCKS " + pHost + ":" + pPort + "; ";
var Direct = "DIRECT; ";

function FindProxyForURL(url, host) {
        if (shExpMatch(dnsResolveEx(host), "*.*.*.*")) {
                return Socks5 + Socks + Direct;
        } else {
                return Direct;
        }
}

以下是始终返回代理服务器的 PAC 文件的简化版本:

function FindProxyForURL(url, host) {
    return "SOCKS Proxy.local:1080";
}

我都尝试过,但是

ProxyInfo.lpszProxy
变量仍然为空。

我的代码是否存在问题,或者

WinHttpGetProxyForUrl
函数是否表现出意外行为?

c++ windows winapi winhttp pac
1个回答
0
投票

我已经重现了您的问题。 ProxyInfo.lpszProxy 为 NULL 的原因是您在 WinHttpGetProxyForUrl 函数中设置了错误的 lpcwszUrl 地址。

您应该将其设置为被代理的目标的地址。而不是服务器代理地址。 那么输出指针不为NULL。

在我的pac文件中,我使用localhost:8000来代理baidu.com。

function FindProxyForURL(url, host) {
 if (shExpMatch(url, "*baidu.com*")){
    return "PROXY localhost:8000; DIRECT";
 }else{
    return "DIRECT";
 }
}
© www.soinside.com 2019 - 2024. All rights reserved.