-
Notifications
You must be signed in to change notification settings - Fork 13
/
connection.cpp
96 lines (86 loc) · 2.93 KB
/
connection.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//
// connection.cpp
// ~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2008 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 <vector>
#include <boost/bind.hpp>
#include "request_handler.hpp"
#include <iostream>
#include <boost/thread.hpp>
namespace http
{
namespace server
{
connection::connection(boost::asio::io_service& io_service, request_handler& handler)
:
strand_(io_service),
socket_(io_service),
request_handler_(handler)
{
}
boost::asio::ip::tcp::socket&
connection::socket()
{
return socket_;
}
void
connection::start()
{
socket_.async_read_some(
boost::asio::buffer(buffer_),
strand_.wrap(
boost::bind(&connection::handle_read, shared_from_this(), boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)));
}
void
connection::handle_read(const boost::system::error_code& e, std::size_t bytes_transferred)
{
if (!e)
{
boost::tribool result;
boost::tie(result, boost::tuples::ignore) = request_parser_.parse(request_, buffer_.data(),
buffer_.data() + bytes_transferred);
if (result)
{
request_handler_.handle_request(shared_from_this(), request_, reply_);
}
else if (!result)
{
reply_ = reply::stock_reply(reply::bad_request);
async_write(reply_.to_buffers());
}
else
{
socket_.async_read_some(
boost::asio::buffer(buffer_),
boost::bind(&connection::handle_read, shared_from_this(), boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
}
// If an error occurs then no new asynchronous operations are started. This
// means that all shared_ptr references to the connection object will
// disappear and the object will be destroyed automatically after this
// handler returns. The connection class's destructor closes the socket.
}
void
connection::handle_write(const boost::system::error_code& e)
{
if (!e)
{
// Initiate graceful connection closure.
boost::system::error_code ignored_ec;
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
}
// No new asynchronous operations are started. This means that all shared_ptr
// references to the connection object will disappear and the object will be
// destroyed automatically after this handler returns. The connection class's
// destructor closes the socket.
}
} // namespace server3
} // namespace http