1//
2// TCPServerTest.cpp
3//
4// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
5// and Contributors.
6//
7// SPDX-License-Identifier: BSL-1.0
8//
9
10
11#include "TCPServerTest.h"
12#include "Poco/CppUnit/TestCaller.h"
13#include "Poco/CppUnit/TestSuite.h"
14#include "Poco/Net/TCPServer.h"
15#include "Poco/Net/TCPServerConnection.h"
16#include "Poco/Net/TCPServerConnectionFactory.h"
17#include "Poco/Net/TCPServerParams.h"
18#include "Poco/Net/SecureStreamSocket.h"
19#include "Poco/Net/SecureServerSocket.h"
20#include "Poco/Net/Context.h"
21#include "Poco/Net/Session.h"
22#include "Poco/Net/SSLManager.h"
23#include "Poco/Util/Application.h"
24#include "Poco/Util/AbstractConfiguration.h"
25#include "Poco/Thread.h"
26#include <iostream>
27
28
29using Poco::Net::TCPServer;
30using Poco::Net::TCPServerConnection;
31using Poco::Net::TCPServerConnectionFactory;
32using Poco::Net::TCPServerConnectionFactoryImpl;
33using Poco::Net::TCPServerParams;
34using Poco::Net::StreamSocket;
35using Poco::Net::SecureStreamSocket;
36using Poco::Net::SecureServerSocket;
37using Poco::Net::SocketAddress;
38using Poco::Net::Context;
39using Poco::Net::Session;
40using Poco::Net::SSLManager;
41using Poco::Thread;
42using Poco::Util::Application;
43
44static const int closeSleepTime = 3000;
45
46namespace
47{
48 class EchoConnection: public TCPServerConnection
49 {
50 public:
51 EchoConnection(const StreamSocket& s): TCPServerConnection(s)
52 {
53 }
54
55 void run()
56 {
57 StreamSocket& ss = socket();
58 try
59 {
60 char buffer[256];
61 int n = ss.receiveBytes(buffer, sizeof(buffer));
62 while (n > 0)
63 {
64 ss.sendBytes(buffer, n);
65 n = ss.receiveBytes(buffer, sizeof(buffer));
66 }
67 }
68 catch (Poco::Exception& exc)
69 {
70 std::cerr << "EchoConnection: " << exc.displayText() << std::endl;
71 }
72 }
73 };
74}
75
76
77TCPServerTest::TCPServerTest(const std::string& name): CppUnit::TestCase(name)
78{
79}
80
81
82TCPServerTest::~TCPServerTest()
83{
84}
85
86
87void TCPServerTest::testOneConnection()
88{
89 SecureServerSocket svs(0);
90 TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs);
91 srv.start();
92 assertTrue (srv.currentConnections() == 0);
93 assertTrue (srv.currentThreads() == 0);
94 assertTrue (srv.queuedConnections() == 0);
95 assertTrue (srv.totalConnections() == 0);
96
97 SocketAddress sa("127.0.0.1", svs.address().port());
98 SecureStreamSocket ss1(sa);
99 std::string data("hello, world");
100 ss1.sendBytes(data.data(), (int) data.size());
101 char buffer[256];
102 int n = ss1.receiveBytes(buffer, sizeof(buffer));
103 assertTrue (n > 0);
104 assertTrue (std::string(buffer, n) == data);
105 assertTrue (srv.currentConnections() == 1);
106 assertTrue (srv.currentThreads() == 1);
107 assertTrue (srv.queuedConnections() == 0);
108 assertTrue (srv.totalConnections() == 1);
109 ss1.close();
110 Thread::sleep(closeSleepTime);
111 assertTrue (srv.currentConnections() == 0);
112}
113
114
115void TCPServerTest::testTwoConnections()
116{
117 SecureServerSocket svs(0);
118 TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs);
119 srv.start();
120 assertTrue (srv.currentConnections() == 0);
121 assertTrue (srv.currentThreads() == 0);
122 assertTrue (srv.queuedConnections() == 0);
123 assertTrue (srv.totalConnections() == 0);
124
125 SocketAddress sa("127.0.0.1", svs.address().port());
126 SecureStreamSocket ss1(sa);
127 SecureStreamSocket ss2(sa);
128 std::string data("hello, world");
129 ss1.sendBytes(data.data(), (int) data.size());
130 ss2.sendBytes(data.data(), (int) data.size());
131
132 char buffer[256];
133 int n = ss1.receiveBytes(buffer, sizeof(buffer));
134 assertTrue (n > 0);
135 assertTrue (std::string(buffer, n) == data);
136
137 n = ss2.receiveBytes(buffer, sizeof(buffer));
138 assertTrue (n > 0);
139 assertTrue (std::string(buffer, n) == data);
140
141 assertTrue (srv.currentConnections() == 2);
142 assertTrue (srv.currentThreads() == 2);
143 assertTrue (srv.queuedConnections() == 0);
144 assertTrue (srv.totalConnections() == 2);
145 ss1.close();
146 Thread::sleep(300);
147 assertTrue (srv.currentConnections() == 1);
148 assertTrue (srv.currentThreads() == 1);
149 assertTrue (srv.queuedConnections() == 0);
150 assertTrue (srv.totalConnections() == 2);
151 ss2.close();
152
153 Thread::sleep(closeSleepTime);
154 assertTrue (srv.currentConnections() == 0);
155}
156
157
158void TCPServerTest::testMultiConnections()
159{
160 SecureServerSocket svs(0);
161 TCPServerParams* pParams = new TCPServerParams;
162 pParams->setMaxThreads(4);
163 pParams->setMaxQueued(4);
164 pParams->setThreadIdleTime(100);
165 TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs, pParams);
166 srv.start();
167 assertTrue (srv.currentConnections() == 0);
168 assertTrue (srv.currentThreads() == 0);
169 assertTrue (srv.queuedConnections() == 0);
170 assertTrue (srv.totalConnections() == 0);
171
172 SocketAddress sa("127.0.0.1", svs.address().port());
173 SecureStreamSocket ss1(sa);
174 SecureStreamSocket ss2(sa);
175 SecureStreamSocket ss3(sa);
176 SecureStreamSocket ss4(sa);
177 std::string data("hello, world");
178 ss1.sendBytes(data.data(), (int) data.size());
179 ss2.sendBytes(data.data(), (int) data.size());
180 ss3.sendBytes(data.data(), (int) data.size());
181 ss4.sendBytes(data.data(), (int) data.size());
182
183 char buffer[256];
184 int n = ss1.receiveBytes(buffer, sizeof(buffer));
185 assertTrue (n > 0);
186 assertTrue (std::string(buffer, n) == data);
187
188 n = ss2.receiveBytes(buffer, sizeof(buffer));
189 assertTrue (n > 0);
190 assertTrue (std::string(buffer, n) == data);
191
192 n = ss3.receiveBytes(buffer, sizeof(buffer));
193 assertTrue (n > 0);
194 assertTrue (std::string(buffer, n) == data);
195
196 n = ss4.receiveBytes(buffer, sizeof(buffer));
197 assertTrue (n > 0);
198 assertTrue (std::string(buffer, n) == data);
199
200 assertTrue (srv.currentConnections() == 4);
201 assertTrue (srv.currentThreads() == 4);
202 assertTrue (srv.queuedConnections() == 0);
203 assertTrue (srv.totalConnections() == 4);
204
205 SecureStreamSocket ss5;
206 ss5.setLazyHandshake();
207 ss5.connect(sa);
208 Thread::sleep(200);
209 assertTrue (srv.queuedConnections() == 1);
210 SecureStreamSocket ss6;
211 ss6.setLazyHandshake();
212 ss6.connect(sa);
213 Thread::sleep(200);
214 assertTrue (srv.queuedConnections() == 2);
215
216 ss1.close();
217 Thread::sleep(300);
218 assertTrue (srv.currentConnections() == 4);
219 assertTrue (srv.currentThreads() == 4);
220 assertTrue (srv.queuedConnections() == 1);
221 assertTrue (srv.totalConnections() == 5);
222
223 ss2.close();
224 Thread::sleep(300);
225 assertTrue (srv.currentConnections() == 4);
226 assertTrue (srv.currentThreads() == 4);
227 assertTrue (srv.queuedConnections() == 0);
228 assertTrue (srv.totalConnections() == 6);
229
230 ss3.close();
231 Thread::sleep(300);
232 assertTrue (srv.currentConnections() == 3);
233 assertTrue (srv.currentThreads() == 3);
234 assertTrue (srv.queuedConnections() == 0);
235 assertTrue (srv.totalConnections() == 6);
236
237 ss4.close();
238 Thread::sleep(300);
239 assertTrue (srv.currentConnections() == 2);
240 assertTrue (srv.currentThreads() == 2);
241 assertTrue (srv.queuedConnections() == 0);
242 assertTrue (srv.totalConnections() == 6);
243
244 ss5.close();
245 ss6.close();
246 Thread::sleep(closeSleepTime);
247 assertTrue (srv.currentConnections() == 0);
248}
249
250
251void TCPServerTest::testReuseSocket()
252{
253 SecureServerSocket svs(0);
254 TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs);
255 srv.start();
256 assertTrue (srv.currentConnections() == 0);
257 assertTrue (srv.currentThreads() == 0);
258 assertTrue (srv.queuedConnections() == 0);
259 assertTrue (srv.totalConnections() == 0);
260
261 SocketAddress sa("127.0.0.1", svs.address().port());
262 SecureStreamSocket ss1(sa);
263 std::string data("hello, world");
264 ss1.sendBytes(data.data(), (int) data.size());
265 char buffer[256];
266 int n = ss1.receiveBytes(buffer, sizeof(buffer));
267 assertTrue (n > 0);
268 assertTrue (std::string(buffer, n) == data);
269 assertTrue (srv.currentConnections() == 1);
270 assertTrue (srv.currentThreads() == 1);
271 assertTrue (srv.queuedConnections() == 0);
272 assertTrue (srv.totalConnections() == 1);
273 ss1.close();
274 Thread::sleep(300);
275 assertTrue (srv.currentConnections() == 0);
276
277 ss1.connect(sa);
278 ss1.sendBytes(data.data(), (int) data.size());
279 n = ss1.receiveBytes(buffer, sizeof(buffer));
280 assertTrue (n > 0);
281 assertTrue (std::string(buffer, n) == data);
282 assertTrue (srv.currentConnections() == 1);
283 assertTrue (srv.queuedConnections() == 0);
284 assertTrue (srv.totalConnections() == 2);
285 ss1.close();
286 Thread::sleep(closeSleepTime);
287 assertTrue (srv.currentConnections() == 0);
288}
289
290
291void TCPServerTest::testReuseSession()
292{
293 // ensure OpenSSL machinery is fully setup
294 Context::Ptr pDefaultServerContext = SSLManager::instance().defaultServerContext();
295 Context::Ptr pDefaultClientContext = SSLManager::instance().defaultClientContext();
296
297 Context::Ptr pServerContext = new Context(
298 Context::SERVER_USE,
299 Application::instance().config().getString("openSSL.server.privateKeyFile"),
300 Application::instance().config().getString("openSSL.server.privateKeyFile"),
301 Application::instance().config().getString("openSSL.server.caConfig"),
302 Context::VERIFY_NONE,
303 9,
304 true,
305 "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
306 pServerContext->enableSessionCache(true, "TestSuite");
307 pServerContext->setSessionTimeout(10);
308 pServerContext->setSessionCacheSize(1000);
309 pServerContext->disableStatelessSessionResumption();
310
311 SecureServerSocket svs(0, 64, pServerContext);
312 TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs);
313 srv.start();
314 assertTrue (srv.currentConnections() == 0);
315 assertTrue (srv.currentThreads() == 0);
316 assertTrue (srv.queuedConnections() == 0);
317 assertTrue (srv.totalConnections() == 0);
318
319 Context::Ptr pClientContext = new Context(
320 Context::CLIENT_USE,
321 Application::instance().config().getString("openSSL.client.privateKeyFile"),
322 Application::instance().config().getString("openSSL.client.privateKeyFile"),
323 Application::instance().config().getString("openSSL.client.caConfig"),
324 Context::VERIFY_RELAXED,
325 9,
326 true,
327 "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
328 pClientContext->enableSessionCache(true);
329
330 SocketAddress sa("127.0.0.1", svs.address().port());
331 SecureStreamSocket ss1(sa, pClientContext);
332 assertTrue (!ss1.sessionWasReused());
333 std::string data("hello, world");
334 ss1.sendBytes(data.data(), (int) data.size());
335 char buffer[256];
336 int n = ss1.receiveBytes(buffer, sizeof(buffer));
337 assertTrue (n > 0);
338 assertTrue (std::string(buffer, n) == data);
339 assertTrue (srv.currentConnections() == 1);
340 assertTrue (srv.currentThreads() == 1);
341 assertTrue (srv.queuedConnections() == 0);
342 assertTrue (srv.totalConnections() == 1);
343
344 Session::Ptr pSession = ss1.currentSession();
345
346 ss1.close();
347 Thread::sleep(300);
348 assertTrue (srv.currentConnections() == 0);
349
350 ss1.useSession(pSession);
351 ss1.connect(sa);
352 assertTrue (ss1.sessionWasReused());
353 assertTrue (ss1.currentSession() == pSession);
354 ss1.sendBytes(data.data(), (int) data.size());
355 n = ss1.receiveBytes(buffer, sizeof(buffer));
356 assertTrue (n > 0);
357 assertTrue (std::string(buffer, n) == data);
358 assertTrue (srv.currentConnections() == 1);
359 assertTrue (srv.queuedConnections() == 0);
360 assertTrue (srv.totalConnections() == 2);
361 ss1.close();
362 Thread::sleep(300);
363 assertTrue (srv.currentConnections() == 0);
364
365 Thread::sleep(15000); // wait for session to expire
366 pServerContext->flushSessionCache();
367
368 ss1.useSession(pSession);
369 ss1.connect(sa);
370 assertTrue (!ss1.sessionWasReused());
371 assertTrue (ss1.currentSession() != pSession);
372 ss1.sendBytes(data.data(), (int) data.size());
373 n = ss1.receiveBytes(buffer, sizeof(buffer));
374 assertTrue (n > 0);
375 assertTrue (std::string(buffer, n) == data);
376 assertTrue (srv.currentConnections() == 1);
377 assertTrue (srv.queuedConnections() == 0);
378 assertTrue (srv.totalConnections() == 3);
379 ss1.close();
380 Thread::sleep(closeSleepTime);
381 assertTrue (srv.currentConnections() == 0);
382}
383
384
385void TCPServerTest::setUp()
386{
387}
388
389
390void TCPServerTest::tearDown()
391{
392}
393
394
395CppUnit::Test* TCPServerTest::suite()
396{
397 CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("TCPServerTest");
398
399 CppUnit_addTest(pSuite, TCPServerTest, testOneConnection);
400 CppUnit_addTest(pSuite, TCPServerTest, testTwoConnections);
401 CppUnit_addTest(pSuite, TCPServerTest, testMultiConnections);
402 CppUnit_addTest(pSuite, TCPServerTest, testReuseSocket);
403 CppUnit_addTest(pSuite, TCPServerTest, testReuseSession);
404
405 return pSuite;
406}
407