Fix a crash when a delayed reply would call a callback for an object that disappeared
parent
4e11026ea4
commit
0eadb8dcd3
|
|
@ -8,6 +8,7 @@
|
|||
#include <QSettings>
|
||||
#include <QUuid>
|
||||
#include <QTimer>
|
||||
#include <QPointer>
|
||||
|
||||
#include "sigv4utils.h"
|
||||
|
||||
|
|
@ -820,7 +821,7 @@ void AWSClient::getCredentialsForIdentity(const QString &identityId)
|
|||
if (qc.method == "fetchDevices") {
|
||||
fetchDevices();
|
||||
} else if (qc.method == "postToMQTT") {
|
||||
postToMQTT(qc.arg1, qc.arg2, qc.callback);
|
||||
postToMQTT(qc.arg1, qc.arg2, qc.sender, qc.callback);
|
||||
} else if (qc.method == "deleteAccount") {
|
||||
deleteAccount();
|
||||
} else if (qc.method == "registerPushNotificationEndpoint") {
|
||||
|
|
@ -837,7 +838,7 @@ bool AWSClient::tokensExpired() const
|
|||
return (m_accessTokenExpiry.addSecs(-10) < QDateTime::currentDateTime()) || (m_sessionTokenExpiry.addSecs(-10) < QDateTime::currentDateTime());
|
||||
}
|
||||
|
||||
bool AWSClient::postToMQTT(const QString &boxId, const QString ×tamp, std::function<void(bool)> callback)
|
||||
bool AWSClient::postToMQTT(const QString &boxId, const QString ×tamp, QObject* sender, std::function<void (bool)> callback)
|
||||
{
|
||||
if (!isLoggedIn()) {
|
||||
qWarning() << "Cannot post to MQTT. Not logged in to AWS";
|
||||
|
|
@ -846,11 +847,13 @@ bool AWSClient::postToMQTT(const QString &boxId, const QString ×tamp, std::
|
|||
if (tokensExpired()) {
|
||||
qDebug() << "Cannot post to MQTT. Need to refresh the tokens first";
|
||||
refreshAccessToken();
|
||||
QueuedCall::enqueue(m_callQueue, QueuedCall("postToMQTT", boxId, timestamp, callback));
|
||||
QueuedCall::enqueue(m_callQueue, QueuedCall("postToMQTT", boxId, timestamp, sender, callback));
|
||||
return true; // So far it looks we're doing ok... let's return true
|
||||
}
|
||||
QString topic = QString("%1/%2/proxy").arg(boxId).arg(QString(m_identityId));
|
||||
|
||||
QPointer<QObject> senderWatcher = QPointer<QObject>(sender);
|
||||
|
||||
// This is somehow broken in AWS...
|
||||
// The Signature needs to be created with having the topic percentage-encoded twice
|
||||
// while the actual request needs to go out with it only being encoded once.
|
||||
|
|
@ -882,15 +885,21 @@ bool AWSClient::postToMQTT(const QString &boxId, const QString ×tamp, std::
|
|||
// }
|
||||
// qDebug() << "Payload:" << payload;
|
||||
QNetworkReply *reply = m_nam->post(request, payload);
|
||||
QTimer::singleShot(5000, reply, [reply, callback](){
|
||||
QTimer::singleShot(5000, reply, [reply, senderWatcher, callback](){
|
||||
reply->deleteLater();
|
||||
qWarning() << "Timeout posting to MQTT";
|
||||
callback(false);
|
||||
if (senderWatcher) {
|
||||
callback(false);
|
||||
}
|
||||
});
|
||||
connect(reply, &QNetworkReply::finished, this, [reply, callback]() {
|
||||
connect(reply, &QNetworkReply::finished, this, [reply, senderWatcher, callback]() {
|
||||
reply->deleteLater();
|
||||
QByteArray data = reply->readAll();
|
||||
// qDebug() << "MQTT post reply" << data;
|
||||
if (senderWatcher.isNull()) {
|
||||
qDebug() << "Request object disappeared. Discarding MQTT reply...";
|
||||
return;
|
||||
}
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qWarning() << "MQTT Network reply error" << reply->error() << reply->errorString();
|
||||
callback(false);
|
||||
|
|
@ -909,7 +918,6 @@ bool AWSClient::postToMQTT(const QString &boxId, const QString ×tamp, std::
|
|||
return;
|
||||
}
|
||||
callback(true);
|
||||
|
||||
});
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <QNetworkRequest>
|
||||
#include <QDate>
|
||||
#include <QAbstractListModel>
|
||||
#include <QPointer>
|
||||
|
||||
class QNetworkAccessManager;
|
||||
|
||||
|
|
@ -117,7 +118,7 @@ public:
|
|||
|
||||
Q_INVOKABLE void fetchDevices();
|
||||
|
||||
Q_INVOKABLE bool postToMQTT(const QString &boxId, const QString ×tamp, std::function<void(bool)> callback);
|
||||
Q_INVOKABLE bool postToMQTT(const QString &boxId, const QString ×tamp, QObject* sender, std::function<void(bool)> callback);
|
||||
Q_INVOKABLE void getId();
|
||||
|
||||
Q_INVOKABLE void registerPushNotificationEndpoint(const QString ®istrationId, const QString &deviceDisplayName, const QString mobileDeviceId, const QString &mobileDeviceManufacturer, const QString &mobileDeviceModel);
|
||||
|
|
@ -184,13 +185,14 @@ private:
|
|||
QueuedCall(const QString &method): method(method) { }
|
||||
QueuedCall(const QString &method, const QString &arg1): method(method), arg1(arg1) { }
|
||||
QueuedCall(const QString &method, const QString &arg1, const QString &arg2, const QString &arg3, const QString &arg4, const QString &arg5): method(method), arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4), arg5(arg5) { }
|
||||
QueuedCall(const QString &method, const QString &arg1, const QString &arg2, std::function<void(bool)> callback): method(method), arg1(arg1), arg2(arg2), callback(callback) {}
|
||||
QueuedCall(const QString &method, const QString &arg1, const QString &arg2, QObject* sender, std::function<void(bool)> callback): method(method), arg1(arg1), arg2(arg2), sender(sender), callback(callback) {}
|
||||
QString method;
|
||||
QString arg1;
|
||||
QString arg2;
|
||||
QString arg3;
|
||||
QString arg4;
|
||||
QString arg5;
|
||||
QPointer<QObject> sender;
|
||||
std::function<void(bool)> callback;
|
||||
|
||||
static void enqueue(QList<QueuedCall> &queue, const QueuedCall &call) {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <QUrlQuery>
|
||||
#include <QHostInfo>
|
||||
#include <QPointer>
|
||||
|
||||
using namespace remoteproxyclient;
|
||||
|
||||
|
|
@ -52,7 +53,7 @@ bool CloudTransport::connect(const QUrl &url)
|
|||
m_url = url;
|
||||
|
||||
m_timestamp = QDateTime::currentDateTime();
|
||||
bool postResult = m_awsClient->postToMQTT(url.host(), QString::number(m_timestamp.toMSecsSinceEpoch()), [this](bool success) {
|
||||
bool postResult = m_awsClient->postToMQTT(url.host(), QString::number(m_timestamp.toMSecsSinceEpoch()), QPointer<QObject>(this), [this](bool success) {
|
||||
if (success) {
|
||||
qDebug() << "MQTT Post done. Connecting to remote proxy";
|
||||
m_remoteproxyConnection->connectServer(QUrl("wss://remoteproxy.nymea.io"));
|
||||
|
|
|
|||
Loading…
Reference in New Issue