Cutelyst  1.6.0
engine.h
1 /*
2  * Copyright (C) 2013-2017 Daniel Nicoletti <dantti12@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB. If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 #ifndef CUTELYST_ENGINE_H
21 #define CUTELYST_ENGINE_H
22 
23 #include <QObject>
24 #include <QHostAddress>
25 
26 #include <Cutelyst/cutelyst_global.h>
27 #include <Cutelyst/Headers>
28 
29 namespace Cutelyst {
30 
31 struct EngineRequest {
33  QString method;
35  QString path;
37  QByteArray query;
39  QString protocol;
42  QString serverAddress;
44  QHostAddress remoteAddress;
46  QString remoteUser;
50  quint64 startOfRequest;
52  QIODevice *body;
54  void *requestPtr;
56  quint16 remotePort;
58  bool isSecure;
59 };
60 
61 class Application;
62 class Context;
63 class EnginePrivate;
64 class CUTELYST_LIBRARY Engine : public QObject
65 {
66  Q_OBJECT
67 public:
73  explicit Engine(Application *app, int workerCore, const QVariantMap &opts);
74  virtual ~Engine();
75 
79  Application *app() const;
80 
85  virtual int workerId() const = 0;
86 
90  int workerCore() const;
91 
99  inline bool isZeroWorker() const;
100 
104  QVariantMap opts() const;
105 
111  QVariantMap config(const QString &entity) const;
112 
116  void setConfig(const QVariantMap &config);
117 
121  static QVariantMap loadIniConfig(const QString &filename);
122 
126  static QVariantMap loadJsonConfig(const QString &filename);
127 
133  virtual quint64 time();
134 
135 protected:
145  bool initApplication();
146 
159  bool postForkApplication();
160 
164  qint64 write(Context *c, const char *data, qint64 len, void *engineData);
165 
169  virtual qint64 doWrite(Context *c, const char *data, qint64 len, void *engineData) = 0;
170 
176  virtual void finalizeCookies(Context *c);
177 
183  virtual bool finalizeHeaders(Context *c);
184 
188  virtual bool finalizeHeadersWrite(Context *c, quint16 status, const Headers &headers, void *engineData) = 0;
189 
194  virtual void finalizeBody(Context *c);
195 
202  virtual void finalizeError(Context *c);
203 
208  void finalize(Context *c);
209 
213  static inline QString camelCaseHeader(const QString &headerKey) {
214  // The RFC 2616 and 7230 states keys are not case
215  // case sensitive, however several tools fail
216  // if the headers are not on camel case form.
217  QString key = headerKey;
218  bool lastWasLetter = false;
219  for (int i = 0 ; i < key.size() ; ++i) {
220  QCharRef c = key[i];
221  if (c == QLatin1Char('_')) {
222  c = QLatin1Char('-');
223  lastWasLetter = false;
224  } else if (lastWasLetter) {
225  c = c.toLower();
226  } else if (c.isLetter()) {
227  lastWasLetter = true;
228  }
229  }
230  return key;
231  }
232 
236  static inline void camelCaseByteArrayHeader(QByteArray &key) {
237  // The RFC 2616 and 7230 states keys are not case
238  // case sensitive, however several tools fail
239  // if the headers are not on camel case form.
240  bool lastWasLetter = false;
241  for (int i = 0 ; i < key.size() ; ++i) {
242  QByteRef c = key[i];
243  if (c == '_') {
244  c = '-';
245  lastWasLetter = false;
246  } else if (lastWasLetter) {
247  c = QChar::toLower(c);
248  } else if (QChar::isLetter(c)) {
249  lastWasLetter = true;
250  }
251  }
252  }
253 
257  static const char *httpStatusMessage(quint16 status, int *len = nullptr);
258 
262  Headers &defaultHeaders();
263 
267  void processRequest(const EngineRequest &req);
268 
269  Q_DECL_DEPRECATED
273  void processRequest(const QString &method,
274  const QString &path,
275  const QByteArray &query,
276  const QString &protocol,
277  bool https,
278  const QString &serverAddress,
279  const QHostAddress &remoteAddress,
280  quint16 remotePort,
281  const QString &remoteUser,
282  const Headers &headers,
283  quint64 startOfRequest,
284  QIODevice *body,
285  void *requestPtr);
286 
287  EnginePrivate *d_ptr;
288 
289 private:
290  Q_DECLARE_PRIVATE(Engine)
291  friend class Application;
292  friend class Response;
293 
298  virtual bool init() = 0;
299 };
300 
301 inline bool Engine::isZeroWorker() const {
302  return !workerId() && !workerCore();
303 }
304 
305 }
306 
307 #endif // CUTELYST_ENGINE_H
bool isZeroWorker() const
Definition: engine.h:301
static QString camelCaseHeader(const QString &headerKey)
Definition: engine.h:213
The Cutelyst Context.
Definition: context.h:52
static void camelCaseByteArrayHeader(QByteArray &key)
Definition: engine.h:236
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:7
QIODevice * body
Definition: engine.h:52
QHostAddress remoteAddress
Definition: engine.h:44
QString serverAddress
Definition: engine.h:42
The Cutelyst Application.
Definition: application.h:56
QByteArray query
Definition: engine.h:37
quint64 startOfRequest
Definition: engine.h:50