7

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.

DevMac
  • 131
  • 1
  • 2
  • 9

2 Answers2

12

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);
Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633
  • This dosen't seem to work as i am using resolver and not endpoint tcp::resolver resolver(ioService); tcp::resolver::query query(cli.getIP(), "8080"); – DevMac Oct 18 '16 at 14:04
  • Don't give link to boost website or github sample code, i have tried all of those(almost all) – DevMac Oct 18 '16 at 14:32
  • Do you have any custom code that just makes a connection using resolver @sehe – DevMac Oct 19 '16 at 05:41
  • @DevMac Found the time to answer your comment, see the UPDATE. What online samples have you found that were more confusing than this? – sehe Oct 19 '16 at 21:11
  • You have used auto here which is compiler dependent, right ? – DevMac Oct 21 '16 at 10:47
  • and how do you gracefully close the connection/socket if any error arises ? @sehe – DevMac Oct 21 '16 at 11:34
  • 2
    `auto` is not compiler dependent. It's standards version dependent in the sense that c++11 introduced it. All compilers support it in c++11 mode. What do you mean by graceful close? Perhaps it is time to search for existing answers to your different questions. If all else fails, you can ask a new question – sehe Oct 21 '16 at 12:42
  • I am basically taking the result of resolver.resolve(query) in boost::asio::ip::tcp::resolver::iterator – DevMac Oct 21 '16 at 12:44
  • I just suggested what I think you should do. The comment thread is not well suited as a personal support forum. Also, by reusing/posting questions on the main site you (a) make it possible for many more people to help (b) make it possible for many more people to find your solutions – sehe Oct 21 '16 at 12:46
0

Simple example:

#include<string>
#include<iostream>

#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/beast.hpp>

using namespace boost::beast;
using namespace boost::asio;

using std::string;
using std::cout;


int
main() {

    const string host = "www.google.com";
    const string path = "/";
    const string port = "443";

    io_service svc;

    ssl::context ctx(ssl::context::sslv23_client);
    ssl::stream<ip::tcp::socket> ssocket = { svc, ctx };
    ip::tcp::resolver resolver(svc);
    auto it = resolver.resolve(host, port);
    connect(ssocket.lowest_layer(), it);
    ssocket.handshake(ssl::stream_base::handshake_type::client);
    http::request<http::string_body> req{ http::verb::get, path, 11 };
    req.set(http::field::host, host);
    http::write(ssocket, req);
    http::response<http::string_body> res;
    flat_buffer buffer;
    http::read(ssocket, buffer, res);
    cout << "Headers" << std::endl;
    cout << res.base() << std::endl << std::endl;
    cout << "Body" << std::endl;
    cout << res.body() << std::endl << std::endl;
}