cutelyst 4.3.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;
18
19Q_LOGGING_CATEGORY(C_SESSION_FILE, "cutelyst.plugin.sessionfile", QtWarningMsg)
20
21#define SESSION_STORE_FILE_SAVE QStringLiteral("_c_session_store_file_save")
22#define SESSION_STORE_FILE_DATA QStringLiteral("_c_session_store_file_data")
23
24static QVariantHash loadSessionData(Context *c, const QByteArray &sid);
25
30
34
36 const QByteArray &sid,
37 const QString &key,
38 const QVariant &defaultValue)
39{
40 const QVariantHash data = loadSessionData(c, sid);
41
42 return data.value(key, defaultValue);
43}
44
46 const QByteArray &sid,
47 const QString &key,
48 const QVariant &value)
49{
50 QVariantHash data = loadSessionData(c, sid);
51
52 data.insert(key, value);
53 c->setStash(SESSION_STORE_FILE_DATA, data);
54 c->setStash(SESSION_STORE_FILE_SAVE, true);
55
56 return true;
57}
58
60{
61 QVariantHash data = loadSessionData(c, sid);
62
63 data.remove(key);
64 c->setStash(SESSION_STORE_FILE_DATA, data);
65 c->setStash(SESSION_STORE_FILE_SAVE, true);
66
67 return true;
68}
69
70static QString rootPath()
71{
72 static QString rootPath =
73 QDir::tempPath() + u'/' + QCoreApplication::applicationName() + u"/session/data";
74 return rootPath;
75}
76
78{
79 Q_UNUSED(c)
80 if (!expires) {
81 QDir dir(rootPath());
83 }
84 return true;
85}
86
87QVariantHash loadSessionData(Context *c, const QByteArray &sid)
88{
89 QVariantHash data;
90 const QVariant sessionVariant = c->stash(SESSION_STORE_FILE_DATA);
91 if (!sessionVariant.isNull()) {
92 data = sessionVariant.toHash();
93 return data;
94 }
95
96 const QString root = rootPath();
97
98 auto file = new QFile(root + u'/' + QString::fromLatin1(sid), c);
99 if (!file->open(QIODevice::ReadWrite)) {
100 if (!QDir().mkpath(root)) {
101 qCWarning(C_SESSION_FILE) << "Failed to create path for session object" << root;
102 return data;
103 }
104
105 if (!file->open(QIODevice::ReadWrite)) {
106 return data;
107 }
108 }
109
110 // Commit data when Context gets deleted
111 QObject::connect(c->app(), &Application::afterDispatch, c, [c, file] {
112 if (!c->stash(SESSION_STORE_FILE_SAVE).toBool()) {
113 return;
114 }
115
116 const QVariantHash data = c->stash(SESSION_STORE_FILE_DATA).toHash();
117
118 if (data.isEmpty()) {
119 QFile::remove(file->fileName());
120 } else {
121 QLockFile lock(file->fileName() + QLatin1String(".lock"));
122 if (lock.lock()) {
123 QDataStream in(file);
124
125 if (file->pos()) {
126 file->seek(0);
127 }
128
129 in << data;
130
131 if (file->pos() < file->size()) {
132 file->resize(file->pos());
133 }
134
135 file->flush();
136 lock.unlock();
137 }
138 }
139 });
140
141 // Load data
142 QLockFile lock(file->fileName() + QLatin1String(".lock"));
143 if (lock.lock()) {
144 QDataStream in(file);
145 in >> data;
146 lock.unlock();
147 }
148
149 c->setStash(SESSION_STORE_FILE_DATA, data);
150
151 return data;
152}
153
154#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:212
Application * app() const noexcept
Definition context.cpp:91
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