cutelyst 4.3.0
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
42Engine::Engine(Cutelyst::Application *app, int workerCore, const QVariantMap &opts)
43 : d_ptr(new EnginePrivate)
44{
45 Q_D(Engine);
46
47 connect(
49
50 d->opts = opts;
51 d->workerCore = workerCore;
52 d->app = app;
53}
54
56{
57 delete d_ptr;
58}
59
61{
62 Q_D(const Engine);
63 Q_ASSERT(d->app);
64 return d->app;
65}
66
68{
69 Q_D(const Engine);
70 return d->workerCore;
71}
72
74{
75 Q_D(Engine);
76
77 if (thread() != QThread::currentThread()) {
78 qCCritical(CUTELYST_ENGINE) << "Cannot init application on a different thread";
79 return false;
80 }
81
82 if (!d->app->setup(this)) {
83 qCCritical(CUTELYST_ENGINE) << "Failed to setup application";
84 return false;
85 }
86
87 return true;
88}
89
91{
92 Q_D(Engine);
93
94 if (!d->app) {
95 qCCritical(CUTELYST_ENGINE) << "Failed to postForkApplication on a null application";
96 return false;
97 }
98
100
101 return d->app->enginePostFork();
102}
103
104const char *Engine::httpStatusMessage(quint16 status, int *len)
105{
106 const char *ret;
107 switch (status) {
108 case Response::OK:
109 ret = "HTTP/1.1 200 OK";
110 break;
111 case Response::Found:
112 ret = "HTTP/1.1 302 Found";
113 break;
114 case Response::NotFound:
115 ret = "HTTP/1.1 404 Not Found";
116 break;
117 case Response::InternalServerError:
118 ret = "HTTP/1.1 500 Internal Server Error";
119 break;
120 case Response::MovedPermanently:
121 ret = "HTTP/1.1 301 Moved Permanently";
122 break;
123 case Response::NotModified:
124 ret = "HTTP/1.1 304 Not Modified";
125 break;
126 case Response::SeeOther:
127 ret = "HTTP/1.1 303 See Other";
128 break;
129 case Response::Forbidden:
130 ret = "HTTP/1.1 403 Forbidden";
131 break;
132 case Response::TemporaryRedirect:
133 ret = "HTTP/1.1 307 Temporary Redirect";
134 break;
135 case Response::Unauthorized:
136 ret = "HTTP/1.1 401 Unauthorized";
137 break;
138 case Response::BadRequest:
139 ret = "HTTP/1.1 400 Bad Request";
140 break;
141 case Response::MethodNotAllowed:
142 ret = "HTTP/1.1 405 Method Not Allowed";
143 break;
144 case Response::RequestTimeout:
145 ret = "HTTP/1.1 408 Request Timeout";
146 break;
147 case Response::Continue:
148 ret = "HTTP/1.1 100 Continue";
149 break;
150 case Response::SwitchingProtocols:
151 ret = "HTTP/1.1 101 Switching Protocols";
152 break;
153 case Response::Created:
154 ret = "HTTP/1.1 201 Created";
155 break;
156 case Response::Accepted:
157 ret = "HTTP/1.1 202 Accepted";
158 break;
159 case Response::NonAuthoritativeInformation:
160 ret = "HTTP/1.1 203 Non-Authoritative Information";
161 break;
162 case Response::NoContent:
163 ret = "HTTP/1.1 204 No Content";
164 break;
165 case Response::ResetContent:
166 ret = "HTTP/1.1 205 Reset Content";
167 break;
168 case Response::PartialContent:
169 ret = "HTTP/1.1 206 Partial Content";
170 break;
171 case Response::MultipleChoices:
172 ret = "HTTP/1.1 300 Multiple Choices";
173 break;
174 case Response::UseProxy:
175 ret = "HTTP/1.1 305 Use Proxy";
176 break;
177 case Response::PaymentRequired:
178 ret = "HTTP/1.1 402 Payment Required";
179 break;
180 case Response::NotAcceptable:
181 ret = "HTTP/1.1 406 Not Acceptable";
182 break;
183 case Response::ProxyAuthenticationRequired:
184 ret = "HTTP/1.1 407 Proxy Authentication Required";
185 break;
186 case Response::Conflict:
187 ret = "HTTP/1.1 409 Conflict";
188 break;
189 case Response::Gone:
190 ret = "HTTP/1.1 410 Gone";
191 break;
192 case Response::LengthRequired:
193 ret = "HTTP/1.1 411 Length Required";
194 break;
195 case Response::PreconditionFailed:
196 ret = "HTTP/1.1 412 Precondition Failed";
197 break;
198 case Response::RequestEntityTooLarge:
199 ret = "HTTP/1.1 413 Request Entity Too Large";
200 break;
201 case Response::RequestURITooLong:
202 ret = "HTTP/1.1 414 Request-URI Too Long";
203 break;
204 case Response::UnsupportedMediaType:
205 ret = "HTTP/1.1 415 Unsupported Media Type";
206 break;
207 case Response::RequestedRangeNotSatisfiable:
208 ret = "HTTP/1.1 416 Requested Range Not Satisfiable";
209 break;
210 case Response::ExpectationFailed:
211 ret = "HTTP/1.1 417 Expectation Failed";
212 break;
213 case Response::NotImplemented:
214 ret = "HTTP/1.1 501 Not Implemented";
215 break;
216 case Response::BadGateway:
217 ret = "HTTP/1.1 502 Bad Gateway";
218 break;
219 case Response::ServiceUnavailable:
220 ret = "HTTP/1.1 503 Service Unavailable";
221 break;
222 case Response::MultiStatus:
223 ret = "HTTP/1.1 207 Multi-Status";
224 break;
225 case Response::GatewayTimeout:
226 ret = "HTTP/1.1 504 Gateway Timeout";
227 break;
228 case Response::HTTPVersionNotSupported:
229 ret = "HTTP/1.1 505 HTTP Version Not Supported";
230 break;
231 case Response::BandwidthLimitExceeded:
232 ret = "HTTP/1.1 509 Bandwidth Limit Exceeded";
233 break;
234 default:
235 ret = QByteArrayLiteral("HTTP/1.1 ").append(QByteArray::number(status)).constData();
236 break;
237 }
238
239 if (len) {
240 *len = int(strlen(ret));
241 }
242 return ret;
243}
244
246{
247 Q_D(Engine);
248 return d->app->defaultHeaders();
249}
250
252{
253 Q_D(Engine);
254 d->app->handleRequest(request);
255}
256
257QVariantMap Engine::opts() const
258{
259 Q_D(const Engine);
260 return d->opts;
261}
262
263QVariantMap Engine::config(const QString &entity) const
264{
265 Q_D(const Engine);
266 return d->config.value(entity).toMap();
267}
268
269void Engine::setConfig(const QVariantMap &config)
270{
271 Q_D(Engine);
272 d->config = config;
273}
274
275QVariantMap Engine::loadIniConfig(const QString &filename)
276{
277 QVariantMap ret;
278 QSettings settings(filename, QSettings::IniFormat);
279 if (settings.status() != QSettings::NoError) {
280 qCWarning(CUTELYST_ENGINE) << "Failed to load INI file:" << settings.status();
281 return ret;
282 }
283
284 const auto groups = settings.childGroups();
285 for (const QString &group : groups) {
286 QVariantMap configGroup;
287 settings.beginGroup(group);
288 const auto child = settings.childKeys();
289 for (const QString &key : child) {
290 configGroup.insert(key, settings.value(key));
291 }
292 settings.endGroup();
293 ret.insert(group, configGroup);
294 }
295
296 return ret;
297}
298
299QVariantMap Engine::loadJsonConfig(const QString &filename)
300{
301 QVariantMap ret;
302 QFile file(filename);
304 return ret;
305 }
307
308 ret = doc.toVariant().toMap();
309
310 return ret;
311}
312
313#include "moc_engine.cpp"
The Cutelyst application.
Definition application.h:66
The Cutelyst Engine.
Definition engine.h:20
static QVariantMap loadJsonConfig(const QString &filename)
Definition engine.cpp:299
Engine(Application *app, int workerCore, const QVariantMap &opts)
Definition engine.cpp:42
bool initApplication()
Definition engine.cpp:73
int workerCore() const
Definition engine.cpp:67
bool postForkApplication()
Definition engine.cpp:90
void setConfig(const QVariantMap &config)
Definition engine.cpp:269
virtual ~Engine()
Definition engine.cpp:55
void processRequestAsync(Cutelyst::EngineRequest *request)
static const char * httpStatusMessage(quint16 status, int *len=nullptr)
Definition engine.cpp:104
void processRequest(EngineRequest *request)
Definition engine.cpp:251
QVariantMap opts() const
Definition engine.cpp:257
QVariantMap config(const QString &entity) const
Definition engine.cpp:263
Application * app() const
Definition engine.cpp:60
Headers & defaultHeaders()
Definition engine.cpp:245
static QVariantMap loadIniConfig(const QString &filename)
Definition engine.cpp:275
Container for HTTP headers.
Definition headers.h:24
The Cutelyst namespace holds all public Cutelyst API.
QByteArray number(double n, char format, int precision)
bool open(FILE *fh, QIODeviceBase::OpenMode mode, QFileDevice::FileHandleFlags handleFlags)
QByteArray readAll()
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
QVariant toVariant() const const
QList::iterator insert(QList::const_iterator before, QList::parameter_type value)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void setObjectName(QAnyStringView name)
QThread * thread() const const
void beginGroup(QAnyStringView prefix)
QStringList childGroups() const const
QStringList childKeys() const const
void endGroup()
QSettings::Status status() const const
QVariant value(QAnyStringView key) const const
QString number(double n, char format, int precision)
QueuedConnection
QThread * currentThread()
QMap< QString, QVariant > toMap() const const