2

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.

Léa Massiot
  • 1,928
  • 6
  • 25
  • 43

2 Answers2

3

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.

fleebness
  • 109
  • 7
  • Thank you for your answer. I just would like to insist on the fact that the IP and PORT of the proxy are known. But maybe this is not the way WinHttp works... – Léa Massiot Jan 29 '16 at 10:44
  • I've expanded on my original question of whether or not you tried WinHttpSetOption to set a proxy for your session, to make it a tad more helpful. I tried it just now, and it seemed to work (although I don't actually have a legitimate proxy... so my test involved seeing that I couldn't access a web site after I set the option). – fleebness Jan 30 '16 at 11:20
  • Although I am not sure about what you exactly mean by "legitimate proxy", I don't think I have one either: I installed a SQUID proxy on one of the machines (P) in my LAN. The machine which is running the WinHttp code is another machine (C) in the LAN. The remote machine is (S). I need (C) to send a HTTP request to (S) but the request has to be sent to the proxy (P) which will send it to (S). – Léa Massiot Feb 01 '16 at 11:09
  • I thank you for sending me a bit of code (which is useful because I wasn't aware of the WinHttpSetOption() function and the WINHTTP_PROXY_INFO structure) but I would need some more including calls to the WinHttpSetCredentials function. I'll try without setting credentials first. – Léa Massiot Feb 01 '16 at 11:12
  • I started another thread related to this one: http://stackoverflow.com/questions/35134287/winhttpsetoption-winhttp-option-proxy-and-winhttpopen – Léa Massiot Feb 01 '16 at 15:31
  • Well, by 'legitimate proxy', I mean a proxy that this API understands as a proxy. I expect one can find a variety of types of proxies... I suspect this API expect the traditional 'need to go through this proxy to get to the internet at all' style of proxy. I don't know how well it works with SQUID... to me, SQUID looks more like something for a server's end than a client's end. I've added to the code to handle credentials using the same API. Again, I don't have the proxy you require, so I don't know if this is what you need. I hope this helps. And I apologize for the delay. – fleebness Feb 17 '16 at 01:05
0

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.

fleebness
  • 109
  • 7