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-​2023·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​5 /​/​·​Copyright·​(c)​·​2003-​2023·​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 ··​:​·​local_socket(io_context)​,​22 ··​:​·​local_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·​local_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 ··​local_socket.​close()​;​35 ··​local_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)​
45 ········​{
46 ··········​request_parser:​:​result_type·​result;​
47 ··········​std:​:​tie(result,​·​std:​:​ignore)​·​=·​request_parser_.​parse(
48 ··············​request_,​·​buffer_.​data()​,​·​buffer_.​data()​·​+·​bytes_transferred)​;​
54 49
55 ····​if·​(result)​50 ··········​if·​(result·==·request_parser:​:​good)​
56 ····​{51 ··········​{
57 ······​request_handler_.​handle_request(reques​t_,​·​reply_)​;​52 ············​request_handler_.​handle_request(reques​t_,​·​reply_)​;​
58 ······asio:​:​async_write(socket_,​·reply_.​to_buffers()​,​53 ············do_write()​;​
59 ··········boost:​:​bind(&connection:​:​handle_write,​·shared_from_this()​,​54 ··········}
60 ············asio:​:​placeholders:​:​error)​)​;​55 ··········else·if·(result·==·request_parser:​:​bad)​
61 ····}56 ··········{
62 ····​else·if·(!result)​57 ············reply_·=·reply:​:​stock_reply(reply:​:​bad_request)​;​
63 ····{58 ············do_write()​;​
64 ······reply_·=·reply:​:​stock_reply(reply:​:​bad_request)​;​59 ··········}
65 ······asio:​:​async_write(socket_,​·reply_.​to_buffers()​,​60 ··········else
66 ··········boost:​:​bind(&connection:​:​handle_write,​·shared_from_this()​,​61 ··········{
67 ············asio:​:​placeholders:​:​error)​)​;​62 ············do_read()​;​
68 ····​}63 ··········​}
69 ····else64 ········}
70 ····{65 ········else·if·(ec·!=·asio:​:​error:​:​operation_aborted)​
71 ······socket_.​async_read_some(asio:​:​buffer(buffer_)​,​66 ········{
72 ··········boost:​:​bind(&connection:​:​handle_read,​·shared_from_this()​,​67 ··········​connection_manager_.​stop(shared_from_this​()​)​;​
73 ············asio:​:​placeholders:​:​error,​68 ········}
74 ············asio:​:​placeholders:​:​bytes_transferred)​)​;​69 ······})​;​
75 ····}
76 ··}
77 ··else·if·(e·!=·asio:​:​error:​:​operation_aborted)​
78 ··{
79 ····connection_manager_.​stop(shared_from_this​()​)​;​
80 ··}
81 }70 }
82 71
83 void·​connection:​:​handle_write(const·asio:​:​error_code&·e)​72 void·​connection:​:​do_write()​
84 {73 {
85 ··if·​(!e)​74 ··auto·self(shared_from_this​()​)​;​
86 ··{75 ··asio:​:​async_write(socket_,​·reply_.​to_buffers()​,​
87 ····/​/​·Initiate·graceful·connection·closure.​76 ······[this,​·self](std:​:​error_code·ec,​·std:​:​size_t)​
88 ····asio:​:​error_code·ignored_ec;​77 ······{
89 ····socket_.​shutdown(asio:​:​ip:​:​tcp:​:​socket:​:​shutdown_both,​·​ignored_ec)​;​78 ········​if·(!ec)​
90 ··}79 ········{
80 ··········​/​/​·​Initiate·​graceful·​connection·​closure.​
81 ··········​asio:​:​error_code·​ignored_ec;​
82 ··········​local_socket.​shutdown(asio:​:​ip:​:​tcp:​:​socket:​:​shutdown_both,​
83 ············​ignored_ec)​;​
84 ········​}
91 85
92 ··​if·​(e·​!=·​asio:​:​error:​:​operation_aborted)​86 ········​if·​(ec·​!=·​asio:​:​error:​:​operation_aborted)​
93 ··​{87 ········​{
94 ····​connection_manager_.​stop(shared_from_this​()​)​;​88 ··········​connection_manager_.​stop(shared_from_this​()​)​;​
95 ··​}89 ········​}
90 ······​})​;​
96 }91 }
97 92
98 }·​/​/​·​namespace·​server93 }·​/​/​·​namespace·​server
99 }·​/​/​·​namespace·​http94 }·​/​/​·​namespace·​http