From 77d5d8bdeab4cadd902fda803b3ec518d59d2610 Mon Sep 17 00:00:00 2001 From: Jim Broadus Date: Wed, 25 Dec 2019 22:59:57 -0800 Subject: [PATCH 1/2] Add a timeout option to NetworkAccessManager. In most cases, timeouts can be applied to a reply after a request has been made. But some APIs, such as libmygpo-qt, don't always provide access to the reply or provide abort methods. For these cases, add an optional timeout to NetworkAccessManager. If set, create a NetworkTimeouts instance in createRequest and add the reply. Use the reply as the parent so that it is destroyed when the reply is destroyed. --- src/core/network.cpp | 17 +++++++++++++++-- src/core/network.h | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/core/network.cpp b/src/core/network.cpp index 78f5f4b36..a2f79c00a 100644 --- a/src/core/network.cpp +++ b/src/core/network.cpp @@ -84,7 +84,12 @@ void ThreadSafeNetworkDiskCache::clear() { } NetworkAccessManager::NetworkAccessManager(QObject* parent) - : QNetworkAccessManager(parent) { + : QNetworkAccessManager(parent), timeout_msec_(0) { + setCache(new ThreadSafeNetworkDiskCache(this)); +} + +NetworkAccessManager::NetworkAccessManager(int timeout, QObject* parent) + : QNetworkAccessManager(parent), timeout_msec_(timeout) { setCache(new ThreadSafeNetworkDiskCache(this)); } @@ -117,7 +122,15 @@ QNetworkReply* NetworkAccessManager::createRequest( QNetworkRequest::PreferCache); } - return QNetworkAccessManager::createRequest(op, new_request, outgoingData); + QNetworkReply* reply = + QNetworkAccessManager::createRequest(op, new_request, outgoingData); + if (timeout_msec_ > 0) { + // Since the parent is the reply, this object will be destroyed when the + // reply is destroyed. + NetworkTimeouts* timeout = new NetworkTimeouts(timeout_msec_, reply); + timeout->AddReply(reply); + } + return reply; } NetworkTimeouts::NetworkTimeouts(int timeout_msec, QObject* parent) diff --git a/src/core/network.h b/src/core/network.h index faad6ba88..ecc69fc86 100644 --- a/src/core/network.h +++ b/src/core/network.h @@ -51,10 +51,12 @@ class NetworkAccessManager : public QNetworkAccessManager { public: explicit NetworkAccessManager(QObject* parent = nullptr); + explicit NetworkAccessManager(int timeout, QObject* parent = nullptr); protected: QNetworkReply* createRequest(Operation op, const QNetworkRequest& request, QIODevice* outgoingData); + int timeout_msec_; }; class RedirectFollower : public QObject { From 5e7e57df7366b89d4c0bb4650d369e806ac474c8 Mon Sep 17 00:00:00 2001 From: Jim Broadus Date: Wed, 25 Dec 2019 23:01:08 -0800 Subject: [PATCH 2/2] Set a 30 second timeout for gpodder requests. --- src/internet/podcasts/gpoddersync.cpp | 3 ++- src/internet/podcasts/gpoddersync.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/internet/podcasts/gpoddersync.cpp b/src/internet/podcasts/gpoddersync.cpp index 6e54d41cb..81aac6031 100644 --- a/src/internet/podcasts/gpoddersync.cpp +++ b/src/internet/podcasts/gpoddersync.cpp @@ -38,11 +38,12 @@ const char* GPodderSync::kSettingsGroup = "Podcasts"; const int GPodderSync::kFlushUpdateQueueDelay = 30 * kMsecPerSec; // 30 seconds const int GPodderSync::kGetUpdatesInterval = 30 * 60 * kMsecPerSec; // 30 minutes +const int GPodderSync::kRequestTimeout = 30 * kMsecPerSec; // 30 seconds GPodderSync::GPodderSync(Application* app, QObject* parent) : QObject(parent), app_(app), - network_(new NetworkAccessManager(this)), + network_(new NetworkAccessManager(kRequestTimeout, this)), backend_(app_->podcast_backend()), loader_(new PodcastUrlLoader(this)), get_updates_timer_(new QTimer(this)), diff --git a/src/internet/podcasts/gpoddersync.h b/src/internet/podcasts/gpoddersync.h index d8613243b..49b1b9cbd 100644 --- a/src/internet/podcasts/gpoddersync.h +++ b/src/internet/podcasts/gpoddersync.h @@ -51,6 +51,7 @@ class GPodderSync : public QObject { static const char* kSettingsGroup; static const int kFlushUpdateQueueDelay; static const int kGetUpdatesInterval; + static const int kRequestTimeout; static QString DefaultDeviceName(); static QString DeviceId();