12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- //
- // connection.cpp
- // ~~~~~~~~~~~~~~
- //
- // Copyright (c) 2003-2019 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(boost::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(boost::asio::buffer(buffer_),
- [this, self](boost::system::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 != boost::asio::error::operation_aborted)
- {
- connection_manager_.stop(shared_from_this());
- }
- });
- }
- void connection::do_write()
- {
- auto self(shared_from_this());
- boost::asio::async_write(socket_, reply_.to_buffers(),
- [this, self](boost::system::error_code ec, std::size_t)
- {
- if (!ec)
- {
- // Initiate graceful connection closure.
- boost::system::error_code ignored_ec;
- socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both,
- ignored_ec);
- }
- if (ec != boost::asio::error::operation_aborted)
- {
- connection_manager_.stop(shared_from_this());
- }
- });
- }
- } // namespace server
- } // namespace http
|