Search code examples
c++boostboost-asio

Creating a HTTPS request using Boost Asio and OpenSSL


I have created a simple HTTP request wherein I am sending GET,POST and PUT requests to the server. Next I want to switch to HTTPS connection using boost asio library, how should I proceed?

I have an Executor Class that resolves and connects to the server and a RequestCreator Class that creates the request.


Solution

  • I happen to just have posted such a thing in a comment (...):

    You just connect over ssl. @Milind coliru.stacked-crooked.com/a/9546326fd1def416

    So perhaps it is helpful to you.

    Live On Coliru

    #include <boost/asio.hpp>
    #include <boost/asio/ssl.hpp>
    #include <iostream>
    
    int main() {
        boost::system::error_code ec;
        using namespace boost::asio;
    
        // what we need
        io_service svc;
        ssl::context ctx(svc, ssl::context::method::sslv23_client);
        ssl::stream<ip::tcp::socket> ssock(svc, ctx);
        ssock.lowest_layer().connect({ {}, 8087 }); // http://localhost:8087 for test
        ssock.handshake(ssl::stream_base::handshake_type::client);
    
        // send request
        std::string request("GET /newGame?name=david HTTP/1.1\r\n\r\n");
        boost::asio::write(ssock, buffer(request));
    
        // read response
        std::string response;
    
        do {
            char buf[1024];
            size_t bytes_transferred = ssock.read_some(buffer(buf), ec);
            if (!ec) response.append(buf, buf + bytes_transferred);
        } while (!ec);
    
        // print and exit
        std::cout << "Response received: '" << response << "'\n";
    }
    

    To emulate a server for demo purposes I've been using the certificate and params from the Asio samples (https://stackoverflow.com/a/31201907/85371).

    UPDATE Here's a version that uses resolver to resolve the endpoint (Coliru doesn't allow us to do that, but it does work on non-restricted machines).

    Live On Coliru

    ip::tcp::resolver resolver(svc);
    auto it = resolver.resolve({"localhost", "8087"}); // http://localhost:8087 for test
    boost::asio::connect(ssock.lowest_layer(), it);
    
    // and the rest unaltered
    ssock.handshake(ssl::stream_base::handshake_type::client);