cutelyst 5.0.0
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
sessionstorefile.cpp
1/*
2 * SPDX-FileCopyrightText: (C) 2015-2022 Daniel Nicoletti <dantti12@gmail.com>
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5#include "sessionstorefile.h"
6
7#include <Cutelyst/Application>
8#include <Cutelyst/Context>
9
10#include <QCoreApplication>
11#include <QDataStream>
12#include <QDir>
13#include <QFile>
14#include <QLockFile>
15#include <QLoggingCategory>
16
17using namespace Cutelyst;
18using namespace Qt::StringLiterals;
19
20Q_LOGGING_CATEGORY(C_SESSION_FILE, "cutelyst.plugin.sessionfile", QtWarningMsg)
21
22#define SESSION_STORE_FILE_SAVE u"_c_session_store_file_save"_s
23#define SESSION_STORE_FILE_DATA u"_c_session_store_file_data"_s
24
25namespace {
26QVariantHash loadSessionData(Context *c, const QByteArray &sid);
27
28inline QString rootPath()
29{
30 static QString rootPath =
31 QDir::tempPath() + u'/' + QCoreApplication::applicationName() + u"/session/data";
32 return rootPath;
33}
34} // namespace
35
40
44
46 const QByteArray &sid,
47 const QString &key,
48 const QVariant &defaultValue)
49{
50 const QVariantHash data = loadSessionData(c, sid);
51
52 return data.value(key, defaultValue);
53}
54
56 const QByteArray &sid,
57 const QString &key,
58 const QVariant &value)
59{
60 QVariantHash data = loadSessionData(c, sid);
61
62 data.insert(key, value);
63 c->setStash(SESSION_STORE_FILE_DATA, data);
64 c->setStash(SESSION_STORE_FILE_SAVE, true);
65
66 return true;
67}
68
70{
71 QVariantHash data = loadSessionData(c, sid);
72
73 data.remove(key);
74 c->setStash(SESSION_STORE_FILE_DATA, data);
75 c->setStash(SESSION_STORE_FILE_SAVE, true);
76
77 return true;
78}
79
81{
82 Q_UNUSED(c)
83 if (!expires) {
84 QDir dir(rootPath());
86 }
87 return true;
88}
89
90namespace {
91QVariantHash loadSessionData(Context *c, const QByteArray &sid)
92{
93 QVariantHash data;
94 const QVariant sessionVariant = c->stash(SESSION_STORE_FILE_DATA);
95 if (!sessionVariant.isNull()) {
96 data = sessionVariant.toHash();
97 return data;
98 }
99
100 const QString root = rootPath();
101
102 auto file = new QFile(root + u'/' + QString::fromLatin1(sid), c);
103 if (!file->open(QIODevice::ReadWrite)) {
104 if (!QDir().mkpath(root)) {
105 qCWarning(C_SESSION_FILE) << "Failed to create path for session object" << root;
106 return data;
107 }
108
109 if (!file->open(QIODevice::ReadWrite)) {
110 return data;
111 }
112 }
113
114 // Commit data when Context gets deleted
115 QObject::connect(c->app(), &Application::afterDispatch, c, [c, file] {
116 if (!c->stash(SESSION_STORE_FILE_SAVE).toBool()) {
117 return;
118 }
119
120 const QVariantHash data = c->stash(SESSION_STORE_FILE_DATA).toHash();
121
122 if (data.isEmpty()) {
123 QFile::remove(file->fileName());
124 } else {
125 QLockFile lock(file->fileName() + u".lock");
126 if (lock.lock()) {
127 QDataStream in(file);
128
129 if (file->pos()) {
130 file->seek(0);
131 }
132
133 in << data;
134
135 if (file->pos() < file->size()) {
136 file->resize(file->pos());
137 }
138
139 file->flush();
140 lock.unlock();
141 }
142 }
143 });
144
145 // Load data
146 QLockFile lock(file->fileName() + u".lock");
147 if (lock.lock()) {
148 QDataStream in(file);
149 in >> data;
150 lock.unlock();
151 }
152
153 c->setStash(SESSION_STORE_FILE_DATA, data);
154
155 return data;
156}
157} // namespace
158
159#include "moc_sessionstorefile.cpp"
void afterDispatch(Cutelyst::Context *c)
The Cutelyst Context.
Definition context.h:42
void stash(const QVariantHash &unite)
Definition context.cpp:562
void setStash(const QString &key, const QVariant &value)
Definition context.cpp:213
Application * app() const noexcept
Definition context.cpp:92
SessionStoreFile(QObject *parent=nullptr)
virtual bool storeSessionData(Context *c, const QByteArray &sid, const QString &key, const QVariant &value) final
virtual bool deleteSessionData(Context *c, const QByteArray &sid, const QString &key) final
virtual QVariant getSessionData(Context *c, const QByteArray &sid, const QString &key, const QVariant &defaultValue) final
virtual bool deleteExpiredSessions(Context *c, quint64 expires) final
Abstract class to create a session store.
Definition session.h:36
The Cutelyst namespace holds all public Cutelyst API.
bool removeRecursively()
QString tempPath()
bool remove()
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString fromLatin1(QByteArrayView str)
bool isNull() const const
QHash< QString, QVariant > toHash() const const