32 friend class HttpServer;
35 TcpSocket(HttpServer *);
39 void readEvent()
override;
42 Response *response =
nullptr;
43 WebSocket *ws_ =
nullptr;
49 friend class HttpServer;
52 enum class StatusCode {
54 SwitchingProtocols = 101,
59 NonAuthoritativeInformation = 203,
64 AlreadyReported = 208,
66 MultipleChoices = 300,
67 MovedPermanently = 301,
72 TemporaryRedirect = 307,
73 PermanentRedirect = 308,
76 PaymentRequired = 402,
79 MethodNotAllowed = 405,
81 ProxyAuthenticationRequired = 407,
86 PreconditionFailed = 412,
87 PayloadTooLarge = 413,
89 UnsupportedMediaType = 415,
90 RequestRangeNotSatisfiable = 416,
91 ExpectationFailed = 417,
93 MisdirectedRequest = 421,
94 UnprocessableEntity = 422,
96 FailedDependency = 424,
97 UpgradeRequired = 426,
98 PreconditionRequired = 428,
99 TooManyRequests = 429,
100 RequestHeaderFieldsTooLarge = 431,
102 UnavailableForLegalReasons = 451,
103 InternalServerError = 500,
104 NotImplemented = 501,
106 ServiceUnavailable = 503,
107 GatewayTimeout = 504,
108 HttpVersionNotSupported = 505,
109 VariantAlsoNegotiates = 506,
110 InsufficientStorage = 507,
113 NetworkAuthenticationRequired = 511,
114 NetworkConnectTimeoutError = 599
117 void setMimeType(
const std::string &mime) { mimeType_ = mime; }
118 std::string mimeType()
const {
return mimeType_; }
119 void addHeader(
const std::string &ba) { additionalHeaders.push_back(ba); }
120 std::string header()
const;
125 void setContent(
const std::vector<uint8_t> &);
126 void setStatusCode(
const StatusCode &_statusCode) { statusCode_ = _statusCode; }
127 bool fail() {
return socket_ ==
nullptr; }
129 Response::StatusCode statusCode() {
return statusCode_; }
131 TcpSocket *socket() {
return socket_; }
134 std::vector<std::string> additionalHeaders;
135 mutable StatusCode statusCode_ = Response::StatusCode::Ok;
136 mutable int contentLength = 0;
137 mutable std::string mimeType_;
140 std::string version =
"1.1";
141 bool cors_headers_enabled =
false;
142 mutable TcpSocket *socket_ =
nullptr;
146 friend class HttpServer;
164 Request(
const std::string_view &);
167 Method method()
const {
return method_; }
168 std::string methodName()
const;
169 std::string path()
const;
170 std::string heaaderItemValue(
const std::string &)
const;
171 std::string queryItemValue(
const std::string &)
const;
174 std::string peerAddress()
const {
return response_->socket_->peerAddress(); }
176 void setSocketData(
const std::any &data)
const { response_->socket_->data_ = data; }
177 std::any &socketData()
const {
return response_->socket_->data_; }
178 Response *response()
const {
return response_; }
179 bool switchingProtocols()
const;
185 Response *response_ =
nullptr;
191 friend class HttpServer;
194 const Request::Method method;
197 HttpRule(
const Request::Method method, std::function<
void(
const Request &)> exec) : method(method), exec(exec) {}
198 std::function<void(
const Request &)> exec;
202 using RulesMap = std::multimap<std::string, std::unique_ptr<HttpRule>>;
204 HttpServer(
const std::string & = {});
205 virtual ~HttpServer();
207 template <
typename A>
208 void addRoute(
const std::string &url, Request::Method method, A action,
const std::any &data = {}) {
209 addRule(url, method, [
this, action, data](
const Request &request) {
210 if (!peek || peek(request, data)) action(request);
212 if (findRule(url, Request::Method::Options) != rules.end())
return;
213 addRule(url, Request::Method::Options, [
this, action, data](
const Request &request) {
214 if (cors_request_enabled) request.response()->setStatusCode(Response::StatusCode::Ok);
215 else { request.response()->setStatusCode(Response::StatusCode::Forbidden); }
218 template <
typename O,
typename A>
219 void addRoute(
const O
object,
const std::string &url, Request::Method method, A action,
const std::any &data = {}) {
220 addRoute(url, method, [
object, action](
const Request &request) {
return (object->*action)(request); }, data);
223 template <
typename T>
224 void clearConnections(
const T &_data) {
225 for (TcpSocket *socket : sockets) {
226 if (socket->data_.has_value() && _data == std::any_cast<T>(socket->data_)) disconnectFromHost(socket);
229 void clearConnections() {
230 for (TcpSocket *socket : sockets) disconnectFromHost(socket);
232 template <
typename T>
236 for (TcpSocket *socket : sockets) {
237 if (!socket->ws_)
continue;
238 if (socket->data_.has_value() && _data == std::any_cast<T>(socket->data_)) {
240 int _s = makeWebSocketFrame(_da, &_f);
241 if (_s <= 0)
return -1;
249 void sendToWebSockets(
const std::string &);
251 void disconnectFromHost(TcpSocket *socket);
252 bool listen(uint16_t port);
258 void addRule(
const std::string &,
const Request::Method, std::function<
void(
const Request &)>);
259 bool execRule(
const Request &);
262 void setEnableCorsRequests(
bool);
263 void setPeek(std::function<
bool(
const Request &,
const std::any &)> f) { peek = f; }
265 static HttpServer *instance() {
return instance_.value; }
266 AsyncFw::FunctionConnectorProtected<HttpServer>::Connector<int,
const std::string &,
bool *> incoming {AsyncFw::AbstractFunctionConnector::SyncOnly};
269 virtual void fileUploadProgress(TcpSocket *,
int);
273 bool incomingConnection(
int,
const std::string &);
274 void received(TcpSocket *,
const std::string_view &);
276 RulesMap::iterator findRule(
const std::string &,
const Request::Method);
277 std::vector<TcpSocket *> sockets;
278 bool cors_request_enabled =
true;
280 std::function<bool(
const Request &, std::any)> peek;
The TlsContext class provides functionality for managing TLS certificates.
Definition TlsContext.h:24