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"