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-​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·​<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·​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 ··}
39
40 ··void·handle_handshake(cons​t·asio:​:​error_code&·error)​
41 ··{
42 ····if·(!error)​
43 ····{
44 ······socket_.​async_read_some(asio:​:​buffer(data_,​·max_length)​,​
45 ··········boost:​:​bind(&session:​:​handle_read,​·this,​
46 ············asio:​:​placeholders:​:​error,​
47 ············asio:​:​placeholders:​:​bytes_transferred)​)​;​
48 ····}
49 ····else
50 ····{
51 ······delete·this;​
52 ····}
53 ··}
54
55 ··void·handle_read(const·asio:​:​error_code&·error,​
56 ······size_t·bytes_transferred)​
57 ··{
58 ····if·(!error)​
59 ····{
60 ······asio:​:​async_write(socket_,​
61 ··········asio:​:​buffer(data_,​·bytes_transferred)​,​
62 ··········boost:​:​bind(&session:​:​handle_write,​·this,​
63 ············asio:​:​placeholders:​:​error)​)​;​
64 ····}
65 ····else
66 ····{
67 ······delete·this;​
68 ····}
69 ··​}30 ··​}
70 31
71 ··void·handle_write(const·asio:​:​error_code&·error)​32 private:​
33 ··​void·​do_handshake()​
72 ··​{34 ··​{
73 ····if·​(!error)​35 ····auto·self(shared_from_this​()​)​;​
74 ····{36 ····socket_.​async_handshake(asio:​:​ssl:​:​stream_base:​:​server,​·
75 ······socket_.​async_read_some(asio:​:​buffer(data_,​·max_length)​,​37 ········[this,​·self](const·std:​:​error_code&·error)​
76 ··········boost:​:​bind(&session:​:​handle_read,​·this,​38 ········{
77 ············asio:​:​placeholders:​:​error,​39 ··········​if·(!error)​
78 ············asio:​:​placeholders:​:​bytes_transferred)​)​;​40 ··········{
79 ····}41 ············do_read()​;​
80 ····else42 ··········}
81 ····{43 ········})​;​
82 ······delete·this;​44 ··}
83 ····}45
46 ··​void·​do_read()​
47 ··​{
48 ····​auto·​self(shared_from_this​()​)​;​
49 ····​socket_.​async_read_some(asio:​:​buffer(data_)​,​
50 ········​[this,​·​self](const·​std:​:​error_code&·​ec,​·​std:​:​size_t·​length)​
51 ········​{
52 ··········​if·​(!ec)​
53 ··········​{
54 ············​do_write(length)​;​
55 ··········​}
56 ········​})​;​
57 ··​}
58
59 ··​void·​do_write(std:​:​size_t·​length)​
60 ··​{
61 ····​auto·​self(shared_from_this​()​)​;​
62 ····​asio:​:​async_write(socket_,​·​asio:​:​buffer(data_,​·​length)​,​
63 ········​[this,​·​self](const·​std:​:​error_code&·​ec,​
64 ··········​std:​:​size_t·​/​*length*/​)​
65 ········​{
66 ··········​if·​(!ec)​
67 ··········​{
68 ············​do_read()​;​
69 ··········​}
70 ········​})​;​
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("dh20​48.​pem")​;​91 ····​context_.​use_tmp_dh_file("dh20​48.​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 ··········{
125 109 ············std:​:​make_shared<session>(​
126 ··void·handle_accept(session​*·new_session,​110 ················asio:​:​ssl:​:​stream<tcp:​:​socket>(
127 ······const·asio:​:​error_code&·error)​111 ··················std:​:​move(socket)​,​·context_)​)​-​>start()​;​
128 ··{112 ··········}
129 ····if·(!error)​
130 ····{
131 ······new_session-​>start()​;​
132 ····}
133 ····else
134 ····{
135 ······delete·new_session;​
136 ····}
137 113
138 ····start_accept()​;​114 ··········do_accept()​;​
115 ········​})​;​
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 }