From 719de7c7616909294f20dd13239e2521dc703db1 Mon Sep 17 00:00:00 2001 From: valentin Bisson Date: Fri, 20 Mar 2020 14:55:55 -0400 Subject: [PATCH 1/3] - fixed cpp-client-qt5 HttpRequestWorker requests crashing on timeout when they have actually NOT timed out (were calling back into a deleted struct). --- .../cpp-qt5-client/HttpRequest.cpp.mustache | 16 +++++++++++----- .../cpp-qt5-client/HttpRequest.h.mustache | 5 +++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/cpp-qt5-client/HttpRequest.cpp.mustache b/modules/openapi-generator/src/main/resources/cpp-qt5-client/HttpRequest.cpp.mustache index 719de8de5b26..89d4d396f2cc 100644 --- a/modules/openapi-generator/src/main/resources/cpp-qt5-client/HttpRequest.cpp.mustache +++ b/modules/openapi-generator/src/main/resources/cpp-qt5-client/HttpRequest.cpp.mustache @@ -45,7 +45,7 @@ void {{prefix}}HttpRequestInput::add_file(QString variable_name, QString local_f } {{prefix}}HttpRequestWorker::{{prefix}}HttpRequestWorker(QObject *parent) - : QObject(parent), manager(nullptr), _timeOut(0) { + : QObject(parent), manager(nullptr), timeOutTimer() { qsrand(QDateTime::currentDateTime().toTime_t()); manager = new QNetworkAccessManager(this); workingDirectory = QDir::currentPath(); @@ -53,6 +53,7 @@ void {{prefix}}HttpRequestInput::add_file(QString variable_name, QString local_f } {{prefix}}HttpRequestWorker::~{{prefix}}HttpRequestWorker() { + QObject::disconnect(&timeOutTimer, nullptr, nullptr, nullptr); for (const auto &item : multiPartFields) { if (item != nullptr) { delete item; @@ -86,8 +87,11 @@ QByteArray *{{prefix}}HttpRequestWorker::getMultiPartField(const QString &fieldn return nullptr; } -void {{prefix}}HttpRequestWorker::setTimeOut(int timeOut) { - _timeOut = timeOut; +void {{prefix}}HttpRequestWorker::setTimeOut(int timeOutMs) { + timeOutTimer.setInterval(timeOutMs); + if(timeOutTimer.interval() == 0) { + QObject::disconnect(&timeOutTimer, nullptr, nullptr, nullptr); + } } void {{prefix}}HttpRequestWorker::setWorkingDirectory(const QString &path) { @@ -347,12 +351,14 @@ void {{prefix}}HttpRequestWorker::execute({{prefix}}HttpRequestInput *input) { buffer->setParent(reply); #endif } - if (_timeOut > 0) { - QTimer::singleShot(_timeOut, [=]() { on_manager_timeout(reply); }); + if (timeOutTimer.interval() > 0) { + timeOutTimer.callOnTimeout([=]() { on_manager_timeout(reply); }); } } void {{prefix}}HttpRequestWorker::on_manager_finished(QNetworkReply *reply) { + if(timeOutTimer.interval() > 0) + QObject::disconnect(&timeOutTimer, nullptr, nullptr, nullptr); error_type = reply->error(); error_str = reply->errorString(); if (reply->rawHeaderPairs().count() > 0) { diff --git a/modules/openapi-generator/src/main/resources/cpp-qt5-client/HttpRequest.h.mustache b/modules/openapi-generator/src/main/resources/cpp-qt5-client/HttpRequest.h.mustache index dea2d3090efc..247f5906841a 100644 --- a/modules/openapi-generator/src/main/resources/cpp-qt5-client/HttpRequest.h.mustache +++ b/modules/openapi-generator/src/main/resources/cpp-qt5-client/HttpRequest.h.mustache @@ -13,6 +13,7 @@ #include #include #include +#include #include "{{prefix}}HttpFileElement.h" @@ -59,7 +60,7 @@ public: QString http_attribute_encode(QString attribute_name, QString input); void execute({{prefix}}HttpRequestInput *input); static QSslConfiguration *sslDefaultConfiguration; - void setTimeOut(int tout); + void setTimeOut(int timeOutMs); void setWorkingDirectory(const QString &path); {{prefix}}HttpFileElement getHttpFileElement(const QString &fieldname = QString()); QByteArray *getMultiPartField(const QString &fieldname = QString()); @@ -78,7 +79,7 @@ private: QMap files; QMap multiPartFields; QString workingDirectory; - int _timeOut; + QTimer timeOutTimer; bool isResponseCompressionEnabled; bool isRequestCompressionEnabled; void on_manager_timeout(QNetworkReply *reply); From 21f7e48c8c20226f8b493b3e6ada3c87949fd3e6 Mon Sep 17 00:00:00 2001 From: valentin Bisson Date: Mon, 23 Mar 2020 10:57:40 -0400 Subject: [PATCH 2/3] #minor fixes after review --- .../cpp-qt5-client/HttpRequest.cpp.mustache | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/cpp-qt5-client/HttpRequest.cpp.mustache b/modules/openapi-generator/src/main/resources/cpp-qt5-client/HttpRequest.cpp.mustache index 89d4d396f2cc..64e8ab094ff8 100644 --- a/modules/openapi-generator/src/main/resources/cpp-qt5-client/HttpRequest.cpp.mustache +++ b/modules/openapi-generator/src/main/resources/cpp-qt5-client/HttpRequest.cpp.mustache @@ -45,15 +45,17 @@ void {{prefix}}HttpRequestInput::add_file(QString variable_name, QString local_f } {{prefix}}HttpRequestWorker::{{prefix}}HttpRequestWorker(QObject *parent) - : QObject(parent), manager(nullptr), timeOutTimer() { + : QObject(parent), manager(nullptr), timeOutTimer(this) { qsrand(QDateTime::currentDateTime().toTime_t()); manager = new QNetworkAccessManager(this); workingDirectory = QDir::currentPath(); connect(manager, &QNetworkAccessManager::finished, this, &{{prefix}}HttpRequestWorker::on_manager_finished); + timeOutTimer.setSingleShot(true); } {{prefix}}HttpRequestWorker::~{{prefix}}HttpRequestWorker() { - QObject::disconnect(&timeOutTimer, nullptr, nullptr, nullptr); + QObject::disconnect(&timeOutTimer, &QTimer::timeout, nullptr, nullptr); + timeOutTimer.stop(); for (const auto &item : multiPartFields) { if (item != nullptr) { delete item; @@ -90,7 +92,7 @@ QByteArray *{{prefix}}HttpRequestWorker::getMultiPartField(const QString &fieldn void {{prefix}}HttpRequestWorker::setTimeOut(int timeOutMs) { timeOutTimer.setInterval(timeOutMs); if(timeOutTimer.interval() == 0) { - QObject::disconnect(&timeOutTimer, nullptr, nullptr, nullptr); + QObject::disconnect(&timeOutTimer, &QTimer::timeout, nullptr, nullptr); } } @@ -352,13 +354,16 @@ void {{prefix}}HttpRequestWorker::execute({{prefix}}HttpRequestInput *input) { #endif } if (timeOutTimer.interval() > 0) { - timeOutTimer.callOnTimeout([=]() { on_manager_timeout(reply); }); + QObject::connect(&timeOutTimer, &QTimer::timeout, [=]() { on_manager_timeout(reply); }); + timeOutTimer.start(); } } void {{prefix}}HttpRequestWorker::on_manager_finished(QNetworkReply *reply) { - if(timeOutTimer.interval() > 0) - QObject::disconnect(&timeOutTimer, nullptr, nullptr, nullptr); + if(timeOutTimer.isActive()) { + QObject::disconnect(&timeOutTimer, &QTimer::timeout, nullptr, nullptr); + timeOutTimer.stop(); + } error_type = reply->error(); error_str = reply->errorString(); if (reply->rawHeaderPairs().count() > 0) { From 40617d6ee96706c191b0923e6d8f802adbf911fa Mon Sep 17 00:00:00 2001 From: etherealjoy Date: Tue, 24 Mar 2020 13:26:56 +0100 Subject: [PATCH 3/3] Regenerate changed files --- .../cpp-qt5/client/PFXHttpRequest.cpp | 21 ++++++++++++++----- .../petstore/cpp-qt5/client/PFXHttpRequest.h | 5 +++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/samples/client/petstore/cpp-qt5/client/PFXHttpRequest.cpp b/samples/client/petstore/cpp-qt5/client/PFXHttpRequest.cpp index 091e075291db..78355e007aad 100644 --- a/samples/client/petstore/cpp-qt5/client/PFXHttpRequest.cpp +++ b/samples/client/petstore/cpp-qt5/client/PFXHttpRequest.cpp @@ -52,14 +52,17 @@ void PFXHttpRequestInput::add_file(QString variable_name, QString local_filename } PFXHttpRequestWorker::PFXHttpRequestWorker(QObject *parent) - : QObject(parent), manager(nullptr), _timeOut(0) { + : QObject(parent), manager(nullptr), timeOutTimer(this) { qsrand(QDateTime::currentDateTime().toTime_t()); manager = new QNetworkAccessManager(this); workingDirectory = QDir::currentPath(); connect(manager, &QNetworkAccessManager::finished, this, &PFXHttpRequestWorker::on_manager_finished); + timeOutTimer.setSingleShot(true); } PFXHttpRequestWorker::~PFXHttpRequestWorker() { + QObject::disconnect(&timeOutTimer, &QTimer::timeout, nullptr, nullptr); + timeOutTimer.stop(); for (const auto &item : multiPartFields) { if (item != nullptr) { delete item; @@ -93,8 +96,11 @@ QByteArray *PFXHttpRequestWorker::getMultiPartField(const QString &fieldname) { return nullptr; } -void PFXHttpRequestWorker::setTimeOut(int timeOut) { - _timeOut = timeOut; +void PFXHttpRequestWorker::setTimeOut(int timeOutMs) { + timeOutTimer.setInterval(timeOutMs); + if(timeOutTimer.interval() == 0) { + QObject::disconnect(&timeOutTimer, &QTimer::timeout, nullptr, nullptr); + } } void PFXHttpRequestWorker::setWorkingDirectory(const QString &path) { @@ -354,12 +360,17 @@ void PFXHttpRequestWorker::execute(PFXHttpRequestInput *input) { buffer->setParent(reply); #endif } - if (_timeOut > 0) { - QTimer::singleShot(_timeOut, [=]() { on_manager_timeout(reply); }); + if (timeOutTimer.interval() > 0) { + QObject::connect(&timeOutTimer, &QTimer::timeout, [=]() { on_manager_timeout(reply); }); + timeOutTimer.start(); } } void PFXHttpRequestWorker::on_manager_finished(QNetworkReply *reply) { + if(timeOutTimer.isActive()) { + QObject::disconnect(&timeOutTimer, &QTimer::timeout, nullptr, nullptr); + timeOutTimer.stop(); + } error_type = reply->error(); error_str = reply->errorString(); if (reply->rawHeaderPairs().count() > 0) { diff --git a/samples/client/petstore/cpp-qt5/client/PFXHttpRequest.h b/samples/client/petstore/cpp-qt5/client/PFXHttpRequest.h index 9f9aeee72fd9..acbb0a8d01ad 100644 --- a/samples/client/petstore/cpp-qt5/client/PFXHttpRequest.h +++ b/samples/client/petstore/cpp-qt5/client/PFXHttpRequest.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "PFXHttpFileElement.h" @@ -67,7 +68,7 @@ class PFXHttpRequestWorker : public QObject { QString http_attribute_encode(QString attribute_name, QString input); void execute(PFXHttpRequestInput *input); static QSslConfiguration *sslDefaultConfiguration; - void setTimeOut(int tout); + void setTimeOut(int timeOutMs); void setWorkingDirectory(const QString &path); PFXHttpFileElement getHttpFileElement(const QString &fieldname = QString()); QByteArray *getMultiPartField(const QString &fieldname = QString()); @@ -86,7 +87,7 @@ class PFXHttpRequestWorker : public QObject { QMap files; QMap multiPartFields; QString workingDirectory; - int _timeOut; + QTimer timeOutTimer; bool isResponseCompressionEnabled; bool isRequestCompressionEnabled; void on_manager_timeout(QNetworkReply *reply);