1//
2// HTTPSServerTest.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 "HTTPSServerTest.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/HTTPRequestHandler.h"
17#include "Poco/Net/HTTPRequestHandlerFactory.h"
18#include "Poco/Net/HTTPSClientSession.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/SecureServerSocket.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::HTTPRequestHandlerFactory;
32using Poco::Net::HTTPSClientSession;
33using Poco::Net::HTTPRequest;
34using Poco::Net::HTTPServerRequest;
35using Poco::Net::HTTPResponse;
36using Poco::Net::HTTPServerResponse;
37using Poco::Net::HTTPMessage;
38using Poco::Net::SecureServerSocket;
39using Poco::StreamCopier;
40
41
42namespace
43{
44 class EchoBodyRequestHandler: public HTTPRequestHandler
45 {
46 public:
47 void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
48 {
49 if (request.getChunkedTransferEncoding())
50 response.setChunkedTransferEncoding(true);
51 else if (request.getContentLength() != HTTPMessage::UNKNOWN_CONTENT_LENGTH)
52 response.setContentLength(request.getContentLength());
53
54 response.setContentType(request.getContentType());
55
56 std::istream& istr = request.stream();
57 std::ostream& ostr = response.send();
58 StreamCopier::copyStream(istr, ostr);
59 }
60 };
61
62 class EchoHeaderRequestHandler: public HTTPRequestHandler
63 {
64 public:
65 void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
66 {
67 std::ostringstream osstr;
68 request.write(osstr);
69 int n = (int) osstr.str().length();
70 response.setContentLength(n);
71 std::ostream& ostr = response.send();
72 if (request.getMethod() != HTTPRequest::HTTP_HEAD)
73 request.write(ostr);
74 }
75 };
76
77 class RedirectRequestHandler: public HTTPRequestHandler
78 {
79 public:
80 void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
81 {
82 response.redirect("http://www.appinf.com/");
83 }
84 };
85
86 class AuthRequestHandler: public HTTPRequestHandler
87 {
88 public:
89 void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
90 {
91 response.requireAuthentication("/auth");
92 response.send();
93 }
94 };
95
96 class RequestHandlerFactory: public HTTPRequestHandlerFactory
97 {
98 public:
99 HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
100 {
101 if (request.getURI() == "/echoBody")
102 return new EchoBodyRequestHandler;
103 else if (request.getURI() == "/echoHeader")
104 return new EchoHeaderRequestHandler;
105 else if (request.getURI() == "/redirect")
106 return new RedirectRequestHandler();
107 else if (request.getURI() == "/auth")
108 return new AuthRequestHandler();
109 else
110 return 0;
111 }
112 };
113}
114
115
116HTTPSServerTest::HTTPSServerTest(const std::string& name): CppUnit::TestCase(name)
117{
118}
119
120
121HTTPSServerTest::~HTTPSServerTest()
122{
123}
124
125
126void HTTPSServerTest::testIdentityRequest()
127{
128 SecureServerSocket svs(0);
129 HTTPServerParams* pParams = new HTTPServerParams;
130 pParams->setKeepAlive(false);
131 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
132 srv.start();
133
134 HTTPSClientSession cs("127.0.0.1", svs.address().port());
135 std::string body(5000, 'x');
136 HTTPRequest request("POST", "/echoBody");
137 request.setContentLength((int) body.length());
138 request.setContentType("text/plain");
139 cs.sendRequest(request) << body;
140 HTTPResponse response;
141 std::string rbody;
142 cs.receiveResponse(response) >> rbody;
143 assertTrue (response.getContentLength() == body.size());
144 assertTrue (response.getContentType() == "text/plain");
145 assertTrue (rbody == body);
146}
147
148
149void HTTPSServerTest::testChunkedRequest()
150{
151 SecureServerSocket svs(0);
152 HTTPServerParams* pParams = new HTTPServerParams;
153 pParams->setKeepAlive(false);
154 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
155 srv.start();
156
157 HTTPSClientSession cs("127.0.0.1", svs.address().port());
158 std::string body(5000, 'x');
159 HTTPRequest request("POST", "/echoBody");
160 request.setContentType("text/plain");
161 request.setChunkedTransferEncoding(true);
162 cs.sendRequest(request) << body;
163 HTTPResponse response;
164 std::string rbody;
165 cs.receiveResponse(response) >> rbody;
166 assertTrue (response.getContentLength() == HTTPMessage::UNKNOWN_CONTENT_LENGTH);
167 assertTrue (response.getContentType() == "text/plain");
168 assertTrue (response.getChunkedTransferEncoding());
169 assertTrue (rbody == body);
170}
171
172
173void HTTPSServerTest::testIdentityRequestKeepAlive()
174{
175 SecureServerSocket svs(0);
176 HTTPServerParams* pParams = new HTTPServerParams;
177 pParams->setKeepAlive(true);
178 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
179 srv.start();
180
181 HTTPSClientSession cs("127.0.0.1", svs.address().port());
182 cs.setKeepAlive(true);
183 std::string body(5000, 'x');
184 HTTPRequest request("POST", "/echoBody", HTTPMessage::HTTP_1_1);
185 request.setContentLength((int) body.length());
186 request.setContentType("text/plain");
187 cs.sendRequest(request) << body;
188 HTTPResponse response;
189 std::string rbody;
190 cs.receiveResponse(response) >> rbody;
191 assertTrue (response.getContentLength() == body.size());
192 assertTrue (response.getContentType() == "text/plain");
193 assertTrue (response.getKeepAlive());
194 assertTrue (rbody == body);
195
196 body.assign(1000, 'y');
197 request.setContentLength((int) body.length());
198 request.setKeepAlive(false);
199 cs.sendRequest(request) << body;
200 cs.receiveResponse(response) >> rbody;
201 assertTrue (response.getContentLength() == body.size());
202 assertTrue (response.getContentType() == "text/plain");
203 assertTrue (!response.getKeepAlive());
204 assertTrue (rbody == body);}
205
206
207void HTTPSServerTest::testChunkedRequestKeepAlive()
208{
209 SecureServerSocket svs(0);
210 HTTPServerParams* pParams = new HTTPServerParams;
211 pParams->setKeepAlive(true);
212 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
213 srv.start();
214
215 HTTPSClientSession cs("127.0.0.1", svs.address().port());
216 cs.setKeepAlive(true);
217 std::string body(5000, 'x');
218 HTTPRequest request("POST", "/echoBody", HTTPMessage::HTTP_1_1);
219 request.setContentType("text/plain");
220 request.setChunkedTransferEncoding(true);
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 body.assign(1000, 'y');
231 request.setKeepAlive(false);
232 cs.sendRequest(request) << body;
233 cs.receiveResponse(response) >> rbody;
234 assertTrue (response.getContentLength() == HTTPMessage::UNKNOWN_CONTENT_LENGTH);
235 assertTrue (response.getContentType() == "text/plain");
236 assertTrue (response.getChunkedTransferEncoding());
237 assertTrue (!response.getKeepAlive());
238 assertTrue (rbody == body);
239}
240
241
242void HTTPSServerTest::test100Continue()
243{
244 SecureServerSocket svs(0);
245 HTTPServerParams* pParams = new HTTPServerParams;
246 pParams->setKeepAlive(false);
247 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
248 srv.start();
249
250 HTTPSClientSession cs("127.0.0.1", svs.address().port());
251 std::string body(5000, 'x');
252 HTTPRequest request("POST", "/echoBody");
253 request.setContentLength((int) body.length());
254 request.setContentType("text/plain");
255 request.set("Expect", "100-Continue");
256 cs.sendRequest(request) << body;
257 HTTPResponse response;
258 std::string rbody;
259 cs.receiveResponse(response) >> rbody;
260 assertTrue (response.getContentLength() == body.size());
261 assertTrue (response.getContentType() == "text/plain");
262 assertTrue (rbody == body);
263}
264
265
266void HTTPSServerTest::testRedirect()
267{
268 SecureServerSocket svs(0);
269 HTTPServerParams* pParams = new HTTPServerParams;
270 pParams->setKeepAlive(false);
271 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
272 srv.start();
273
274 HTTPSClientSession cs("127.0.0.1", svs.address().port());
275 HTTPRequest request("GET", "/redirect");
276 cs.sendRequest(request);
277 HTTPResponse response;
278 std::string rbody;
279 cs.receiveResponse(response) >> rbody;
280 assertTrue (response.getStatus() == HTTPResponse::HTTP_FOUND);
281 assertTrue (response.get("Location") == "http://www.appinf.com/");
282 assertTrue (rbody.empty());
283}
284
285
286void HTTPSServerTest::testAuth()
287{
288 SecureServerSocket svs(0);
289 HTTPServerParams* pParams = new HTTPServerParams;
290 pParams->setKeepAlive(false);
291 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
292 srv.start();
293
294 HTTPSClientSession cs("127.0.0.1", svs.address().port());
295 HTTPRequest request("GET", "/auth");
296 cs.sendRequest(request);
297 HTTPResponse response;
298 std::string rbody;
299 cs.receiveResponse(response) >> rbody;
300 assertTrue (response.getStatus() == HTTPResponse::HTTP_UNAUTHORIZED);
301 assertTrue (response.get("WWW-Authenticate") == "Basic realm=\"/auth\"");
302 assertTrue (rbody.empty());
303}
304
305
306void HTTPSServerTest::testNotImpl()
307{
308 SecureServerSocket svs(0);
309 HTTPServerParams* pParams = new HTTPServerParams;
310 pParams->setKeepAlive(false);
311 HTTPServer srv(new RequestHandlerFactory, svs, pParams);
312 srv.start();
313
314 HTTPSClientSession cs("127.0.0.1", svs.address().port());
315 HTTPRequest request("GET", "/notImpl");
316 cs.sendRequest(request);
317 HTTPResponse response;
318 std::string rbody;
319 cs.receiveResponse(response) >> rbody;
320 assertTrue (response.getStatus() == HTTPResponse::HTTP_NOT_IMPLEMENTED);
321 assertTrue (rbody.empty());
322}
323
324
325void HTTPSServerTest::setUp()
326{
327}
328
329
330void HTTPSServerTest::tearDown()
331{
332}
333
334
335CppUnit::Test* HTTPSServerTest::suite()
336{
337 CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("HTTPSServerTest");
338
339 CppUnit_addTest(pSuite, HTTPSServerTest, testIdentityRequest);
340 CppUnit_addTest(pSuite, HTTPSServerTest, testChunkedRequest);
341 CppUnit_addTest(pSuite, HTTPSServerTest, testIdentityRequestKeepAlive);
342 CppUnit_addTest(pSuite, HTTPSServerTest, testChunkedRequestKeepAlive);
343 CppUnit_addTest(pSuite, HTTPSServerTest, test100Continue);
344 CppUnit_addTest(pSuite, HTTPSServerTest, testRedirect);
345 CppUnit_addTest(pSuite, HTTPSServerTest, testAuth);
346 CppUnit_addTest(pSuite, HTTPSServerTest, testNotImpl);
347
348 return pSuite;
349}
350