summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/http/connection.cpp
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2016-11-07 10:42:23 +0100
committer Miodrag Milanovic <mmicko@gmail.com>2016-11-07 10:42:23 +0100
commitfc58a0bec8bf779af3afecbc6ca59a7b9c9c0b67 (patch)
tree011e6d736c6e191f130c066a860e7fda9d0e0014 /src/lib/http/connection.cpp
parentce0e6e6a3e114625e6b33a2ab75489a5b0cba17b (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.cpp87
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