diff options
| author | Mehmet Samet Duman <yongdohyun@projecttick.org> | 2026-04-02 18:45:07 +0300 |
|---|---|---|
| committer | Mehmet Samet Duman <yongdohyun@projecttick.org> | 2026-04-02 18:45:07 +0300 |
| commit | 31b9a8949ed0a288143e23bf739f2eb64fdc63be (patch) | |
| tree | 8a984fa143c38fccad461a77792d6864f3e82cd3 /meshmc/libraries/katabasis/src/PollServer.cpp | |
| parent | 934382c8a1ce738589dee9ee0f14e1cec812770e (diff) | |
| parent | fad6a1066616b69d7f5fef01178efdf014c59537 (diff) | |
| download | Project-Tick-31b9a8949ed0a288143e23bf739f2eb64fdc63be.tar.gz Project-Tick-31b9a8949ed0a288143e23bf739f2eb64fdc63be.zip | |
Add 'meshmc/' from commit 'fad6a1066616b69d7f5fef01178efdf014c59537'
git-subtree-dir: meshmc
git-subtree-mainline: 934382c8a1ce738589dee9ee0f14e1cec812770e
git-subtree-split: fad6a1066616b69d7f5fef01178efdf014c59537
Diffstat (limited to 'meshmc/libraries/katabasis/src/PollServer.cpp')
| -rw-r--r-- | meshmc/libraries/katabasis/src/PollServer.cpp | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/meshmc/libraries/katabasis/src/PollServer.cpp b/meshmc/libraries/katabasis/src/PollServer.cpp new file mode 100644 index 0000000000..1c8556aa98 --- /dev/null +++ b/meshmc/libraries/katabasis/src/PollServer.cpp @@ -0,0 +1,147 @@ +/* SPDX-FileCopyrightText: 2026 Project Tick + * SPDX-FileContributor: Project Tick + * SPDX-License-Identifier: GPL-3.0-or-later + * + * MeshMC - A Custom Launcher for Minecraft + * Copyright (C) 2026 Project Tick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <QNetworkAccessManager> +#include <QNetworkReply> + +#include "katabasis/PollServer.h" +#include "JsonResponse.h" + +namespace +{ + QMap<QString, QString> toVerificationParams(const QVariantMap& map) + { + QMap<QString, QString> params; + for (QVariantMap::const_iterator i = map.constBegin(); + i != map.constEnd(); ++i) { + params[i.key()] = i.value().toString(); + } + return params; + } +} // namespace + +namespace Katabasis +{ + + PollServer::PollServer(QNetworkAccessManager* manager, + const QNetworkRequest& request, + const QByteArray& payload, int expiresIn, + QObject* parent) + : QObject(parent), manager_(manager), request_(request), + payload_(payload), expiresIn_(expiresIn) + { + expirationTimer.setTimerType(Qt::VeryCoarseTimer); + expirationTimer.setInterval(expiresIn * 1000); + expirationTimer.setSingleShot(true); + connect(&expirationTimer, SIGNAL(timeout()), this, + SLOT(onExpiration())); + expirationTimer.start(); + + pollTimer.setTimerType(Qt::VeryCoarseTimer); + pollTimer.setInterval(5 * 1000); + pollTimer.setSingleShot(true); + connect(&pollTimer, SIGNAL(timeout()), this, SLOT(onPollTimeout())); + } + + int PollServer::interval() const + { + return pollTimer.interval() / 1000; + } + + void PollServer::setInterval(int interval) + { + pollTimer.setInterval(interval * 1000); + } + + void PollServer::startPolling() + { + if (expirationTimer.isActive()) { + pollTimer.start(); + } + } + + void PollServer::onPollTimeout() + { + qDebug() << "PollServer::onPollTimeout: retrying"; + QNetworkReply* reply = manager_->post(request_, payload_); + connect(reply, SIGNAL(finished()), this, SLOT(onReplyFinished())); + } + + void PollServer::onExpiration() + { + pollTimer.stop(); + emit serverClosed(false); + } + + void PollServer::onReplyFinished() + { + QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender()); + + if (!reply) { + qDebug() << "PollServer::onReplyFinished: reply is null"; + return; + } + + QByteArray replyData = reply->readAll(); + QMap<QString, QString> params = + toVerificationParams(parseJsonResponse(replyData)); + + // Dump replyData + // SENSITIVE DATA in RelWithDebInfo or Debug builds + // qDebug() << "PollServer::onReplyFinished: replyData\n"; + // qDebug() << QString( replyData ); + + if (reply->error() == QNetworkReply::TimeoutError) { + // rfc8628#section-3.2 + // "On encountering a connection timeout, clients MUST unilaterally + // reduce their polling frequency before retrying. The use of an + // exponential backoff algorithm to achieve this, such as doubling + // the polling interval on each such connection timeout, is + // RECOMMENDED." + setInterval(interval() * 2); + pollTimer.start(); + } else { + QString error = params.value("error"); + if (error == "slow_down") { + // rfc8628#section-3.2 + // "A variant of 'authorization_pending', the authorization + // request is still pending and polling should continue, but the + // interval MUST be increased by 5 seconds for this and all + // subsequent requests." + setInterval(interval() + 5); + pollTimer.start(); + } else if (error == "authorization_pending") { + // keep trying - rfc8628#section-3.2 + // "The authorization request is still pending as the end user + // hasn't yet completed the user-interaction steps + // (Section 3.3)." + pollTimer.start(); + } else { + expirationTimer.stop(); + emit serverClosed(true); + // let O2 handle the other cases + emit verificationReceived(params); + } + } + reply->deleteLater(); + } + +} // namespace Katabasis |
