Minimal boost::beast HTTPS client JSON example
This example uses boost::beast
to make a HTTPS request to ipify.org and parses the response using boost::json
.
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <boost/beast/core.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/json.hpp>
#include <openssl/ssl.h>
namespace beast = boost::beast;
namespace http = beast::http;
namespace net = boost::asio;
namespace ip = boost::asio::ip;
namespace ssl = boost::asio::ssl;
namespace json = boost::json;
using tcp = boost::asio::ip::tcp;
int main()
{
std::string host = "api64.ipify.org";
// Initialize IO context
net::io_context ioc;
ssl::context ctx(ssl::context::tlsv13_client);
ctx.set_default_verify_paths();
// Set up an SSL context
beast::ssl_stream<beast::tcp_stream> stream(ioc, ctx);
stream.set_verify_mode(ssl::verify_none);
stream.set_verify_callback([](bool preverified, ssl::verify_context& ctx) {
return true; // Accept any certificate
});
// Enable SNI
if(!SSL_set_tlsext_host_name(stream.native_handle(), host.c_str())) {
beast::error_code ec{static_cast<int>(::ERR_get_error()), net::error::get_ssl_category()};
throw beast::system_error{ec};
}
// Connect to the HTTPS server
ip::tcp::resolver resolver(ioc);
get_lowest_layer(stream).connect(resolver.resolve({host, "https"}));
get_lowest_layer(stream).expires_after(std::chrono::seconds(30));
// Construct request
http::request<http::empty_body> req{http::verb::get, "/?format=json" , 11};
req.set(http::field::host, host);
req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING);
// Send the request
stream.handshake(ssl::stream_base::client);
http::write(stream, req);
// Receive the response
beast::flat_buffer buffer;
http::response<http::dynamic_body> res;
http::read(stream, buffer, res);
// Parse the JSON response
json::error_code err;
json::value j = json::parse(buffers_to_string(res.body().data()), err);
std::cout << "IP address: " << j.at("ip").as_string() << std::endl;
if (err) {
std::cerr << "Error parsing JSON: " << err.message() << std::endl;
}
// Cleanup
beast::error_code ec;
stream.shutdown(ec);
if (ec == net::error::eof) {
ec = {};
}
if (ec) {
throw beast::system_error{ec};
}
return 0;
}
Compile using
g++ -g -o http-example http-example.cpp -lcrypto -lssl -lboost_json
Example output:
IP address: "2a01:c22:6f8c:ef00:f0bb:a8a8:9c00:ff49"