Error in SSL handshake for consecutive requests

Feb 8, 2015 at 6:30 PM
Edited Feb 8, 2015 at 6:31 PM

I'm getting "Error in SSL handshake" after requesting with my http_client instance twice on iOS/simulator (casablanca commit 219daed12e45). SSL certificate on my server is valid. I tried to pass to the client a custom http_client_config object with validate_certificates set to false but no dice. It doesn't want to work unless I recreate the client with exactly the same settings (well, basically the base_url) before the second request. Has anyone seen this behavior? Here's a code snippet:
http_client_config config;
http_client client(base_url, config);
client.request(methods::GET, build_org_context(org_name)).then([=] (http_response response) {
    return response.extract_json();
}).then([=] (value json) {
    return json[U("links")][U("token")].as_string();
}).then([=] (string_t token) mutable {
    http_request request(methods::POST);
    request.headers().add(U("Content-Type"), U("application/x-www-form-urlencoded"));
    request.set_body(build_auth_body(user, pass));

    // comment out to reproduce
    http_client client(base_url, config);
    return client.request(request);
}).then([=] (http_response response) {
    return response.extract_json();
Feb 16, 2015 at 3:13 PM
Hello, Marcin

Recently I start to use Casablanca on iOS too and I face the same challenge. I have only one http_client object in heap, configured on specific HTTPS host uri and perform several requests one by one. Certainly the "Connection" header of requests is "Keep-alive"(as I understood casablanca make it by itself). So, every second request failed with "Error in SSL handshake".
If use individual http_client object for every http_request everything is fine but there is no keep-alive permanent connection. Also if use only one http_client with HTTP url scheme instead of HTTPS - everything is fine too, but there is no ssl.

I explored casablanca sources and found some interesting moment in http_client_asio.cpp:
void write_request()
        if (m_connection->is_ssl())
            const auto weakCtx = std::weak_ptr<asio_context>(shared_from_this());
            m_connection->async_handshake(boost::asio::ssl::stream_base::client, ...........
            m_connection->async_write(m_body_buf, boost::bind(&asio_context::handle_write_headers, shared_from_this(), boost::asio::placeholders::error));
It turn outs that every request even in one connection do async_handshake. When i change it to that (see code below), combination https + keep-alive starts working correctly:
void write_request()
        if (m_connection->is_ssl() && !m_connection->is_reused())
I don't know absolutely right this fix or no. May be someone from contributors can answer this question here?
Feb 16, 2015 at 4:44 PM
Hi mlu and overinc,

This thread escaped my attention last week. What version of the C++ REST SDK are you both using?

Feb 16, 2015 at 5:37 PM
Hi, stevetgates

I use the latest stable version from this site - 2.4.0
Feb 16, 2015 at 8:01 PM
And I was using the master branch, commit 219daed12e45.
Feb 18, 2015 at 4:28 AM
Hi overinc,

OK, I got some time to take a look at this bug and that indeed is the problem. If TLS is enabled and a connection ends up getting reused from the pool then it is attempting to perform the handshake again. I do think you mentioned change is the correct fix. I've implemented the same and I'm running some tests now.

This is actually quite a bad bug. Thanks for reporting it. It will be fixed in the development branch in the next day or so, I'll update this thread once in place.

Feb 18, 2015 at 4:36 AM
Thank you Steve for your attention to this problem!
Feb 18, 2015 at 11:36 PM
FYI the fix is now in the development branch, and will eventually be in release 2.5.0.

Feb 19, 2015 at 6:29 PM
Great, thanks!