diff --git a/CHANGELOG.md b/CHANGELOG.md index 590a8b24..d99dd894 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Version 213: * Fix posix_file::close handling of EINTR * basic_stream subsumes stranded_stream: * Use timeouts in HTTP server examples +* Use timeouts in HTTP client examples -------------------------------------------------------------------------------- diff --git a/example/http/client/async-ssl/http_client_async_ssl.cpp b/example/http/client/async-ssl/http_client_async_ssl.cpp index 2093a876..27d66f35 100644 --- a/example/http/client/async-ssl/http_client_async_ssl.cpp +++ b/example/http/client/async-ssl/http_client_async_ssl.cpp @@ -18,10 +18,7 @@ #include #include #include -#include -#include -#include -#include +#include #include #include #include @@ -36,6 +33,10 @@ using tcp = boost::asio::ip::tcp; // from //------------------------------------------------------------------------------ +// The type of stream to use +using stream_type = + beast::ssl_stream>; + // Report a failure void fail(beast::error_code ec, char const* what) @@ -47,7 +48,7 @@ fail(beast::error_code ec, char const* what) class session : public std::enable_shared_from_this { tcp::resolver resolver_; - ssl::stream stream_; + stream_type stream_; beast::flat_buffer buffer_; // (Must persist between reads) http::request req_; http::response res_; @@ -103,11 +104,13 @@ public: if(ec) return fail(ec, "resolve"); + // Set a timeout on the operation + beast::get_lowest_layer(stream_).expires_after(std::chrono::seconds(30)); + // Make the connection on the IP address we get from a lookup - net::async_connect( - stream_.next_layer(), - results.begin(), - results.end(), + beast::async_connect( + beast::get_lowest_layer(stream_), + results, std::bind( &session::on_connect, shared_from_this(), @@ -135,6 +138,9 @@ public: if(ec) return fail(ec, "handshake"); + // Set a timeout on the operation + beast::get_lowest_layer(stream_).expires_after(std::chrono::seconds(30)); + // Send the HTTP request to the remote host http::async_write(stream_, req_, std::bind( @@ -176,6 +182,9 @@ public: // Write the message to standard out std::cout << res_ << std::endl; + // Set a timeout on the operation + beast::get_lowest_layer(stream_).expires_after(std::chrono::seconds(30)); + // Gracefully close the stream stream_.async_shutdown( std::bind( diff --git a/example/http/client/async/http_client_async.cpp b/example/http/client/async/http_client_async.cpp index 9eec2a1a..3bb5121b 100644 --- a/example/http/client/async/http_client_async.cpp +++ b/example/http/client/async/http_client_async.cpp @@ -16,8 +16,6 @@ #include #include #include -#include -#include #include #include #include @@ -31,6 +29,9 @@ using tcp = boost::asio::ip::tcp; // from //------------------------------------------------------------------------------ +// The type of stream to use +using stream_type = beast::tcp_stream; + // Report a failure void fail(beast::error_code ec, char const* what) @@ -42,7 +43,7 @@ fail(beast::error_code ec, char const* what) class session : public std::enable_shared_from_this { tcp::resolver resolver_; - tcp::socket socket_; + stream_type stream_; beast::flat_buffer buffer_; // (Must persist between reads) http::request req_; http::response res_; @@ -52,7 +53,7 @@ public: explicit session(net::io_context& ioc) : resolver_(ioc) - , socket_(ioc) + , stream_(ioc) { } @@ -90,11 +91,13 @@ public: 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 - net::async_connect( - socket_, - results.begin(), - results.end(), + beast::async_connect( + stream_, + results, std::bind( &session::on_connect, shared_from_this(), @@ -107,8 +110,11 @@ public: 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(socket_, req_, + http::async_write(stream_, req_, std::bind( &session::on_write, shared_from_this(), @@ -127,7 +133,7 @@ public: return fail(ec, "write"); // Receive the HTTP response - http::async_read(socket_, buffer_, res_, + http::async_read(stream_, buffer_, res_, std::bind( &session::on_read, shared_from_this(), @@ -149,7 +155,7 @@ public: std::cout << res_ << std::endl; // Gracefully close the socket - socket_.shutdown(tcp::socket::shutdown_both, ec); + 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) diff --git a/example/http/client/coro-ssl/http_client_coro_ssl.cpp b/example/http/client/coro-ssl/http_client_coro_ssl.cpp index cd4fc8af..6c603473 100644 --- a/example/http/client/coro-ssl/http_client_coro_ssl.cpp +++ b/example/http/client/coro-ssl/http_client_coro_ssl.cpp @@ -18,11 +18,8 @@ #include #include #include -#include +#include #include -#include -#include -#include #include #include #include @@ -36,6 +33,11 @@ using tcp = boost::asio::ip::tcp; // from //------------------------------------------------------------------------------ +// The type of stream to use +// Stackful coroutines are already stranded. +using stream_type = + beast::ssl_stream>; + // Report a failure void fail(beast::error_code ec, char const* what) @@ -57,8 +59,8 @@ do_session( beast::error_code ec; // These objects perform our I/O - tcp::resolver resolver{ioc}; - ssl::stream stream{ioc, ctx}; + tcp::resolver resolver(ioc); + stream_type stream(ioc, ctx); // Set SNI Hostname (many hosts need this to handshake successfully) if(! SSL_set_tlsext_host_name(stream.native_handle(), host.c_str())) @@ -73,11 +75,17 @@ do_session( if(ec) return fail(ec, "resolve"); + // Set the timeout. + beast::get_lowest_layer(stream).expires_after(std::chrono::seconds(30)); + // Make the connection on the IP address we get from a lookup - net::async_connect(stream.next_layer(), results.begin(), results.end(), yield[ec]); + beast::async_connect(get_lowest_layer(stream), results, yield[ec]); if(ec) return fail(ec, "connect"); + // Set the timeout. + beast::get_lowest_layer(stream).expires_after(std::chrono::seconds(30)); + // Perform the SSL handshake stream.async_handshake(ssl::stream_base::client, yield[ec]); if(ec) @@ -88,6 +96,9 @@ do_session( req.set(http::field::host, host); req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING); + // Set the timeout. + beast::get_lowest_layer(stream).expires_after(std::chrono::seconds(30)); + // Send the HTTP request to the remote host http::async_write(stream, req, yield[ec]); if(ec) @@ -107,6 +118,9 @@ do_session( // Write the message to standard out std::cout << res << std::endl; + // Set the timeout. + beast::get_lowest_layer(stream).expires_after(std::chrono::seconds(30)); + // Gracefully close the stream stream.async_shutdown(yield[ec]); if(ec == net::error::eof) diff --git a/example/http/client/coro/http_client_coro.cpp b/example/http/client/coro/http_client_coro.cpp index 8448b9cb..f21583bd 100644 --- a/example/http/client/coro/http_client_coro.cpp +++ b/example/http/client/coro/http_client_coro.cpp @@ -16,9 +16,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -31,6 +29,10 @@ using tcp = boost::asio::ip::tcp; // from //------------------------------------------------------------------------------ +// The type of stream to use. +// Stackful coroutines are already stranded. +using stream_type = beast::tcp_stream; + // Report a failure void fail(beast::error_code ec, char const* what) @@ -52,15 +54,18 @@ do_session( // These objects perform our I/O tcp::resolver resolver{ioc}; - tcp::socket socket{ioc}; + stream_type stream(ioc); // Look up the domain name auto const results = resolver.async_resolve(host, port, yield[ec]); if(ec) return fail(ec, "resolve"); + // Set the timeout. + stream.expires_after(std::chrono::seconds(30)); + // Make the connection on the IP address we get from a lookup - net::async_connect(socket, results.begin(), results.end(), yield[ec]); + beast::async_connect(stream, results, yield[ec]); if(ec) return fail(ec, "connect"); @@ -69,8 +74,11 @@ do_session( req.set(http::field::host, host); req.set(http::field::user_agent, BOOST_BEAST_VERSION_STRING); + // Set the timeout. + stream.expires_after(std::chrono::seconds(30)); + // Send the HTTP request to the remote host - http::async_write(socket, req, yield[ec]); + http::async_write(stream, req, yield[ec]); if(ec) return fail(ec, "write"); @@ -81,7 +89,7 @@ do_session( http::response res; // Receive the HTTP response - http::async_read(socket, b, res, yield[ec]); + http::async_read(stream, b, res, yield[ec]); if(ec) return fail(ec, "read"); @@ -89,7 +97,7 @@ do_session( std::cout << res << std::endl; // Gracefully close the socket - socket.shutdown(tcp::socket::shutdown_both, ec); + stream.socket().shutdown(tcp::socket::shutdown_both, ec); // not_connected happens sometimes // so don't bother reporting it.