使用 WinHttp 通过代理发送 HTTP 请求的代码

Code to send an HTTP request through a proxy using WinHttp

本文关键字:HTTP 请求 代码 WinHttp 代理 使用      更新时间:2023-10-16

我正在使用Winhttp.lib库将C++中的HTTP请求发送到远程服务器。

在客户端,HTTP请求必须发送到代理,哪个IP W.X.Y.Z,哪个端口1234

根据函数WinHttpOpen()(https://msdn.microsoft.com/en-us/library/windows/desktop/aa384098%28v=vs.85%29.aspx)的原型,特别是参数dwAccessTypepwszProxyNamepwszProxyBypass,看起来这是必须告诉代理的函数。

如何告诉WinHttpOpen()函数要将 HTTP 请求发送到的代理(IP = W.X.Y.Z, PORT = 1234)

结构WINHTTP_PROXY_INFO(https://msdn.microsoft.com/en-us/library/windows/desktop/aa383912%28v=vs.85%29.aspx)看起来很有趣,但我确实知道如何将其与WinHttpOpen()结合使用。

谢谢。

您是否尝试过带有WINHTTP_OPTION_PROXY标志的WinHttpSetOption? 它大致看起来像这样:

    hSession = WinHttpOpen(L"WinHTTP Example/1.0",
        WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
        WINHTTP_NO_PROXY_NAME,
        WINHTTP_NO_PROXY_BYPASS, 0);        
    WINHTTP_PROXY_INFO proxy = { 0 };
    proxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
    proxy.lpszProxy = L"http://127.0.0.1:1234;http://blarg.com:4545";
    if (!WinHttpSetOption(hSession, WINHTTP_OPTION_PROXY, &proxy, sizeof(proxy)))
    {
        wprintf(L"Unable to set proxy.n");
    }
    else
    {
        HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"GET", NULL, NULL,
            WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
        char* username = "username";
        WinHttpSetOption(hRequest, WINHTTP_OPTION_PROXY_USERNAME, username, strlen(username));
        WinHttpSetOption(hRequest, WINHTTP_OPTION_PROXY_PASSWORD, password, strlen(password));
        [ ... ]
    }

以上将设置您的会话以使用两个代理...127.0.0.1:1234 和 blarg.com:4545。 如果需要,您还可以使用 https 更改方案。 它将使用WINHTTP_OPTION_PROXY_USERNAME和WINHTTP_OPTION_PROXY_PASSWORD选项为代理用户名和密码设置参数。

请注意,我几乎没有执行错误检查。 您通常希望确保正确设置选项等。

您也可以考虑 MSDN 上的此页面:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa384100(v=vs.85).aspx

它有一个使用代理的完整示例,比我之前介绍的代理更安全,因为如果我正确理解 API,它不会以明文形式发送用户名/密码。

他们建议在请求的句柄(而不是会话的句柄)上使用带有WINHTTP_AUTH_TARGET_PROXY的 WinHttpSetCredentials。 但是,要执行此操作,您需要为 WinHttpSetCredentials 提供所需的身份验证方案。 WinHttpQueryAuthSchemes可以帮助您做到这一点。

请注意,示例代码处于循环中...对页面的第一个请求可能会为您提供一个状态代码,指示您需要提供代理身份验证 (407),并且应该拥有它想要的身份验证类型。 后续请求可以使用所需的身份验证方案。