Cutelyst  3.5.0
statusmessage.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2016-2022 Daniel Nicoletti <dantti12@gmail.com>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 #include "statusmessage.h"
6 
7 #include <Cutelyst/Application>
8 #include <Cutelyst/Plugins/Session/session.h>
9 
10 #include <QtCore/QDateTime>
11 #include <QtCore/QLoggingCategory>
12 
13 #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
14 #include <QRandomGenerator>
15 #endif
16 
17 using namespace Cutelyst;
18 
19 Q_LOGGING_CATEGORY(C_STATUSMESSAGE, "cutelyst.plugins.statusmessage", QtWarningMsg)
20 
21 static thread_local StatusMessage *m_instance = nullptr;
22 
23 namespace Cutelyst {
24 
26 {
27 public:
28  static void _q_postFork(Application *app);
29 
30  QString sessionPrefix = QStringLiteral("status_msg");
31  QString tokenParam = QStringLiteral("mid");
32  QString statusMsgStashKey = QStringLiteral("status_msg");
33  QString errorMsgStashKey = QStringLiteral("error_msg");
34 };
35 
36 void StatusMessagePrivate::_q_postFork(Application *app)
37 {
38  m_instance = app->plugin<StatusMessage *>();
39 }
40 
41 }
42 
43 StatusMessage::StatusMessage(Application *parent) : Plugin(parent), d_ptr(new StatusMessagePrivate)
44 {
45 #if (QT_VERSION < QT_VERSION_CHECK(5, 10, 0))
47 #endif
48  m_instance = this;
49 }
50 
51 StatusMessage::~StatusMessage()
52 {
53  delete d_ptr;
54 }
55 
57 {
58  Q_D(const StatusMessage);
59  return d->sessionPrefix;
60 }
61 
62 void StatusMessage::setSessionPrefix(const QString &sessionPrefix)
63 {
64  Q_D(StatusMessage);
65  d->sessionPrefix = sessionPrefix;
66 }
67 
69 {
70  Q_D(const StatusMessage);
71  return d->tokenParam;
72 }
73 
74 void StatusMessage::setTokenParam(const QString &tokenParam)
75 {
76  Q_D(StatusMessage);
77  d->tokenParam = tokenParam;
78 }
79 
81 {
82  Q_D(const StatusMessage);
83  return d->statusMsgStashKey;
84 }
85 
86 void StatusMessage::setStatusMsgStashKey(const QString &statusMsgStashKey)
87 {
88  Q_D(StatusMessage);
89  d->statusMsgStashKey = statusMsgStashKey;
90 }
91 
93 {
94  Q_D(const StatusMessage);
95  return d->errorMsgStashKey;
96 }
97 
98 void StatusMessage::setErrorMgStashKey(const QString &errorMgStashKey)
99 {
100  Q_D(StatusMessage);
101  d->errorMsgStashKey = errorMgStashKey;
102 }
103 
105 {
106  if (Q_UNLIKELY(!m_instance)) {
107  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
108  return;
109  }
110  StatusMessagePrivate *priv = m_instance->d_ptr;
111 
112  const QString token = c->request()->queryParam(priv->tokenParam);
113  if (token.isEmpty()) {
114  return;
115  }
116 
117  QStringList deleteKeys;
118  const QString statusKey = priv->sessionPrefix + QLatin1String("status") + token;
119  const QVariant statusValue = Session::value(c, statusKey);
120  if (!statusValue.isNull()) {
121  deleteKeys.append(statusKey);
122  c->setStash(priv->statusMsgStashKey, statusValue);
123  }
124 
125  const QString errorKey = priv->sessionPrefix + QLatin1String("error") + token;
126  const QVariant errorValue = Session::value(c, errorKey);
127  if (!errorValue.isNull()) {
128  deleteKeys.append(errorKey);
129  c->setStash(priv->errorMsgStashKey, errorValue);
130  }
131 
132  if (!deleteKeys.isEmpty()) {
133  Session::deleteValues(c, deleteKeys);
134  }
135 }
136 
137 inline QString createToken()
138 {
139 #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
140  return QString::number(QRandomGenerator::global()->generate() % 99999999).rightJustified(8, QLatin1Char('0'), true);
141 #else
142  return QString::number(qrand() % 99999999).rightJustified(8, QLatin1Char('0'), true);
143 #endif
144 }
145 
147 {
148  QString token;
149  if (Q_UNLIKELY(!m_instance)) {
150  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
151  return token;
152  }
153 
154  token = createToken();
155  Session::setValue(c, m_instance->d_ptr->sessionPrefix + QLatin1String("error") + token, msg);
156  return token;
157 }
158 
160 {
161  ParamsMultiMap map(query);
162  if (Q_UNLIKELY(!m_instance)) {
163  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
164  return map;
165  }
166  StatusMessagePrivate *priv = m_instance->d_ptr;
167 
168  const QString token = createToken();
169  Session::setValue(c, priv->sessionPrefix + QLatin1String("error") + token, msg);
170  map.insert(priv->tokenParam, token);
171  return map;
172 }
173 
175 {
176  QString token;
177  if (Q_UNLIKELY(!m_instance)) {
178  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
179  return token;
180  }
181 
182  token = createToken();
183  Session::setValue(c, m_instance->d_ptr->sessionPrefix + QLatin1String("status") + token, msg);
184  return token;
185 }
186 
188 {
189  ParamsMultiMap map(query);
190  if (Q_UNLIKELY(!m_instance)) {
191  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
192  return map;
193  }
194  StatusMessagePrivate *priv = m_instance->d_ptr;
195 
196  const QString token = createToken();
197  Session::setValue(c, priv->sessionPrefix + QLatin1String("status") + token, msg);
198  map.insert(priv->tokenParam, token);
199  return map;
200 }
201 
203 {
204  connect(app, &Application::postForked, this, &StatusMessagePrivate::_q_postFork);
205  return true;
206 }
207 
208 #include "moc_statusmessage.cpp"
void setTokenParam(const QString &tokenParam)
static QString status(Context *c, const QString &msg)
void postForked(Cutelyst::Application *app)
QString sessionPrefix() const
void setStash(const QString &key, const QVariant &value)
Definition: context.cpp:212
T plugin()
Returns the registered plugin that casts to the template type T.
Definition: application.h:102
QString queryParam(const QString &key, const QString &defaultValue={}) const
Definition: request.h:542
static ParamsMultiMap statusQuery(Context *c, const QString &msg, ParamsMultiMap query=ParamsMultiMap())
static void load(Context *c)
qint64 currentMSecsSinceEpoch()
The Cutelyst Context.
Definition: context.h:38
QString number(int n, int base)
void append(const T &value)
QString tokenParam() const
bool isNull() const const
QString rightJustified(int width, QChar fill, bool truncate) const const
bool isEmpty() const const
bool isEmpty() const const
static void setValue(Context *c, const QString &key, const QVariant &value)
Definition: session.cpp:165
typename QMap< Key, T >::iterator insert(const Key &key, const T &value)
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:7
void setStatusMsgStashKey(const QString &statusMsgStashKey)
virtual bool setup(Application *app) override
QString errorMgStashKey() const
static void deleteValues(Context *c, const QStringList &keys)
Definition: session.cpp:211
QString statusMsgStashKey() const
static QVariant value(Context *c, const QString &key, const QVariant &defaultValue=QVariant())
Definition: session.cpp:150
The Cutelyst Application.
Definition: application.h:42
static ParamsMultiMap errorQuery(Context *c, const QString &msg, ParamsMultiMap query=ParamsMultiMap())
static QString error(Context *c, const QString &msg)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void setErrorMgStashKey(const QString &errorMgStashKey)
QRandomGenerator * global()
void setSessionPrefix(const QString &sessionPrefix)