src/​examples/​cpp03/​http/​server/​connection.​cppsrc/​examples/​cpp11/​http/​server/​connection.​cpp
1 /​/​1 /​/​
2 /​/​·​connection.​cpp2 /​/​·​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·​accompanying7 /​/​·​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_(m​anager)​,​23 ····​connection_manager_(m​anager)​,​
24 ····​request_handler_(hand​ler)​24 ····​request_handler_(hand​ler)​
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(reques​t_,​·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(reques​t_,​·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 ····​else60 ··········​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·​server93 }·​/​/​·​namespace·​server
99 }·​/​/​·​namespace·​http94 }·​/​/​·​namespace·​http