cutelyst  4.4.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 
19 using namespace Cutelyst;
20 
42 Engine::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 
67 int Engine::workerCore() const
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 
104 const 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 = "HTTP/1.1 000 Unknown Status";
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 
257 QVariantMap Engine::opts() const
258 {
259  Q_D(const Engine);
260  return d->opts;
261 }
262 
263 QVariantMap Engine::config(const QString &entity) const
264 {
265  Q_D(const Engine);
266  return d->config.value(entity).toMap();
267 }
268 
269 void Engine::setConfig(const QVariantMap &config)
270 {
271  Q_D(Engine);
272  d->config = config;
273 }
274 
275 QVariantMap 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 
299 QVariantMap 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.
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