Cutelyst  1.8.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 
210  bool webSocketHandshake(Context *c, const QString &key, const QString &origin, const QString &protocol);
211 
212  virtual bool webSocketHandshakeDo(Context *c, const QString &key, const QString &origin, const QString &protocol, void *engineData);
213 
214  virtual bool webSocketSendTextMessage(Context *c, const QString &message);
215 
216  virtual bool webSocketSendBinaryMessage(Context *c, const QByteArray &message);
217 
218  virtual bool webSocketSendPing(Context *c, const QByteArray &payload);
219 
220  virtual bool webSocketClose(Context *c, quint16 code, const QString &reason);
221 
225  static inline QString camelCaseHeader(const QString &headerKey) {
226  // The RFC 2616 and 7230 states keys are not case
227  // case sensitive, however several tools fail
228  // if the headers are not on camel case form.
229  QString key = headerKey;
230  bool lastWasLetter = false;
231  for (int i = 0 ; i < key.size() ; ++i) {
232  QCharRef c = key[i];
233  if (c == QLatin1Char('_')) {
234  c = QLatin1Char('-');
235  lastWasLetter = false;
236  } else if (lastWasLetter) {
237  c = c.toLower();
238  } else if (c.isLetter()) {
239  lastWasLetter = true;
240  }
241  }
242  return key;
243  }
244 
248  static inline void camelCaseByteArrayHeader(QByteArray &key) {
249  // The RFC 2616 and 7230 states keys are not case
250  // case sensitive, however several tools fail
251  // if the headers are not on camel case form.
252  bool lastWasLetter = false;
253  for (int i = 0 ; i < key.size() ; ++i) {
254  QByteRef c = key[i];
255  if (c == '_') {
256  c = '-';
257  lastWasLetter = false;
258  } else if (lastWasLetter) {
259  c = QChar::toLower(c);
260  } else if (QChar::isLetter(c)) {
261  lastWasLetter = true;
262  }
263  }
264  }
265 
269  static const char *httpStatusMessage(quint16 status, int *len = nullptr);
270 
274  Headers &defaultHeaders();
275 
283  Context *processRequest2(const EngineRequest &req);
284 
288  Q_DECL_DEPRECATED
289  void processRequest(const EngineRequest &req);
290 
291  Q_DECL_DEPRECATED
295  void processRequest(const QString &method,
296  const QString &path,
297  const QByteArray &query,
298  const QString &protocol,
299  bool https,
300  const QString &serverAddress,
301  const QHostAddress &remoteAddress,
302  quint16 remotePort,
303  const QString &remoteUser,
304  const Headers &headers,
305  quint64 startOfRequest,
306  QIODevice *body,
307  void *requestPtr);
308 
309  EnginePrivate *d_ptr;
310 
311 private:
312  Q_DECLARE_PRIVATE(Engine)
313  friend class Application;
314  friend class Response;
315 
320  virtual bool init() = 0;
321 };
322 
323 inline bool Engine::isZeroWorker() const {
324  return !workerId() && !workerCore();
325 }
326 
327 }
328 
329 #endif // CUTELYST_ENGINE_H
bool isZeroWorker() const
Definition: engine.h:323
static QString camelCaseHeader(const QString &headerKey)
Definition: engine.h:225
The Cutelyst Context.
Definition: context.h:52
static void camelCaseByteArrayHeader(QByteArray &key)
Definition: engine.h:248
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