1//
2// HTTPServerTest.cpp
3//
4// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
5// and Contributors.
6//
7// SPDX-License-Identifier: BSL-1.0
8//
9
10
11#include "HTTPServerTest.h"
12#include "Poco/CppUnit/TestCaller.h"
13#include "Poco/CppUnit/TestSuite.h"
14#include "Poco/Net/HTTPServer.h"
15#include "Poco/Net/HTTPServerParams.h"
16#include "Poco/Net/AbstractHTTPRequestHandler.h"
17#include "Poco/Net/HTTPRequestHandlerFactory.h"
18#include "Poco/Net/HTTPClientSession.h"
19#include "Poco/Net/HTTPRequest.h"
20#include "Poco/Net/HTTPServerRequest.h"
21#include "Poco/Net/HTTPResponse.h"
22#include "Poco/Net/HTTPServerResponse.h"
23#include "Poco/Net/ServerSocket.h"
24#include "Poco/StreamCopier.h"
25#include <sstream>
26
27
28using Poco::Net::HTTPServer;
29using Poco::Net::HTTPServerParams;
30using Poco::Net::HTTPRequestHandler;
31using Poco::Net::AbstractHTTPRequestHandler;
32using Poco::Net::HTTPRequestHandlerFactory;
33using Poco::Net::HTTPClientSession;
34using Poco::Net::HTTPRequest;
35using Poco::Net::HTTPServerRequest;
36using Poco::Net::HTTPResponse;
37using Poco::Net::HTTPServerResponse;
38using Poco::Net::HTTPMessage;
39using Poco::Net::ServerSocket;
40using Poco::StreamCopier;
41
42
43namespace
44{
45 class EchoBodyRequestHandler: public HTTPRequestHandler
46 {
47 public:
48 void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
49 {
50 if (request.getChunkedTransferEncoding())
51 response.setChunkedTransferEncoding(true);
52 else if (request.getContentLength() != HTTPMessage::UNKNOWN_CONTENT_LENGTH)
53 response.setContentLength(request.getContentLength());
54
55 response.setContentType(request.getContentType());
56
57 std::istream& istr = request.stream();
58 std::ostream& ostr = response.send();
59 StreamCopier::copyStream(istr, ostr);
60 }
61 };
62
63 class EchoHeaderRequestHandler: public HTTPRequestHandler
64 {
65 public:
66 void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
67 {
68 std::ostringstream osstr;
69 request.write(osstr);
70 int n = (int) osstr.str().length();
71 response.setContentLength(n);
72 std::ostream& ostr = response.send();
73 if (request.getMethod() != HTTPRequest::HTTP_HEAD)
74 request.write(ostr);
75 }
76 };
77
78 class RedirectRequestHandler: public AbstractHTTPRequestHandler
79 {
80 public:
81 void run()
82 {
83 response().redirect("http://www.appinf.com/");
84 }
85 };
86
87 class AuthRequestHandler: public HTTPRequestHandler
88 {
89 public:
90 void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
91 {
92 response.requireAuthentication("/auth");
93 response.send();
94 }
95 };
96
97 class BufferRequestHandler: public HTTPRequestHandler
98 {
99 public:
100 void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
101 {
102 std::string data("xxxxxxxxxx");
103 response.sendBuffer(data.data(), data.length());
104 }
105 };
106
107 class RequestHandlerFactory: public HTTPRequestHandlerFactory
108 {
109 public:
110 HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
111 {
112 if (request.getURI() == "/echoBody")
113 return new EchoBodyRequestHandler;
114 else if (request.getURI() == "/echoHeader")
115 return new EchoHeaderRequestHandler;
116 else if (request.getURI() == "/redirect")
117 return new RedirectRequestHandler();
118 else if (request.getURI() == "/auth")
119 return new AuthRequestHandler();
120 else if (request.getURI() == "/buffer")
121 return new BufferRequestHandler();
122 else
123 return 0;
124 }
125 };
126}
127
128
129HTTPServerTest::HTTPServerTest(const std::string& name): CppUnit::TestCase(name)
130{
131}
132
133
134HTTPServerTest::~HTTPServerTest()
135{
136}
137
138
139void HTTPServerTest::testIdentityRequest()
140{
141 ServerSocket svs(0);
142 HTTPServerParams* pParams = new HTTPServerParams;
143 pParams->setKeepAlive(false);
144 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
145 srv.start();
146
147 HTTPClientSession cs("127.0.0.1", svs.address().port());
148 std::string body(5000, 'x');
149 HTTPRequest request("POST", "/echoBody");
150 request.setContentLength((int) body.length());
151 request.setContentType("text/plain");
152 cs.sendRequest(request) << body;
153 HTTPResponse response;
154 std::string rbody;
155 cs.receiveResponse(response) >> rbody;
156 assertTrue (response.getContentLength() == body.size());
157 assertTrue (response.getContentType() == "text/plain");
158 assertTrue (rbody == body);
159}
160
161
162void HTTPServerTest::testPutIdentityRequest()
163{
164 ServerSocket svs(0);
165 HTTPServerParams* pParams = new HTTPServerParams;
166 pParams->setKeepAlive(false);
167 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
168 srv.start();
169
170 HTTPClientSession cs("127.0.0.1", svs.address().port());
171 std::string body(5000, 'x');
172 HTTPRequest request("PUT", "/echoBody");
173 request.setContentLength((int) body.length());
174 request.setContentType("text/plain");
175 cs.sendRequest(request) << body;
176 HTTPResponse response;
177 std::string rbody;
178 cs.receiveResponse(response) >> rbody;
179 assertTrue (response.getContentLength() == body.size());
180 assertTrue (response.getContentType() == "text/plain");
181 assertTrue (rbody == body);
182}
183
184
185void HTTPServerTest::testChunkedRequest()
186{
187 ServerSocket svs(0);
188 HTTPServerParams* pParams = new HTTPServerParams;
189 pParams->setKeepAlive(false);
190 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
191 srv.start();
192
193 HTTPClientSession cs("127.0.0.1", svs.address().port());
194 std::string body(5000, 'x');
195 HTTPRequest request("POST", "/echoBody");
196 request.setContentType("text/plain");
197 request.setChunkedTransferEncoding(true);
198 cs.sendRequest(request) << body;
199 HTTPResponse response;
200 std::string rbody;
201 cs.receiveResponse(response) >> rbody;
202 assertTrue (response.getContentLength() == HTTPMessage::UNKNOWN_CONTENT_LENGTH);
203 assertTrue (response.getContentType() == "text/plain");
204 assertTrue (response.getChunkedTransferEncoding());
205 assertTrue (rbody == body);
206}
207
208
209void HTTPServerTest::testClosedRequest()
210{
211 ServerSocket svs(0);
212 HTTPServerParams* pParams = new HTTPServerParams;
213 pParams->setKeepAlive(false);
214 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
215 srv.start();
216
217 HTTPClientSession cs("127.0.0.1", svs.address().port());
218 std::string body(5000, 'x');
219 HTTPRequest request("POST", "/echoBody");
220 request.setContentType("text/plain");
221 cs.sendRequest(request) << body;
222 HTTPResponse response;
223 std::string rbody;
224 cs.receiveResponse(response) >> rbody;
225 assertTrue (response.getContentLength() == HTTPMessage::UNKNOWN_CONTENT_LENGTH);
226 assertTrue (response.getContentType() == "text/plain");
227 assertTrue (!response.getChunkedTransferEncoding());
228 assertTrue (rbody == body);
229}
230
231
232void HTTPServerTest::testIdentityRequestKeepAlive()
233{
234 HTTPServer srv(new RequestHandlerFactory, 8008);
235 srv.start();
236
237 HTTPClientSession cs("127.0.0.1", srv.socket().address().port());
238 cs.setKeepAlive(true);
239 std::string body(5000, 'x');
240 HTTPRequest request("POST", "/echoBody", HTTPMessage::HTTP_1_1);
241 request.setContentLength((int) body.length());
242 request.setContentType("text/plain");
243 cs.sendRequest(request) << body;
244 HTTPResponse response;
245 std::string rbody;
246 cs.receiveResponse(response) >> rbody;
247 assertTrue (response.getContentLength() == body.size());
248 assertTrue (response.getContentType() == "text/plain");
249 assertTrue (response.getKeepAlive());
250 assertTrue (rbody == body);
251
252 body.assign(1000, 'y');
253 request.setContentLength((int) body.length());
254 request.setKeepAlive(false);
255 cs.sendRequest(request) << body;
256 cs.receiveResponse(response) >> rbody;
257 assertTrue (response.getContentLength() == body.size());
258 assertTrue (response.getContentType() == "text/plain");
259 assertTrue (!response.getKeepAlive());
260 assertTrue (rbody == body);}
261
262
263void HTTPServerTest::testChunkedRequestKeepAlive()
264{
265 HTTPServer srv(new RequestHandlerFactory, 8009);
266 srv.start();
267
268 HTTPClientSession cs("127.0.0.1", srv.socket().address().port());
269 cs.setKeepAlive(true);
270 std::string body(5000, 'x');
271 HTTPRequest request("POST", "/echoBody", HTTPMessage::HTTP_1_1);
272 request.setContentType("text/plain");
273 request.setChunkedTransferEncoding(true);
274 cs.sendRequest(request) << body;
275 HTTPResponse response;
276 std::string rbody;
277 cs.receiveResponse(response) >> rbody;
278 assertTrue (response.getContentLength() == HTTPMessage::UNKNOWN_CONTENT_LENGTH);
279 assertTrue (response.getContentType() == "text/plain");
280 assertTrue (response.getChunkedTransferEncoding());
281 assertTrue (rbody == body);
282
283 body.assign(1000, 'y');
284 request.setKeepAlive(false);
285 cs.sendRequest(request) << body;
286 cs.receiveResponse(response) >> rbody;
287 assertTrue (response.getContentLength() == HTTPMessage::UNKNOWN_CONTENT_LENGTH);
288 assertTrue (response.getContentType() == "text/plain");
289 assertTrue (response.getChunkedTransferEncoding());
290 assertTrue (!response.getKeepAlive());
291 assertTrue (rbody == body);
292}
293
294
295void HTTPServerTest::testClosedRequestKeepAlive()
296{
297 HTTPServer srv(new RequestHandlerFactory, 8010);
298 srv.start();
299
300 HTTPClientSession cs("127.0.0.1", srv.socket().address().port());
301 std::string body(5000, 'x');
302 HTTPRequest request("POST", "/echoBody");
303 request.setContentType("text/plain");
304 cs.sendRequest(request) << body;
305 HTTPResponse response;
306 std::string rbody;
307 cs.receiveResponse(response) >> rbody;
308 assertTrue (response.getContentLength() == HTTPMessage::UNKNOWN_CONTENT_LENGTH);
309 assertTrue (response.getContentType() == "text/plain");
310 assertTrue (!response.getChunkedTransferEncoding());
311 assertTrue (!response.getKeepAlive());
312 assertTrue (rbody == body);
313}
314
315
316void HTTPServerTest::testMaxKeepAlive()
317{
318 ServerSocket svs(0);
319 HTTPServerParams* pParams = new HTTPServerParams;
320 pParams->setKeepAlive(true);
321 pParams->setMaxKeepAliveRequests(4);
322 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
323 srv.start();
324
325 HTTPClientSession cs("127.0.0.1", svs.address().port());
326 cs.setKeepAlive(true);
327 HTTPRequest request("POST", "/echoBody", HTTPMessage::HTTP_1_1);
328 request.setContentType("text/plain");
329 request.setChunkedTransferEncoding(true);
330 std::string body(5000, 'x');
331 for (int i = 0; i < 3; ++i)
332 {
333 cs.sendRequest(request) << body;
334 HTTPResponse response;
335 std::string rbody;
336 cs.receiveResponse(response) >> rbody;
337 assertTrue (response.getContentLength() == HTTPMessage::UNKNOWN_CONTENT_LENGTH);
338 assertTrue (response.getContentType() == "text/plain");
339 assertTrue (response.getChunkedTransferEncoding());
340 assertTrue (response.getKeepAlive());
341 assertTrue (rbody == body);
342 }
343
344 {
345 cs.sendRequest(request) << body;
346 HTTPResponse response;
347 std::string rbody;
348 cs.receiveResponse(response) >> rbody;
349 assertTrue (response.getContentLength() == HTTPMessage::UNKNOWN_CONTENT_LENGTH);
350 assertTrue (response.getContentType() == "text/plain");
351 assertTrue (response.getChunkedTransferEncoding());
352 assertTrue (!response.getKeepAlive());
353 assertTrue (rbody == body);
354 }
355
356 {
357 cs.setKeepAlive(false);
358 cs.sendRequest(request) << body;
359 HTTPResponse response;
360 std::string rbody;
361 cs.receiveResponse(response) >> rbody;
362 assertTrue (response.getContentLength() == HTTPMessage::UNKNOWN_CONTENT_LENGTH);
363 assertTrue (response.getContentType() == "text/plain");
364 assertTrue (response.getChunkedTransferEncoding());
365 assertTrue (!response.getKeepAlive());
366 assertTrue (rbody == body);
367 }
368}
369
370
371void HTTPServerTest::testKeepAliveTimeout()
372{
373 ServerSocket svs(0);
374 HTTPServerParams* pParams = new HTTPServerParams;
375 pParams->setKeepAlive(true);
376 pParams->setMaxKeepAliveRequests(4);
377 pParams->setKeepAliveTimeout(Poco::Timespan(3, 0));
378 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
379 srv.start();
380
381 HTTPClientSession cs("127.0.0.1", svs.address().port());
382 cs.setKeepAlive(true);
383 cs.setKeepAliveTimeout(Poco::Timespan(2, 0));
384 HTTPRequest request("POST", "/echoBody", HTTPMessage::HTTP_1_1);
385 request.setContentType("text/plain");
386 request.setChunkedTransferEncoding(true);
387 std::string body(5000, 'x');
388 for (int i = 0; i < 3; ++i)
389 {
390 cs.sendRequest(request) << body;
391 HTTPResponse response;
392 std::string rbody;
393 cs.receiveResponse(response) >> rbody;
394 assertTrue (response.getContentLength() == HTTPMessage::UNKNOWN_CONTENT_LENGTH);
395 assertTrue (response.getContentType() == "text/plain");
396 assertTrue (response.getChunkedTransferEncoding());
397 assertTrue (response.getKeepAlive());
398 assertTrue (rbody == body);
399 }
400
401 Poco::Thread::sleep(4000);
402
403 {
404 cs.sendRequest(request) << body;
405 HTTPResponse response;
406 std::string rbody;
407 cs.receiveResponse(response) >> rbody;
408 assertTrue (response.getContentLength() == HTTPMessage::UNKNOWN_CONTENT_LENGTH);
409 assertTrue (response.getContentType() == "text/plain");
410 assertTrue (response.getChunkedTransferEncoding());
411 assertTrue (response.getKeepAlive());
412 assertTrue (rbody == body);
413 }
414}
415
416
417void HTTPServerTest::test100Continue()
418{
419 ServerSocket svs(0);
420 HTTPServerParams* pParams = new HTTPServerParams;
421 pParams->setKeepAlive(false);
422 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
423 srv.start();
424
425 HTTPClientSession cs("127.0.0.1", svs.address().port());
426 std::string body(5000, 'x');
427 HTTPRequest request("POST", "/echoBody");
428 request.setContentLength((int) body.length());
429 request.setContentType("text/plain");
430 request.set("Expect", "100-Continue");
431 cs.sendRequest(request) << body;
432 HTTPResponse response;
433 std::string rbody;
434 cs.receiveResponse(response) >> rbody;
435 assertTrue (response.getContentLength() == body.size());
436 assertTrue (response.getContentType() == "text/plain");
437 assertTrue (rbody == body);
438}
439
440
441void HTTPServerTest::testRedirect()
442{
443 ServerSocket svs(0);
444 HTTPServerParams* pParams = new HTTPServerParams;
445 pParams->setKeepAlive(false);
446 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
447 srv.start();
448
449 HTTPClientSession cs("127.0.0.1", svs.address().port());
450 HTTPRequest request("GET", "/redirect");
451 cs.sendRequest(request);
452 HTTPResponse response;
453 std::string rbody;
454 cs.receiveResponse(response) >> rbody;
455 assertTrue (response.getStatus() == HTTPResponse::HTTP_FOUND);
456 assertTrue (response.get("Location") == "http://www.appinf.com/");
457 assertTrue (rbody.empty());
458}
459
460
461void HTTPServerTest::testAuth()
462{
463 ServerSocket svs(0);
464 HTTPServerParams* pParams = new HTTPServerParams;
465 pParams->setKeepAlive(false);
466 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
467 srv.start();
468
469 HTTPClientSession cs("127.0.0.1", svs.address().port());
470 HTTPRequest request("GET", "/auth");
471 cs.sendRequest(request);
472 HTTPResponse response;
473 std::string rbody;
474 cs.receiveResponse(response) >> rbody;
475 assertTrue (response.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED);
476 assertTrue (response.get("WWW-Authenticate") == "Basic realm=\"/auth\"");
477 assertTrue (rbody.empty());
478}
479
480
481void HTTPServerTest::testNotImpl()
482{
483 ServerSocket svs(0);
484 HTTPServerParams* pParams = new HTTPServerParams;
485 pParams->setKeepAlive(false);
486 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
487 srv.start();
488
489 HTTPClientSession cs("127.0.0.1", svs.address().port());
490 HTTPRequest request("GET", "/notImpl");
491 cs.sendRequest(request);
492 HTTPResponse response;
493 std::string rbody;
494 cs.receiveResponse(response) >> rbody;
495 assertTrue (response.getStatus() == HTTPResponse::HTTP_NOT_IMPLEMENTED);
496 assertTrue (rbody.empty());
497}
498
499
500void HTTPServerTest::testBuffer()
501{
502 ServerSocket svs(0);
503 HTTPServerParams* pParams = new HTTPServerParams;
504 pParams->setKeepAlive(false);
505 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
506 srv.start();
507
508 HTTPClientSession cs("127.0.0.1", svs.address().port());
509 HTTPRequest request("GET", "/buffer");
510 cs.sendRequest(request);
511 HTTPResponse response;
512 std::string rbody;
513 cs.receiveResponse(response) >> rbody;
514 assertTrue (response.getStatus() == HTTPResponse::HTTP_OK);
515 assertTrue (rbody == "xxxxxxxxxx");
516}
517
518
519void HTTPServerTest::setUp()
520{
521}
522
523
524void HTTPServerTest::tearDown()
525{
526}
527
528
529CppUnit::Test* HTTPServerTest::suite()
530{
531 CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("HTTPServerTest");
532
533 CppUnit_addTest(pSuite, HTTPServerTest, testIdentityRequest);
534 CppUnit_addTest(pSuite, HTTPServerTest, testPutIdentityRequest);
535 CppUnit_addTest(pSuite, HTTPServerTest, testChunkedRequest);
536 CppUnit_addTest(pSuite, HTTPServerTest, testClosedRequest);
537 CppUnit_addTest(pSuite, HTTPServerTest, testIdentityRequestKeepAlive);
538 CppUnit_addTest(pSuite, HTTPServerTest, testChunkedRequestKeepAlive);
539 CppUnit_addTest(pSuite, HTTPServerTest, testClosedRequestKeepAlive);
540 CppUnit_addTest(pSuite, HTTPServerTest, testMaxKeepAlive);
541 CppUnit_addTest(pSuite, HTTPServerTest, testKeepAliveTimeout);
542 CppUnit_addTest(pSuite, HTTPServerTest, test100Continue);
543 CppUnit_addTest(pSuite, HTTPServerTest, testRedirect);
544 CppUnit_addTest(pSuite, HTTPServerTest, testAuth);
545 CppUnit_addTest(pSuite, HTTPServerTest, testNotImpl);
546 CppUnit_addTest(pSuite, HTTPServerTest, testBuffer);
547
548 return pSuite;
549}
550