src/examples/cpp03/http/server/connection.cpp | src/examples/cpp11/http/server/connection.cpp |
⋮ | ⋮ |
1 | // | 1 | // |
2 | //·connection.cpp | 2 | //·connection.cpp |
3 | //·~~~~~~~~~~~~~~ | 3 | //·~~~~~~~~~~~~~~ |
4 | // | 4 | // |
5 | //·Copyright·(c)·2003-2020·Christopher·M.·Kohlhoff·(chris·at·kohlhoff·dot·com) | 5 | //·Copyright·(c)·2003-2020·Christopher·M.·Kohlhoff·(chris·at·kohlhoff·dot·com) |
6 | // | 6 | // |
7 | //·Distributed·under·the·Boost·Software·License,·Version·1.0.·(See·accompanying | 7 | //·Distributed·under·the·Boost·Software·License,·Version·1.0.·(See·accompanying |
8 | //·file·LICENSE_1_0.txt·or·copy·at·http://www.boost.org/LICENSE_1_0.txt) | 8 | //·file·LICENSE_1_0.txt·or·copy·at·http://www.boost.org/LICENSE_1_0.txt) |
9 | // | 9 | // |
10 | | 10 | |
11 | #include·"connection.hpp" | 11 | #include·"connection.hpp" |
| 12 | #include·<utility> |
12 | #include·<vector> | 13 | #include·<vector> |
13 | #include·<boost/bind/bind.hpp> | |
14 | #include·"connection_manager.hpp" | 14 | #include·"connection_manager.hpp" |
15 | #include·"request_handler.hpp" | 15 | #include·"request_handler.hpp" |
16 | | 16 | |
17 | namespace·http·{ | 17 | namespace·http·{ |
18 | namespace·server·{ | 18 | namespace·server·{ |
19 | | 19 | |
20 | connection::connection(asio::io_context&·io_context, | 20 | connection::connection(asio::ip::tcp::socket·socket, |
21 | ····connection_manager&·manager,·request_handler&·handler) | 21 | ····connection_manager&·manager,·request_handler&·handler) |
22 | ··:·socket_(io_context), | 22 | ··:·socket_(std::move(socket)), |
23 | ····connection_manager_(manager), | 23 | ····connection_manager_(manager), |
24 | ····request_handler_(handler) | 24 | ····request_handler_(handler) |
25 | { | 25 | { |
26 | } | 26 | } |
27 | | 27 | |
28 | asio::ip::tcp::socket&·connection::socket() | |
29 | { | |
30 | ··return·socket_; | |
31 | } | |
32 | | |
33 | void·connection::start() | 28 | void·connection::start() |
34 | { | 29 | { |
35 | ··socket_.async_read_some(asio::buffer(buffer_), | 30 | ··do_read(); |
36 | ······boost::bind(&connection::handle_read,·shared_from_this(), | |
37 | ········asio::placeholders::error, | |
38 | ········asio::placeholders::bytes_transferred)); | |
39 | } | 31 | } |
40 | | 32 | |
41 | void·connection::stop() | 33 | void·connection::stop() |
42 | { | 34 | { |
43 | ··socket_.close(); | 35 | ··socket_.close(); |
44 | } | 36 | } |
45 | | 37 | |
46 | void·connection::handle_read(const·asio::error_code&·e, | 38 | void·connection::do_read() |
47 | ····std::size_t·bytes_transferred) | |
48 | { | 39 | { |
49 | ··if·(!e) | 40 | ··auto·self(shared_from_this()); |
50 | ··{ | 41 | ··socket_.async_read_some(asio::buffer(buffer_), |
51 | ····boost::tribool·result; | 42 | ······[this,·self](std::error_code·ec,·std::size_t·bytes_transferred) |
52 | ····boost::tie(result,·boost::tuples::ignore)·=·request_parser_.parse( | 43 | ······{ |
53 | ········request_,·buffer_.data(),·buffer_.data()·+·bytes_transferred); | 44 | ········if·(!ec) |
54 | | 45 | ········{ |
55 | ····if·(result) | 46 | ··········request_parser::result_type·result; |
56 | ····{ | 47 | ··········std::tie(result,·std::ignore)·=·request_parser_.parse( |
57 | ······request_handler_.handle_request(request_,·reply_); | 48 | ··············request_,·buffer_.data(),·buffer_.data()·+·bytes_transferred); |
58 | ······asio::async_write(socket_,·reply_.to_buffers(), | 49 | |
59 | ··········boost::bind(&connection::handle_write,·shared_from_this(), | 50 | ··········if·(result·==·request_parser::good) |
60 | ············asio::placeholders::error)); | 51 | ··········{ |
61 | ····} | 52 | ············request_handler_.handle_request(request_,·reply_); |
62 | ····else·if·(!result) | 53 | ············do_write(); |
63 | ····{ | 54 | ··········} |
64 | ······reply_·=·reply::stock_reply(reply::bad_request); | 55 | ··········else·if·(result·==·request_parser::bad) |
65 | ······asio::async_write(socket_,·reply_.to_buffers(), | 56 | ··········{ |
66 | ··········boost::bind(&connection::handle_write,·shared_from_this(), | 57 | ············reply_·=·reply::stock_reply(reply::bad_request); |
67 | ············asio::placeholders::error)); | 58 | ············do_write(); |
68 | ····} | 59 | ··········} |
69 | ····else | 60 | ··········else |
70 | ····{ | 61 | ··········{ |
71 | ······socket_.async_read_some(asio::buffer(buffer_), | 62 | ············do_read(); |
72 | ··········boost::bind(&connection::handle_read,·shared_from_this(), | 63 | ··········} |
73 | ············asio::placeholders::error, | 64 | ········} |
74 | ············asio::placeholders::bytes_transferred)); | 65 | ········else·if·(ec·!=·asio::error::operation_aborted) |
75 | ····} | 66 | ········{ |
76 | ··} | 67 | ··········connection_manager_.stop(shared_from_this()); |
77 | ··else·if·(e·!=·asio::error::operation_aborted) | 68 | ········} |
78 | ··{ | 69 | ······}); |
79 | ····connection_manager_.stop(shared_from_this()); | 70 | } |
80 | ··} | 71 | |
81 | } | 72 | void·connection::do_write() |
82 | | 73 | { |
83 | void·connection::handle_write(const·asio::error_code&·e) | 74 | ··auto·self(shared_from_this()); |
84 | { | 75 | ··asio::async_write(socket_,·reply_.to_buffers(), |
85 | ··if·(!e) | 76 | ······[this,·self](std::error_code·ec,·std::size_t) |
86 | ··{ | 77 | ······{ |
87 | ····//·Initiate·graceful·connection·closure. | 78 | ········if·(!ec) |
88 | ····asio::error_code·ignored_ec; | 79 | ········{ |
89 | ····socket_.shutdown(asio::ip::tcp::socket::shutdown_both,·ignored_ec); | 80 | ··········//·Initiate·graceful·connection·closure. |
90 | ··} | 81 | ··········asio::error_code·ignored_ec; |
91 | | 82 | ··········socket_.shutdown(asio::ip::tcp::socket::shutdown_both, |
92 | ··if·(e·!=·asio::error::operation_aborted) | 83 | ············ignored_ec); |
93 | ··{ | 84 | ········} |
94 | ····connection_manager_.stop(shared_from_this()); | 85 | |
95 | ··} | 86 | ········if·(ec·!=·asio::error::operation_aborted) |
| 87 | ········{ |
| 88 | ··········connection_manager_.stop(shared_from_this()); |
| 89 | ········} |
| 90 | ······}); |
96 | } | 91 | } |
97 | | 92 | |
98 | }·//·namespace·server | 93 | }·//·namespace·server |
99 | }·//·namespace·http | 94 | }·//·namespace·http |