cutelyst 3.9.1
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
engine.cpp
1/*
2 * SPDX-FileCopyrightText: (C) 2013-2022 Daniel Nicoletti <dantti12@gmail.com>
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5#include "application.h"
6#include "common.h"
7#include "context_p.h"
8#include "engine_p.h"
9#include "request_p.h"
10#include "response_p.h"
11
12#include <QByteArray>
13#include <QDir>
14#include <QJsonDocument>
15#include <QSettings>
16#include <QThread>
17#include <QUrl>
18
19using namespace Cutelyst;
20
35
42 : d_ptr(new EnginePrivate)
43{
44 Q_D(Engine);
45
46 connect(
48
49 d->opts = opts;
50 d->workerCore = workerCore;
51 d->app = app;
52}
53
54Engine::~Engine()
55{
56 delete d_ptr;
57}
58
63Application *Engine::app() const
64{
65 Q_D(const Engine);
66 Q_ASSERT(d->app);
67 return d->app;
68}
69
81
90{
91 Q_D(const Engine);
92 return d->workerCore;
93}
94
96{
97 Q_D(Engine);
98
99 if (thread() != QThread::currentThread()) {
100 qCCritical(CUTELYST_ENGINE) << "Cannot init application on a different thread";
101 return false;
102 }
103
104 if (!d->app->setup(this)) {
105 qCCritical(CUTELYST_ENGINE) << "Failed to setup application";
106 return false;
107 }
108
109 return true;
110}
111
113{
114 Q_D(Engine);
115
116 if (!d->app) {
117 qCCritical(CUTELYST_ENGINE) << "Failed to postForkApplication on a null application";
118 return false;
119 }
120
122
123 return d->app->enginePostFork();
124}
125
127{
128 return quint64(QDateTime::currentMSecsSinceEpoch() * 1000);
129}
130
131const char *Engine::httpStatusMessage(quint16 status, int *len)
132{
133 const char *ret;
134 switch (status) {
135 case Response::OK:
136 ret = "HTTP/1.1 200 OK";
137 break;
138 case Response::Found:
139 ret = "HTTP/1.1 302 Found";
140 break;
141 case Response::NotFound:
142 ret = "HTTP/1.1 404 Not Found";
143 break;
144 case Response::InternalServerError:
145 ret = "HTTP/1.1 500 Internal Server Error";
146 break;
147 case Response::MovedPermanently:
148 ret = "HTTP/1.1 301 Moved Permanently";
149 break;
150 case Response::NotModified:
151 ret = "HTTP/1.1 304 Not Modified";
152 break;
153 case Response::SeeOther:
154 ret = "HTTP/1.1 303 See Other";
155 break;
156 case Response::Forbidden:
157 ret = "HTTP/1.1 403 Forbidden";
158 break;
159 case Response::TemporaryRedirect:
160 ret = "HTTP/1.1 307 Temporary Redirect";
161 break;
162 case Response::Unauthorized:
163 ret = "HTTP/1.1 401 Unauthorized";
164 break;
165 case Response::BadRequest:
166 ret = "HTTP/1.1 400 Bad Request";
167 break;
168 case Response::MethodNotAllowed:
169 ret = "HTTP/1.1 405 Method Not Allowed";
170 break;
171 case Response::RequestTimeout:
172 ret = "HTTP/1.1 408 Request Timeout";
173 break;
174 case Response::Continue:
175 ret = "HTTP/1.1 100 Continue";
176 break;
177 case Response::SwitchingProtocols:
178 ret = "HTTP/1.1 101 Switching Protocols";
179 break;
180 case Response::Created:
181 ret = "HTTP/1.1 201 Created";
182 break;
183 case Response::Accepted:
184 ret = "HTTP/1.1 202 Accepted";
185 break;
186 case Response::NonAuthoritativeInformation:
187 ret = "HTTP/1.1 203 Non-Authoritative Information";
188 break;
189 case Response::NoContent:
190 ret = "HTTP/1.1 204 No Content";
191 break;
192 case Response::ResetContent:
193 ret = "HTTP/1.1 205 Reset Content";
194 break;
195 case Response::PartialContent:
196 ret = "HTTP/1.1 206 Partial Content";
197 break;
198 case Response::MultipleChoices:
199 ret = "HTTP/1.1 300 Multiple Choices";
200 break;
201 case Response::UseProxy:
202 ret = "HTTP/1.1 305 Use Proxy";
203 break;
204 case Response::PaymentRequired:
205 ret = "HTTP/1.1 402 Payment Required";
206 break;
207 case Response::NotAcceptable:
208 ret = "HTTP/1.1 406 Not Acceptable";
209 break;
210 case Response::ProxyAuthenticationRequired:
211 ret = "HTTP/1.1 407 Proxy Authentication Required";
212 break;
213 case Response::Conflict:
214 ret = "HTTP/1.1 409 Conflict";
215 break;
216 case Response::Gone:
217 ret = "HTTP/1.1 410 Gone";
218 break;
219 case Response::LengthRequired:
220 ret = "HTTP/1.1 411 Length Required";
221 break;
222 case Response::PreconditionFailed:
223 ret = "HTTP/1.1 412 Precondition Failed";
224 break;
225 case Response::RequestEntityTooLarge:
226 ret = "HTTP/1.1 413 Request Entity Too Large";
227 break;
228 case Response::RequestURITooLong:
229 ret = "HTTP/1.1 414 Request-URI Too Long";
230 break;
231 case Response::UnsupportedMediaType:
232 ret = "HTTP/1.1 415 Unsupported Media Type";
233 break;
234 case Response::RequestedRangeNotSatisfiable:
235 ret = "HTTP/1.1 416 Requested Range Not Satisfiable";
236 break;
237 case Response::ExpectationFailed:
238 ret = "HTTP/1.1 417 Expectation Failed";
239 break;
240 case Response::NotImplemented:
241 ret = "HTTP/1.1 501 Not Implemented";
242 break;
243 case Response::BadGateway:
244 ret = "HTTP/1.1 502 Bad Gateway";
245 break;
246 case Response::ServiceUnavailable:
247 ret = "HTTP/1.1 503 Service Unavailable";
248 break;
249 case Response::MultiStatus:
250 ret = "HTTP/1.1 207 Multi-Status";
251 break;
252 case Response::GatewayTimeout:
253 ret = "HTTP/1.1 504 Gateway Timeout";
254 break;
255 case Response::HTTPVersionNotSupported:
256 ret = "HTTP/1.1 505 HTTP Version Not Supported";
257 break;
258 case Response::BandwidthLimitExceeded:
259 ret = "HTTP/1.1 509 Bandwidth Limit Exceeded";
260 break;
261 default:
262 ret = "HTTP/1.1 000 Unknown Status";
263 break;
264 }
265
266 if (len) {
267 *len = int(strlen(ret));
268 }
269 return ret;
270}
271
273{
274 Q_D(Engine);
275 return d->app->defaultHeaders();
276}
277
279{
280 Q_D(Engine);
281 d->app->handleRequest(request);
282}
283
284QVariantMap Engine::opts() const
285{
286 Q_D(const Engine);
287 return d->opts;
288}
289
290QVariantMap Engine::config(const QString &entity) const
291{
292 Q_D(const Engine);
293 return d->config.value(entity).toMap();
294}
295
296void Engine::setConfig(const QVariantMap &config)
297{
298 Q_D(Engine);
299 d->config = config;
300}
301
302QVariantMap Engine::loadIniConfig(const QString &filename)
303{
304 QVariantMap ret;
305 QSettings settings(filename, QSettings::IniFormat);
306 if (settings.status() != QSettings::NoError) {
307 qCWarning(CUTELYST_ENGINE) << "Failed to load INI file:" << settings.status();
308 return ret;
309 }
310
311 const auto groups = settings.childGroups();
312 for (const QString &group : groups) {
313 QVariantMap configGroup;
314 settings.beginGroup(group);
315 const auto child = settings.childKeys();
316 for (const QString &key : child) {
317 configGroup.insert(key, settings.value(key));
318 }
319 settings.endGroup();
320 ret.insert(group, configGroup);
321 }
322
323 return ret;
324}
325
326QVariantMap Engine::loadJsonConfig(const QString &filename)
327{
328 QVariantMap ret;
329 QFile file(filename);
330 if (!file.open(QIODevice::ReadOnly)) {
331 return ret;
332 }
334
335 ret = doc.toVariant().toMap();
336
337 return ret;
338}
339
340#include "moc_engine.cpp"
The Cutelyst Application.
Definition application.h:43
static QVariantMap loadJsonConfig(const QString &filename)
Definition engine.cpp:326
Engine(Application *app, int workerCore, const QVariantMap &opts)
Definition engine.cpp:41
bool initApplication()
initApplication
Definition engine.cpp:95
int workerCore() const
Each worker process migth have a number of worker cores (threads), a single process with two worker t...
Definition engine.cpp:89
bool postForkApplication()
postForkApplication
Definition engine.cpp:112
void setConfig(const QVariantMap &config)
Definition engine.cpp:296
void processRequestAsync(Cutelyst::EngineRequest *request)
static const char * httpStatusMessage(quint16 status, int *len=nullptr)
Definition engine.cpp:131
void processRequest(EngineRequest *request)
Definition engine.cpp:278
QVariantMap opts() const
Definition engine.cpp:284
QVariantMap config(const QString &entity) const
user configuration for the application
Definition engine.cpp:290
Application * app() const
application
Definition engine.cpp:63
virtual quint64 time()
Definition engine.cpp:126
Headers & defaultHeaders()
Definition engine.cpp:272
static QVariantMap loadIniConfig(const QString &filename)
Definition engine.cpp:302
The Cutelyst namespace holds all public Cutelyst API.
Definition Mainpage.dox:8
qint64 currentMSecsSinceEpoch()
virtual bool open(OpenMode mode) override
QByteArray readAll()
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
QVariant toVariant() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void setObjectName(const QString &name)
QThread * thread() const const
void beginGroup(const QString &prefix)
QStringList childGroups() const const
QStringList childKeys() const const
void endGroup()
Status status() const const
QVariant value(const QString &key, const QVariant &defaultValue) const const
QString number(int n, int base)
QueuedConnection
QThread * currentThread()
QMap< QString, QVariant > toMap() const const