| 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-2018·Christopher·M.·Kohlhoff·(chris·at·kohlhoff·dot·com) | 5 | //·Copyright·(c)·2003-2018·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.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 |