diff options
author | 2016-11-07 10:42:23 +0100 | |
---|---|---|
committer | 2016-11-07 10:42:23 +0100 | |
commit | fc58a0bec8bf779af3afecbc6ca59a7b9c9c0b67 (patch) | |
tree | 011e6d736c6e191f130c066a860e7fda9d0e0014 /src/lib/http/connection.cpp | |
parent | ce0e6e6a3e114625e6b33a2ab75489a5b0cba17b (diff) |
Added basic HTTP server, not active yet, based on ASIO example with small refactoring included (nw)
Diffstat (limited to 'src/lib/http/connection.cpp')
-rw-r--r-- | src/lib/http/connection.cpp | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/lib/http/connection.cpp b/src/lib/http/connection.cpp new file mode 100644 index 00000000000..bb1c07cfa06 --- /dev/null +++ b/src/lib/http/connection.cpp @@ -0,0 +1,87 @@ +// license:Boost +// copyright-holders:Christopher M. Kohlhoff + +#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) + : m_socket(std::move(socket)), + m_connection_manager(manager), + m_request_handler(handler) +{ +} + +void connection::start() +{ + do_read(); +} + +void connection::stop() +{ + m_socket.close(); +} + +void connection::do_read() +{ + auto self(shared_from_this()); + m_socket.async_read_some(asio::buffer(m_buffer), + [this, self](std::error_code ec, std::size_t bytes_transferred) + { + if (!ec) + { + request_parser::result_type result; + std::tie(result, std::ignore) = m_request_parser.parse( + m_request, m_buffer.data(), m_buffer.data() + bytes_transferred); + + if (result == request_parser::good) + { + m_request_handler.handle_request(m_request, m_reply); + do_write(); + } + else if (result == request_parser::bad) + { + m_reply = reply::stock_reply(reply::bad_request); + do_write(); + } + else + { + do_read(); + } + } + else if (ec != asio::error::operation_aborted) + { + m_connection_manager.stop(shared_from_this()); + } + }); +} + +void connection::do_write() +{ + auto self(shared_from_this()); + asio::async_write(m_socket, m_reply.to_buffers(), + [this, self](std::error_code ec, std::size_t) + { + if (!ec) + { + // Initiate graceful connection closure. + asio::error_code ignored_ec; + m_socket.shutdown(asio::ip::tcp::socket::shutdown_both, + ignored_ec); + } + + if (ec != asio::error::operation_aborted) + { + m_connection_manager.stop(shared_from_this()); + } + }); +} + +} // namespace server +} // namespace http |