1//
2// HTTPServerConnection.cpp
3//
4// Library: Net
5// Package: HTTPServer
6// Module: HTTPServerConnection
7//
8// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/Net/HTTPServerConnection.h"
16#include "Poco/Net/HTTPServerSession.h"
17#include "Poco/Net/HTTPServerRequestImpl.h"
18#include "Poco/Net/HTTPServerResponseImpl.h"
19#include "Poco/Net/HTTPRequestHandler.h"
20#include "Poco/Net/HTTPRequestHandlerFactory.h"
21#include "Poco/Net/NetException.h"
22#include "Poco/NumberFormatter.h"
23#include "Poco/Timestamp.h"
24#include "Poco/Delegate.h"
25#include <memory>
26
27
28namespace Poco {
29namespace Net {
30
31
32HTTPServerConnection::HTTPServerConnection(const StreamSocket& socket, HTTPServerParams::Ptr pParams, HTTPRequestHandlerFactory::Ptr pFactory):
33 TCPServerConnection(socket),
34 _pParams(pParams),
35 _pFactory(pFactory),
36 _stopped(false)
37{
38 poco_check_ptr (pFactory);
39
40 _pFactory->serverStopped += Poco::delegate(this, &HTTPServerConnection::onServerStopped);
41}
42
43
44HTTPServerConnection::~HTTPServerConnection()
45{
46 try
47 {
48 _pFactory->serverStopped -= Poco::delegate(this, &HTTPServerConnection::onServerStopped);
49 }
50 catch (...)
51 {
52 poco_unexpected();
53 }
54}
55
56
57void HTTPServerConnection::run()
58{
59 std::string server = _pParams->getSoftwareVersion();
60 HTTPServerSession session(socket(), _pParams);
61 while (!_stopped && session.hasMoreRequests())
62 {
63 try
64 {
65 Poco::FastMutex::ScopedLock lock(_mutex);
66 if (!_stopped)
67 {
68 HTTPServerResponseImpl response(session);
69 HTTPServerRequestImpl request(response, session, _pParams);
70
71 Poco::Timestamp now;
72 response.setDate(now);
73 response.setVersion(request.getVersion());
74 response.setKeepAlive(_pParams->getKeepAlive() && request.getKeepAlive() && session.canKeepAlive());
75 if (!server.empty())
76 response.set("Server", server);
77 try
78 {
79 std::unique_ptr<HTTPRequestHandler> pHandler(_pFactory->createRequestHandler(request));
80 if (pHandler.get())
81 {
82 if (request.getExpectContinue() && response.getStatus() == HTTPResponse::HTTP_OK)
83 response.sendContinue();
84
85 pHandler->handleRequest(request, response);
86 session.setKeepAlive(_pParams->getKeepAlive() && response.getKeepAlive() && session.canKeepAlive());
87 }
88 else sendErrorResponse(session, HTTPResponse::HTTP_NOT_IMPLEMENTED);
89 }
90 catch (Poco::Exception&)
91 {
92 if (!response.sent())
93 {
94 try
95 {
96 sendErrorResponse(session, HTTPResponse::HTTP_INTERNAL_SERVER_ERROR);
97 }
98 catch (...)
99 {
100 }
101 }
102 throw;
103 }
104 }
105 }
106 catch (NoMessageException&)
107 {
108 break;
109 }
110 catch (MessageException&)
111 {
112 sendErrorResponse(session, HTTPResponse::HTTP_BAD_REQUEST);
113 }
114 catch (Poco::Exception&)
115 {
116 if (session.networkException())
117 {
118 session.networkException()->rethrow();
119 }
120 else throw;
121 }
122 }
123}
124
125
126void HTTPServerConnection::sendErrorResponse(HTTPServerSession& session, HTTPResponse::HTTPStatus status)
127{
128 HTTPServerResponseImpl response(session);
129 response.setVersion(HTTPMessage::HTTP_1_1);
130 response.setStatusAndReason(status);
131 response.setKeepAlive(false);
132 response.send();
133 session.setKeepAlive(false);
134}
135
136
137void HTTPServerConnection::onServerStopped(const bool& abortCurrent)
138{
139 _stopped = true;
140 if (abortCurrent)
141 {
142 try
143 {
144 // Note: On Windows, select() will not return if one of its socket is being
145 // shut down. Therefore we have to call close(), which works better.
146 // On other platforms, we do the more graceful thing.
147#if defined(_WIN32)
148 socket().close();
149#else
150 socket().shutdown();
151#endif
152 }
153 catch (...)
154 {
155 }
156 }
157 else
158 {
159 Poco::FastMutex::ScopedLock lock(_mutex);
160
161 try
162 {
163#if defined(_WIN32)
164 socket().close();
165#else
166 socket().shutdown();
167#endif
168 }
169 catch (...)
170 {
171 }
172 }
173}
174
175
176} } // namespace Poco::Net
177