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