diff options
Diffstat (limited to '3rdparty/asio/src/examples/cpp11/http/server/connection.cpp')
-rw-r--r-- | 3rdparty/asio/src/examples/cpp11/http/server/connection.cpp | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/3rdparty/asio/src/examples/cpp11/http/server/connection.cpp b/3rdparty/asio/src/examples/cpp11/http/server/connection.cpp new file mode 100644 index 00000000000..f4d9cac46e5 --- /dev/null +++ b/3rdparty/asio/src/examples/cpp11/http/server/connection.cpp @@ -0,0 +1,94 @@ +// +// connection.cpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff 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) +// + +#include "connection.hpp" +#include <utility> +#include <vector> +#include "connection_manager.hpp" +#include "request_handler.hpp" + +namespace http { +namespace server { + +connection::connection(asio::ip::tcp::socket socket, + connection_manager& manager, request_handler& handler) + : socket_(std::move(socket)), + connection_manager_(manager), + request_handler_(handler) +{ +} + +void connection::start() +{ + do_read(); +} + +void connection::stop() +{ + socket_.close(); +} + +void connection::do_read() +{ + auto self(shared_from_this()); + socket_.async_read_some(asio::buffer(buffer_), + [this, self](std::error_code ec, std::size_t bytes_transferred) + { + if (!ec) + { + request_parser::result_type result; + std::tie(result, std::ignore) = request_parser_.parse( + request_, buffer_.data(), buffer_.data() + bytes_transferred); + + if (result == request_parser::good) + { + request_handler_.handle_request(request_, reply_); + do_write(); + } + else if (result == request_parser::bad) + { + reply_ = reply::stock_reply(reply::bad_request); + do_write(); + } + else + { + do_read(); + } + } + else if (ec != asio::error::operation_aborted) + { + connection_manager_.stop(shared_from_this()); + } + }); +} + +void connection::do_write() +{ + auto self(shared_from_this()); + asio::async_write(socket_, reply_.to_buffers(), + [this, self](std::error_code ec, std::size_t) + { + if (!ec) + { + // Initiate graceful connection closure. + asio::error_code ignored_ec; + socket_.shutdown(asio::ip::tcp::socket::shutdown_both, + ignored_ec); + } + + if (ec != asio::error::operation_aborted) + { + connection_manager_.stop(shared_from_this()); + } + }); +} + +} // namespace server +} // namespace http |