src/​examples/​cpp03/​ssl/​server.​cppsrc/​examples/​cpp11/​ssl/​server.​cpp
1 /​/​1 /​/​
2 /​/​·​server.​cpp2 /​/​·​server.​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·​<cstdlib>11 #include·​<cstdlib>
12 #include·​<functional>
12 #include·​<iostream>13 #include·​<iostream>
13 #include·​<boost/​bind/​bind.​hpp>
14 #include·​"asio.​hpp"14 #include·​"asio.​hpp"
15 #include·​"asio/​ssl.​hpp"15 #include·​"asio/​ssl.​hpp"
16 16
17 typedef·asio:​:​ssl:​:​stream<asio:​:​ip:​:​tcp:​:​socket>·ssl_socket;​17 using·asio:​:​ip:​:​tcp;​
18 18
19 class·​session19 class·session·:​·public·std:​:​enable_shared_from_th​is<session>
20 {20 {
21 public:​21 public:​
22 ··​session(asio:​:​io_context&·io_context,​22 ··​session(asio:​:​ssl:​:​stream<tcp:​:​socket>·socket)​
23 ······asio:​:​ssl:​:​context&·context)​23 ····:​·socket_(std:​:​move(socket)​)​
24 ····:​·socket_(io_context,​·context)​
25 ··​{24 ··​{
26 ··​}25 ··​}
27 26
28 ··​ssl_socket:​:​lowest_layer_type&·​socket()​
29 ··​{
30 ····​return·​local_socket.​lowest_layer()​;​
31 ··​}
32
33 ··​void·​start()​27 ··​void·​start()​
34 ··​{28 ··​{
35 ····socket_.​async_handshake(asio:​:​ssl:​:​stream_base:​:​server,​29 ····do_handshake()​;​
36 ········boost:​:​bind(&session:​:​handle_handshake,​·this,​
37 ··········asio:​:​placeholders:​:​error)​)​;​
38 ··​}30 ··​}
39 31
40 ··void·handle_handshake(cons​t·asio:​:​error_code&·error)​32 private:​
33 ··​void·​do_handshake()​
41 ··​{34 ··​{
42 ····if·​(!error)​35 ····auto·self(shared_from_this​()​)​;​
43 ····{36 ····socket_.​async_handshake(asio:​:​ssl:​:​stream_base:​:​server,​·
44 ······socket_.​async_read_some(asio:​:​buffer(data_,​·max_length)​,​37 ········[this,​·self](const·std:​:​error_code&·error)​
45 ··········boost:​:​bind(&session:​:​handle_read,​·this,​38 ········{
46 ············asio:​:​placeholders:​:​error,​39 ··········​if·(!error)​
47 ············asio:​:​placeholders:​:​bytes_transferred)​)​;​40 ··········{
48 ····}41 ············do_read()​;​
49 ····else42 ··········}
50 ····{43 ········})​;​
51 ······delete·this;​
52 ····}
53 ··​}44 ··​}
54 45
55 ··​void·handle_read(const·asio:​:​error_code&·error,​46 ··​void·​do_read()​
56 ······size_t·bytes_transferred)​
57 ··​{47 ··​{
58 ····if·​(!error)​48 ····auto·self(shared_from_this​()​)​;​
59 ····{49 ····socket_.​async_read_some(asio:​:​buffer(data_)​,​
60 ······asio:​:​async_write(socket_,​50 ········[this,​·self](const·std:​:​error_code&·ec,​·std:​:​size_t·length)​
61 ··········asio:​:​buffer(data_,​·bytes_transferred)​,​51 ········{
62 ··········boost:​:​bind(&session:​:​handle_write,​·this,​52 ··········​if·(!ec)​
63 ············asio:​:​placeholders:​:​error)​)​;​53 ··········{
64 ····}54 ············do_write(length)​;​
65 ····else55 ··········}
66 ····{56 ········})​;​
67 ······delete·this;​
68 ····}
69 ··​}57 ··​}
70 58
71 ··​void·handle_write(const·asio:​:​error_code&·error)​59 ··​void·​do_write(std:​:​size_t·length)​
72 ··​{60 ··​{
73 ····if·​(!error)​61 ····auto·self(shared_from_this​()​)​;​
74 ····{62 ····asio:​:​async_write(socket_,​·asio:​:​buffer(data_,​·length)​,​
75 ······socket_.​async_read_some(asio:​:​buffer(data_,​·max_length)​,​63 ········[this,​·self](const·std:​:​error_code&·ec,​
76 ··········boost:​:​bind(&session:​:​handle_read,​·this,​64 ··········​std:​:​size_t·/​*length*/​)​
77 ············asio:​:​placeholders:​:​error,​65 ········{
78 ············asio:​:​placeholders:​:​bytes_transferred)​)​;​66 ··········​if·(!ec)​
79 ····}67 ··········{
80 ····​else68 ············do_read()​;​
81 ····{69 ··········}
82 ······delete·this;​70 ········})​;​
83 ····}
84 ··​}71 ··​}
85 72
86 private:​73 ··asio:​:​ssl:​:​stream<tcp:​:​socket>·socket_;​
87 ··ssl_socket·socket_;​74 ··char·data_[1024];​
88 ··enum·{·max_length·=·1024·};​
89 ··char·data_[max_length];​
90 };​75 };​
91 76
92 class·​server77 class·​server
93 {78 {
94 public:​79 public:​
95 ··​server(asio:​:​io_context&·​io_context,​·​unsigned·​short·​port)​80 ··​server(asio:​:​io_context&·​io_context,​·​unsigned·​short·​port)​
96 ····​:​·​io_context_(io_contex​t)​,​81 ····​:​·acceptor_(io_context,​·tcp:​:​endpoint(tcp:​:​v4()​,​·port)​)​,​
97 ······acceptor_(io_context,​
98 ··········asio:​:​ip:​:​tcp:​:​endpoint(asio:​:​ip:​:​tcp:​:​v4()​,​·port)​)​,​
99 ······​context_(asio:​:​ssl:​:​context:​:​sslv23)​82 ······​context_(asio:​:​ssl:​:​context:​:​sslv23)​
100 ··​{83 ··​{
101 ····​context_.​set_options(84 ····​context_.​set_options(
102 ········​asio:​:​ssl:​:​context:​:​default_workarounds85 ········​asio:​:​ssl:​:​context:​:​default_workarounds
103 ········​|·​asio:​:​ssl:​:​context:​:​no_sslv286 ········​|·​asio:​:​ssl:​:​context:​:​no_sslv2
104 ········​|·​asio:​:​ssl:​:​context:​:​single_dh_use)​;​87 ········​|·​asio:​:​ssl:​:​context:​:​single_dh_use)​;​
105 ····​context_.​set_password_callback​(boost:​:​bind(&server:​:​get_password,​·​this)​)​;​88 ····​context_.​set_password_callback​(std:​:​bind(&server:​:​get_password,​·​this)​)​;​
106 ····​context_.​use_certificate_chain​_file("server.​pem")​;​89 ····​context_.​use_certificate_chain​_file("server.​pem")​;​
107 ····​context_.​use_private_key_file(​"server.​pem",​·​asio:​:​ssl:​:​context:​:​pem)​;​90 ····​context_.​use_private_key_file(​"server.​pem",​·​asio:​:​ssl:​:​context:​:​pem)​;​
108 ····​context_.​use_tmp_dh_file("dh40​96.​pem")​;​91 ····​context_.​use_tmp_dh_file("dh40​96.​pem")​;​
109 92
110 ····start_accept()​;​93 ····do_accept()​;​
111 ··​}94 ··​}
112 95
96 private:​
113 ··​std:​:​string·​get_password()​·​const97 ··​std:​:​string·​get_password()​·​const
114 ··​{98 ··​{
115 ····​return·​"test";​99 ····​return·​"test";​
116 ··​}100 ··​}
117 101
118 ··​void·start_accept()​102 ··​void·do_accept()​
119 ··​{103 ··​{
120 ····session*·new_session·=·new·session(io_context_,​·context_)​;​104 ····acceptor_.​async_accept(
121 ····acceptor_.​async_accept(new_sess​ion-​>socket()​,​105 ········[this](const·std:​:​error_code&·error,​·tcp:​:​socket·socket)​
122 ········boost:​:​bind(&server:​:​handle_accept,​·this,​·new_session,​106 ········{
123 ··········asio:​:​placeholders:​:​error)​)​;​107 ··········​if·(!error)​
124 ··}108 ··········{
109 ············​std:​:​make_shared<session>(​
110 ················​asio:​:​ssl:​:​stream<tcp:​:​socket>(
111 ··················​std:​:​move(socket)​,​·​context_)​)​-​>start()​;​
112 ··········​}
125 113
126 ··void·handle_accept(session​*·new_session,​114 ··········do_accept()​;​
127 ······const·asio:​:​error_code&·error)​115 ········})​;​
128 ··{
129 ····if·(!error)​
130 ····{
131 ······new_session-​>start()​;​
132 ····}
133 ····else
134 ····{
135 ······delete·new_session;​
136 ····}
137
138 ····start_accept()​;​
139 ··​}116 ··​}
140 117
141 private:​118 ··tcp:​:​acceptor·acceptor_;​
142 ··asio:​:​io_context&·io_context_;​
143 ··asio:​:​ip:​:​tcp:​:​acceptor·acceptor_;​
144 ··​asio:​:​ssl:​:​context·​context_;​119 ··​asio:​:​ssl:​:​context·​context_;​
145 };​120 };​
146 121
147 int·​main(int·​argc,​·​char*·​argv[])​122 int·​main(int·​argc,​·​char*·​argv[])​
148 {123 {
149 ··​try124 ··​try
150 ··​{125 ··​{
151 ····​if·​(argc·​!=·​2)​126 ····​if·​(argc·​!=·​2)​
152 ····​{127 ····​{
153 ······​std:​:​cerr·​<<·​"Usage:​·​server·​<port>\n";​128 ······​std:​:​cerr·​<<·​"Usage:​·​server·​<port>\n";​
154 ······​return·​1;​129 ······​return·​1;​
155 ····​}130 ····​}
156 131
157 ····​asio:​:​io_context·​io_context;​132 ····​asio:​:​io_context·​io_context;​
158 133
159 ····​using·​namespace·​std;​·​/​/​·​For·​atoi.​134 ····​using·​namespace·​std;​·​/​/​·​For·​atoi.​
160 ····​server·​s(io_context,​·​atoi(argv[1])​)​;​135 ····​server·​s(io_context,​·​atoi(argv[1])​)​;​
161 136
162 ····​io_context.​run()​;​137 ····​io_context.​run()​;​
163 ··​}138 ··​}
164 ··​catch·​(std:​:​exception&·​e)​139 ··​catch·​(std:​:​exception&·​e)​
165 ··​{140 ··​{
166 ····​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​141 ····​std:​:​cerr·​<<·​"Exception:​·​"·​<<·​e.​what()​·​<<·​"\n";​
167 ··​}142 ··​}
168 143
169 ··​return·​0;​144 ··​return·​0;​
170 }145 }