Code to send an HTTP request through a proxy using

2019-08-11 22:09发布

问题:

I am using the Winhttp.lib library to send an HTTP request in C++ to a remote server.

On the client side, the HTTP request has to be sent to a proxy which IP is W.X.Y.Z and which port is 1234.

According to the prototype of the function WinHttpOpen() (https://msdn.microsoft.com/en-us/library/windows/desktop/aa384098%28v=vs.85%29.aspx), in particular the parameters dwAccessType, pwszProxyName and pwszProxyBypass, it looks like this is the function which has to be told about the proxy.

How do I tell the WinHttpOpen() function that the proxy to send the HTTP request to is (IP = W.X.Y.Z, PORT = 1234)?

The structure WINHTTP_PROXY_INFO (https://msdn.microsoft.com/en-us/library/windows/desktop/aa383912%28v=vs.85%29.aspx) looks interesting but I do know how to use it in combination with WinHttpOpen().

Thank you.

回答1:

Have you tried WinHttpSetOption with the WINHTTP_OPTION_PROXY flag? It would look roughly like this:

    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));

        [ ... ]
    }

The above would set your session to use two proxies... 127.0.0.1:1234, and blarg.com:4545. You can also change the scheme using https if you need. It would set parameters for the proxy username and password using the WINHTTP_OPTION_PROXY_USERNAME, and WINHTTP_OPTION_PROXY_PASSWORD options.

Please note I've performed little to no error checking. You would normally want to ensure the options were set properly, etc.



回答2:

You might also consider this page on MSDN:

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

It has a full example of working with proxies that is safer than the one I presented earlier, as it does not send username/passwords in the clear, if I understand the API correctly.

They recommend using WinHttpSetCredentials with WINHTTP_AUTH_TARGET_PROXY on the handle to the request (not the session's handle). To do this, though, you'll need to give WinHttpSetCredentials the authentication scheme you want. WinHttpQueryAuthSchemes can help you do this.

Note that the sample code is in a loop... the first request for the page may give you a status code that indicates you need to supply proxy authentication (407), and should possess the kind of authentication it wants. The subsequent request can use the desired authentication scheme.