diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/beast/example/http/client/async | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/beast/example/http/client/async')
3 files changed, 227 insertions, 0 deletions
diff --git a/src/boost/libs/beast/example/http/client/async/CMakeLists.txt b/src/boost/libs/beast/example/http/client/async/CMakeLists.txt new file mode 100644 index 00000000..3847ce61 --- /dev/null +++ b/src/boost/libs/beast/example/http/client/async/CMakeLists.txt @@ -0,0 +1,23 @@ +# +# Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com) +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# +# Official repository: https://github.com/boostorg/beast +# + +GroupSources(include/boost/beast beast) +GroupSources(example/http/client/async "/") + +add_executable (http-client-async + ${BOOST_BEAST_FILES} + Jamfile + http_client_async.cpp +) + +target_link_libraries(http-client-async + lib-asio + lib-beast) + +set_property(TARGET http-client-async PROPERTY FOLDER "example-http-client") diff --git a/src/boost/libs/beast/example/http/client/async/Jamfile b/src/boost/libs/beast/example/http/client/async/Jamfile new file mode 100644 index 00000000..abc9d4d6 --- /dev/null +++ b/src/boost/libs/beast/example/http/client/async/Jamfile @@ -0,0 +1,15 @@ +# +# Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com) +# +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# +# Official repository: https://github.com/boostorg/beast +# + +exe http-client-async : + http_client_async.cpp + : + <variant>coverage:<build>no + <variant>ubasan:<build>no + ; diff --git a/src/boost/libs/beast/example/http/client/async/http_client_async.cpp b/src/boost/libs/beast/example/http/client/async/http_client_async.cpp new file mode 100644 index 00000000..f451df51 --- /dev/null +++ b/src/boost/libs/beast/example/http/client/async/http_client_async.cpp @@ -0,0 +1,189 @@ +// +// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/beast +// + +//------------------------------------------------------------------------------ +// +// Example: HTTP client, asynchronous +// +//------------------------------------------------------------------------------ + +#include <boost/beast/core.hpp> +#include <boost/beast/http.hpp> +#include <boost/beast/version.hpp> +#include <boost/asio/strand.hpp> +#include <cstdlib> +#include <functional> +#include <iostream> +#include <memory> +#include <string> + +namespace beast = boost::beast; // from <boost/beast.hpp> +namespace http = beast::http; // from <boost/beast/http.hpp> +namespace net = boost::asio; // from <boost/asio.hpp> +using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp> + +//------------------------------------------------------------------------------ + +// Report a failure +void +fail(beast::error_code ec, char const* what) +{ + std::cerr << what << ": " << ec.message() << "\n"; +} + +// Performs an HTTP GET and prints the response +class session : public std::enable_shared_from_this<session> +{ + tcp::resolver resolver_; + beast::tcp_stream stream_; + beast::flat_buffer buffer_; // (Must persist between reads) + http::request<http::empty_body> req_; + http::response<http::string_body> res_; + +public: + // Objects are constructed with a strand to + // ensure that handlers do not execute concurrently. + explicit + session(net::io_context& ioc) + : resolver_(net::make_strand(ioc)) + , stream_(net::make_strand(ioc)) + { + } + + // Start the asynchronous operation + void + run( + char const* host, + char const* port, + char const* target, + int version) + { + // Set up an HTTP GET request message + req_.version(version); + req_.method(http::verb::get); + req_.target(target); + req_.set(http::field::host, host); + req_.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING); + + // Look up the domain name + resolver_.async_resolve( + host, + port, + beast::bind_front_handler( + &session::on_resolve, + shared_from_this())); + } + + void + on_resolve( + beast::error_code ec, + tcp::resolver::results_type results) + { + if(ec) + return fail(ec, "resolve"); + + // Set a timeout on the operation + stream_.expires_after(std::chrono::seconds(30)); + + // Make the connection on the IP address we get from a lookup + stream_.async_connect( + results, + beast::bind_front_handler( + &session::on_connect, + shared_from_this())); + } + + void + on_connect(beast::error_code ec, tcp::resolver::results_type::endpoint_type) + { + if(ec) + return fail(ec, "connect"); + + // Set a timeout on the operation + stream_.expires_after(std::chrono::seconds(30)); + + // Send the HTTP request to the remote host + http::async_write(stream_, req_, + beast::bind_front_handler( + &session::on_write, + shared_from_this())); + } + + void + on_write( + beast::error_code ec, + std::size_t bytes_transferred) + { + boost::ignore_unused(bytes_transferred); + + if(ec) + return fail(ec, "write"); + + // Receive the HTTP response + http::async_read(stream_, buffer_, res_, + beast::bind_front_handler( + &session::on_read, + shared_from_this())); + } + + void + on_read( + beast::error_code ec, + std::size_t bytes_transferred) + { + boost::ignore_unused(bytes_transferred); + + if(ec) + return fail(ec, "read"); + + // Write the message to standard out + std::cout << res_ << std::endl; + + // Gracefully close the socket + stream_.socket().shutdown(tcp::socket::shutdown_both, ec); + + // not_connected happens sometimes so don't bother reporting it. + if(ec && ec != beast::errc::not_connected) + return fail(ec, "shutdown"); + + // If we get here then the connection is closed gracefully + } +}; + +//------------------------------------------------------------------------------ + +int main(int argc, char** argv) +{ + // Check command line arguments. + if(argc != 4 && argc != 5) + { + std::cerr << + "Usage: http-client-async <host> <port> <target> [<HTTP version: 1.0 or 1.1(default)>]\n" << + "Example:\n" << + " http-client-async www.example.com 80 /\n" << + " http-client-async www.example.com 80 / 1.0\n"; + return EXIT_FAILURE; + } + auto const host = argv[1]; + auto const port = argv[2]; + auto const target = argv[3]; + int version = argc == 5 && !std::strcmp("1.0", argv[4]) ? 10 : 11; + + // The io_context is required for all I/O + net::io_context ioc; + + // Launch the asynchronous operation + std::make_shared<session>(ioc)->run(host, port, target, version); + + // Run the I/O service. The call will return when + // the get operation is complete. + ioc.run(); + + return EXIT_SUCCESS; +} |