File indexing completed on 2025-01-26 04:57:21
0001 /* 0002 SPDX-FileCopyrightText: 2016-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "backoffmodemanager.h" 0008 #include "checkphishingurlutil.h" 0009 #include "webengineviewer_debug.h" 0010 0011 #include <KConfig> 0012 #include <KConfigGroup> 0013 0014 #include <QTimer> 0015 0016 using namespace WebEngineViewer; 0017 0018 Q_GLOBAL_STATIC(BackOffModeManager, s_backOffModeManager) 0019 0020 class WebEngineViewer::BackOffModeManagerPrivate 0021 { 0022 public: 0023 BackOffModeManagerPrivate(BackOffModeManager *qq) 0024 : q(qq) 0025 , mTimer(new QTimer(q)) 0026 { 0027 mTimer->setSingleShot(true); 0028 q->connect(mTimer, &QTimer::timeout, q, &BackOffModeManager::slotTimerFinished); 0029 load(); 0030 } 0031 0032 void save(); 0033 void load(); 0034 [[nodiscard]] int calculateBackModeTime() const; 0035 void startOffMode(); 0036 void exitBackOffMode(); 0037 void updateTimer(int seconds); 0038 void slotTimerFinished(); 0039 0040 BackOffModeManager *const q; 0041 QTimer *const mTimer; 0042 int mNumberOfHttpFailed = 0; 0043 bool isInOffMode = false; 0044 }; 0045 0046 void BackOffModeManagerPrivate::save() 0047 { 0048 KConfig phishingurlKConfig(WebEngineViewer::CheckPhishingUrlUtil::configFileName()); 0049 KConfigGroup grp = phishingurlKConfig.group(QStringLiteral("BackOffMode")); 0050 grp.writeEntry("Enabled", isInOffMode); 0051 if (isInOffMode) { 0052 const int calculateTimeInSeconds = calculateBackModeTime(); 0053 const qint64 delay = QDateTime::currentDateTime().addSecs(calculateTimeInSeconds).toSecsSinceEpoch(); 0054 grp.writeEntry("Delay", delay); 0055 updateTimer(calculateTimeInSeconds); 0056 } else { 0057 grp.deleteEntry("Delay"); 0058 } 0059 grp.sync(); 0060 } 0061 0062 void BackOffModeManagerPrivate::slotTimerFinished() 0063 { 0064 qCDebug(WEBENGINEVIEWER_LOG) << "Existing from BlackOffMode"; 0065 exitBackOffMode(); 0066 save(); 0067 } 0068 0069 void BackOffModeManagerPrivate::updateTimer(int seconds) 0070 { 0071 if (mTimer->isActive()) { 0072 mTimer->stop(); 0073 } 0074 mTimer->setInterval(seconds * 1000); 0075 mTimer->start(); 0076 } 0077 0078 void BackOffModeManagerPrivate::load() 0079 { 0080 KConfig phishingurlKConfig(WebEngineViewer::CheckPhishingUrlUtil::configFileName()); 0081 KConfigGroup grp = phishingurlKConfig.group(QStringLiteral("BackOffMode")); 0082 isInOffMode = grp.readEntry("Enabled", false); 0083 if (isInOffMode) { 0084 const qint64 delay = grp.readEntry("Delay", 0); 0085 const qint64 now = QDateTime::currentDateTimeUtc().toSecsSinceEpoch(); 0086 if (delay > now) { 0087 const qint64 diff = (delay - now); 0088 updateTimer(diff); 0089 } else { 0090 // Disable mode. 0091 isInOffMode = false; 0092 } 0093 } 0094 } 0095 0096 int BackOffModeManagerPrivate::calculateBackModeTime() const 0097 { 0098 return WebEngineViewer::CheckPhishingUrlUtil::generateRandomSecondValue(mNumberOfHttpFailed); 0099 } 0100 0101 void BackOffModeManagerPrivate::startOffMode() 0102 { 0103 mNumberOfHttpFailed++; 0104 if (isInOffMode) { 0105 qCWarning(WEBENGINEVIEWER_LOG) << "New failed" << mNumberOfHttpFailed; 0106 } else { 0107 qCWarning(WEBENGINEVIEWER_LOG) << "starting back of mode"; 0108 isInOffMode = true; 0109 } 0110 save(); 0111 } 0112 0113 void BackOffModeManagerPrivate::exitBackOffMode() 0114 { 0115 isInOffMode = false; 0116 mNumberOfHttpFailed = 0; 0117 } 0118 0119 BackOffModeManager::BackOffModeManager(QObject *parent) 0120 : QObject(parent) 0121 , d(new BackOffModeManagerPrivate(this)) 0122 { 0123 } 0124 0125 BackOffModeManager::~BackOffModeManager() = default; 0126 0127 BackOffModeManager *BackOffModeManager::self() 0128 { 0129 return s_backOffModeManager; 0130 } 0131 0132 bool BackOffModeManager::isInBackOffMode() const 0133 { 0134 return d->isInOffMode; 0135 } 0136 0137 void BackOffModeManager::startOffMode() 0138 { 0139 d->startOffMode(); 0140 } 0141 0142 int BackOffModeManager::numberOfHttpFailed() const 0143 { 0144 return d->mNumberOfHttpFailed; 0145 } 0146 0147 void BackOffModeManager::slotTimerFinished() 0148 { 0149 d->slotTimerFinished(); 0150 }