00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "connection.hpp"
00012 #include <vector>
00013 #include <boost/bind.hpp>
00014 #include "connection_manager.hpp"
00015 #include "request_handler.hpp"
00016
00017 namespace http {
00018 namespace server {
00019
00020 connection::connection(asio::io_service& io_service,
00021 connection_manager& manager, request_handler& handler)
00022 : socket_(io_service),
00023 connection_manager_(manager),
00024 request_handler_(handler)
00025 {
00026 }
00027
00028 asio::ip::tcp::socket& connection::socket()
00029 {
00030 return socket_;
00031 }
00032
00033 void connection::start()
00034 {
00035 socket_.async_read_some(asio::buffer(buffer_),
00036 boost::bind(&connection::handle_read, shared_from_this(),
00037 asio::placeholders::error,
00038 asio::placeholders::bytes_transferred));
00039 }
00040
00041 void connection::stop()
00042 {
00043 socket_.close();
00044 }
00045
00046 void connection::handle_read(const asio::error_code& e,
00047 std::size_t bytes_transferred)
00048 {
00049 if (!e)
00050 {
00051 boost::tribool result;
00052 boost::tie(result, boost::tuples::ignore) = request_parser_.parse(
00053 request_, buffer_.data(), buffer_.data() + bytes_transferred);
00054
00055 if (result)
00056 {
00057 request_handler_.handle_request(request_, reply_);
00058 asio::async_write(socket_, reply_.to_buffers(),
00059 boost::bind(&connection::handle_write, shared_from_this(),
00060 asio::placeholders::error));
00061 }
00062 else if (!result)
00063 {
00064 reply_ = reply::stock_reply(reply::bad_request);
00065 asio::async_write(socket_, reply_.to_buffers(),
00066 boost::bind(&connection::handle_write, shared_from_this(),
00067 asio::placeholders::error));
00068 }
00069 else
00070 {
00071 socket_.async_read_some(asio::buffer(buffer_),
00072 boost::bind(&connection::handle_read, shared_from_this(),
00073 asio::placeholders::error,
00074 asio::placeholders::bytes_transferred));
00075 }
00076 }
00077 else if (e != asio::error::operation_aborted)
00078 {
00079 connection_manager_.stop(shared_from_this());
00080 }
00081 }
00082
00083 void connection::handle_write(const asio::error_code& e)
00084 {
00085 if (e != asio::error::operation_aborted)
00086 {
00087 connection_manager_.stop(shared_from_this());
00088 }
00089 }
00090
00091 }
00092 }