restc-cpp icon indicating copy to clipboard operation
restc-cpp copied to clipboard

Https proxy (via CONNECT) support

Open uralm1 opened this issue 2 years ago • 0 comments

If someone interested, I have added preliminary HTTPS proxy support, known as CONNECT proxy tunnel. It can be used to pass https requests through http proxy (this is how most proxies are working today).

New proxy type Request::Proxy::Type::HTTPS is added for CONNECT type proxy.

No proxy authentication support done yet. Sorry.

Example: (see https://github.com/jgaa/restc-cpp/blob/master/doc/Tutorial.md#send-a-request-going-trough-a-http-proxy)

// Add the proxy information to the properties used by the client
    Request::Properties properties;
    //// use HTTPS proxy type
    properties.proxy.type = Request::Proxy::Type::HTTPS;
    properties.proxy.address = "http://127.0.0.1:3003";

    //// or detect proxy automatically
    properties.proxy.detect();

    // Create the client with our configuration
    auto rest_client = RestClient::Create(properties);
    rest_client->ProcessWithPromise([&](Context& ctx) {
        // Here we are again in a co-routine, running in a worker-thread.
        // Asynchronously connect to a server trough a HTTP proxy and fetch some data.
        auto reply = RequestBuilder(ctx)
            ////
            //// https request is passed via http proxy CONNECT tunnel
            ////
            .Get("https://api.example.com/normal/posts/1")

            // Send the request.
            .Execute();
        // Dump the data
        cout << "Got: " << reply->GetBodyAsString();
    }).get();

Also I changed TlsSocket class, so we can pass unencrypted data over TLS socket before tls handshake is done. Otherwise we get tls unintialized protocol error (I know, code is imperfect, more ideas are welcome).

Though I haven't done much testing, sequental proxied requests correctly use the same cached connection to proxy. If we send proxied requests asyncronously in parallel, they will open new proxy tunnels one for each request.

Testing nginx container is modified so it will serve https requests. Benefit from this, old https tests can be rewritten to request the local nginx instead of the public internet.

uralm1 avatar Aug 29 '23 12:08 uralm1