From 2bd65b27e1f3624549457a91c1b39dba1f521f80 Mon Sep 17 00:00:00 2001 From: Klemens Morgenstern Date: Mon, 20 Feb 2023 13:58:07 +0800 Subject: [PATCH] awaitable server close fix. Closes #2637 --- .../awaitable/http_server_awaitable.cpp | 66 ++++++++++--------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/example/http/server/awaitable/http_server_awaitable.cpp b/example/http/server/awaitable/http_server_awaitable.cpp index 64961da5..47ae01dc 100644 --- a/example/http/server/awaitable/http_server_awaitable.cpp +++ b/example/http/server/awaitable/http_server_awaitable.cpp @@ -215,37 +215,37 @@ do_session( tcp_stream stream, std::shared_ptr doc_root) { - beast::error_code ec; - // This buffer is required to persist across reads beast::flat_buffer buffer; // This lambda is used to send messages - for(;;) try { - // Set the timeout. - stream.expires_after(std::chrono::seconds(30)); - - // Read a request - http::request req; - co_await http::async_read(stream, buffer, req); - - // Handle the request - http::message_generator msg = - handle_request(*doc_root, std::move(req)); - - // Determine if we should close the connection - bool keep_alive = msg.keep_alive(); - - // Send the response - co_await beast::async_write(stream, std::move(msg), net::use_awaitable); - - if(! keep_alive) + for(;;) { - // This means we should close the connection, usually because - // the response indicated the "Connection: close" semantic. - break; + // Set the timeout. + stream.expires_after(std::chrono::seconds(30)); + + // Read a request + http::request req; + co_await http::async_read(stream, buffer, req); + + // Handle the request + http::message_generator msg = + handle_request(*doc_root, std::move(req)); + + // Determine if we should close the connection + bool keep_alive = msg.keep_alive(); + + // Send the response + co_await beast::async_write(stream, std::move(msg), net::use_awaitable); + + if(! keep_alive) + { + // This means we should close the connection, usually because + // the response indicated the "Connection: close" semantic. + break; + } } } catch (boost::system::system_error & se) @@ -255,9 +255,12 @@ do_session( } // Send a TCP shutdown + beast::error_code ec; stream.socket().shutdown(tcp::socket::shutdown_send, ec); // At this point the connection is closed gracefully + // we ignore the error because the client might have + // dropped the connection already. } //------------------------------------------------------------------------------ @@ -287,13 +290,14 @@ do_listen( do_session(tcp_stream(co_await acceptor.async_accept()), doc_root), [](std::exception_ptr e) { - try - { - std::rethrow_exception(e); - } - catch (std::exception &e) { - std::cerr << "Error in session: " << e.what() << "\n"; - } + if (e) + try + { + std::rethrow_exception(e); + } + catch (std::exception &e) { + std::cerr << "Error in session: " << e.what() << "\n"; + } }); }