diff --git a/src/librssguard-gmail/src/gmailnetworkfactory.h b/src/librssguard-gmail/src/gmailnetworkfactory.h index 4ae5a62a5..ba846cd27 100644 --- a/src/librssguard-gmail/src/gmailnetworkfactory.h +++ b/src/librssguard-gmail/src/gmailnetworkfactory.h @@ -16,7 +16,6 @@ class RootItem; class GmailServiceRoot; class OAuth2Service; -class Downloader; class GmailNetworkFactory : public QObject { Q_OBJECT diff --git a/src/librssguard-reddit/src/redditnetworkfactory.h b/src/librssguard-reddit/src/redditnetworkfactory.h index 3f02755ae..4acb4c65f 100644 --- a/src/librssguard-reddit/src/redditnetworkfactory.h +++ b/src/librssguard-reddit/src/redditnetworkfactory.h @@ -14,7 +14,6 @@ class RootItem; class RedditServiceRoot; class OAuth2Service; -class Downloader; struct Subreddit {}; diff --git a/src/librssguard-standard/src/gui/formstandardfeeddetails.cpp b/src/librssguard-standard/src/gui/formstandardfeeddetails.cpp index 8b26ab152..ae1d37167 100644 --- a/src/librssguard-standard/src/gui/formstandardfeeddetails.cpp +++ b/src/librssguard-standard/src/gui/formstandardfeeddetails.cpp @@ -137,6 +137,12 @@ void FormStandardFeedDetails::apply() { std_feed->setDontUseRawXmlSaving(m_standardFeedExpDetails->m_ui.m_cbDontUseRawXml->isChecked()); } + if (isChangeAllowed(m_standardFeedExpDetails->m_ui.m_mcbEnableHttp2)) { + std_feed->setHttp2Status(static_cast(m_standardFeedExpDetails->m_ui.m_cmbEnableHttp2 + ->currentData() + .toInt())); + } + std_feed->setCreationDate(QDateTime::currentDateTime()); std_feed->setLastEtag({}); @@ -192,6 +198,8 @@ void FormStandardFeedDetails::loadFeedData() { m_standardFeedExpDetails->m_ui.m_mcbDontUseRawXml ->addActionWidget(m_standardFeedExpDetails->m_ui.m_cbDontUseRawXml); + m_standardFeedExpDetails->m_ui.m_mcbEnableHttp2->addActionWidget(m_standardFeedExpDetails->m_ui.m_lblEnableHttp2); + m_standardFeedExpDetails->m_ui.m_mcbEnableHttp2->addActionWidget(m_standardFeedExpDetails->m_ui.m_cmbEnableHttp2); } else { // We hide batch selectors. @@ -220,5 +228,7 @@ void FormStandardFeedDetails::loadFeedData() { m_standardFeedDetails->setExistingFeed(std_feed); m_standardFeedExpDetails->m_ui.m_cbDontUseRawXml->setChecked(std_feed->dontUseRawXmlSaving()); + m_standardFeedExpDetails->m_ui.m_cmbEnableHttp2 + ->setCurrentIndex(m_standardFeedExpDetails->m_ui.m_cmbEnableHttp2->findData(int(std_feed->http2Status()))); } } diff --git a/src/librssguard-standard/src/gui/standardfeedexpdetails.cpp b/src/librssguard-standard/src/gui/standardfeedexpdetails.cpp index ee61c4283..be74c9648 100644 --- a/src/librssguard-standard/src/gui/standardfeedexpdetails.cpp +++ b/src/librssguard-standard/src/gui/standardfeedexpdetails.cpp @@ -28,4 +28,9 @@ StandardFeedExpDetails::StandardFeedExpDetails(QWidget* parent) : QWidget(parent "This setting is useful when raw XML parsing of the feed is very slow, this " "happens for feed which do have very long contents."), false); + + m_ui.m_cmbEnableHttp2->addItem(tr("Use application settings"), + QVariant::fromValue(int(NetworkFactory::Http2Status::DontSet))); + m_ui.m_cmbEnableHttp2->addItem(tr("Enabled"), QVariant::fromValue(int(NetworkFactory::Http2Status::Enabled))); + m_ui.m_cmbEnableHttp2->addItem(tr("Disabled"), QVariant::fromValue(int(NetworkFactory::Http2Status::Disabled))); } diff --git a/src/librssguard-standard/src/gui/standardfeedexpdetails.ui b/src/librssguard-standard/src/gui/standardfeedexpdetails.ui index 38e5fc57d..f7c0456ff 100644 --- a/src/librssguard-standard/src/gui/standardfeedexpdetails.ui +++ b/src/librssguard-standard/src/gui/standardfeedexpdetails.ui @@ -14,18 +14,53 @@ Form - - - - - - - Use older mechanism for extracting raw XML data - - + + - + + + + + + + + Use older mechanism for extracting raw XML data + + + + + + + + + + + + + + + + + 0 + 0 + + + + + + + + Enable HTTP/2 + + + m_cmbEnableHttp2 + + + + + + @@ -42,6 +77,12 @@ 1 + + m_mcbEnableHttp2 + m_cmbEnableHttp2 + m_mcbDontUseRawXml + m_cbDontUseRawXml + diff --git a/src/librssguard-standard/src/standardfeed.cpp b/src/librssguard-standard/src/standardfeed.cpp index 37d8778d6..33125f18a 100644 --- a/src/librssguard-standard/src/standardfeed.cpp +++ b/src/librssguard-standard/src/standardfeed.cpp @@ -54,6 +54,7 @@ StandardFeed::StandardFeed(RootItem* parent_item) : Feed(parent_item) { m_password = QString(); m_httpHeaders = {}; m_dontUseRawXmlSaving = false; + m_http2Status = NetworkFactory::Http2Status::DontSet; } StandardFeed::StandardFeed(const StandardFeed& other) : Feed(other) { @@ -66,6 +67,7 @@ StandardFeed::StandardFeed(const StandardFeed& other) : Feed(other) { m_password = other.password(); m_dontUseRawXmlSaving = other.dontUseRawXmlSaving(); m_httpHeaders = other.httpHeaders(); + m_http2Status = other.http2Status(); } QList StandardFeed::contextMenuFeedsList() { @@ -88,7 +90,7 @@ QString StandardFeed::additionalTooltip() const { .toStdList(); QStringList fltrs = FROM_STD_LIST(QStringList, std_fltrs); - // TODO: toto je v podstatÄ› zkopirovane z Feed... + // TODO: Basically copied from base implementation. QString base_tooltip = tr("Auto-update status: %1\n" "Active message filters: %2\n" @@ -113,6 +115,14 @@ QString StandardFeed::additionalTooltip() const { !dontUseRawXmlSaving() ? tr("yes") : tr("no")); } +NetworkFactory::Http2Status StandardFeed::http2Status() const { + return m_http2Status; +} + +void StandardFeed::setHttp2Status(NetworkFactory::Http2Status status) { + m_http2Status = status; +} + bool StandardFeed::canBeDeleted() const { return true; } @@ -167,6 +177,7 @@ QVariantHash StandardFeed::customDatabaseData() const { data[QSL("password")] = TextFactory::encrypt(password()); data[QSL("dont_use_raw_xml_saving")] = dontUseRawXmlSaving(); data[QSL("http_headers")] = httpHeaders(); + data[QSL("http2_status")] = int(http2Status()); return data; } @@ -181,6 +192,7 @@ void StandardFeed::setCustomDatabaseData(const QVariantHash& data) { setPassword(TextFactory::decrypt(data[QSL("password")].toString())); setDontUseRawXmlSaving(data[QSL("dont_use_raw_xml_saving")].toBool()); setHttpHeaders(data[QSL("http_headers")].toHash()); + setHttp2Status(NetworkFactory::Http2Status(data[QSL("http2_status")].toInt())); } QString StandardFeed::typeToString(StandardFeed::Type type) { diff --git a/src/librssguard-standard/src/standardfeed.h b/src/librssguard-standard/src/standardfeed.h index e9260b5ec..9a9f5275b 100644 --- a/src/librssguard-standard/src/standardfeed.h +++ b/src/librssguard-standard/src/standardfeed.h @@ -74,6 +74,9 @@ class StandardFeed : public Feed { QString password() const; void setPassword(const QString& password); + NetworkFactory::Http2Status http2Status() const; + void setHttp2Status(NetworkFactory::Http2Status status); + // Tries to guess feed hidden under given URL // and uses given credentials. // Returns pointer to guessed feed (if at least partially @@ -140,6 +143,7 @@ class StandardFeed : public Feed { QString m_lastEtag; bool m_dontUseRawXmlSaving; QVariantHash m_httpHeaders; + NetworkFactory::Http2Status m_http2Status; }; Q_DECLARE_METATYPE(StandardFeed::SourceType) diff --git a/src/librssguard-standard/src/standardserviceroot.cpp b/src/librssguard-standard/src/standardserviceroot.cpp index 0f804932f..55a54cbb5 100644 --- a/src/librssguard-standard/src/standardserviceroot.cpp +++ b/src/librssguard-standard/src/standardserviceroot.cpp @@ -220,7 +220,7 @@ QList StandardServiceRoot::obtainNewMessages(Feed* feed, qDebugNN << "Using ETag value:" << QUOTE_W_SPACE_DOT(f->lastEtag()); } - auto network_result = NetworkFactory::performNetworkOperation(feed->source(), + auto network_result = NetworkFactory::performNetworkOperation(f->source(), download_timeout, {}, feed_contents, @@ -229,7 +229,8 @@ QList StandardServiceRoot::obtainNewMessages(Feed* feed, false, {}, {}, - networkProxy()); + networkProxy(), + f->http2Status()); if (network_result.m_networkError != QNetworkReply::NetworkError::NoError) { qWarningNN << LOGSEC_CORE << "Error" << QUOTE_W_SPACE(network_result.m_networkError) diff --git a/src/librssguard/network-web/basenetworkaccessmanager.cpp b/src/librssguard/network-web/basenetworkaccessmanager.cpp index 9e61b3ab9..cca6f16f8 100644 --- a/src/librssguard/network-web/basenetworkaccessmanager.cpp +++ b/src/librssguard/network-web/basenetworkaccessmanager.cpp @@ -21,6 +21,22 @@ BaseNetworkAccessManager::BaseNetworkAccessManager(QObject* parent) loadSettings(); } +void BaseNetworkAccessManager::setSpecificHtpp2Status(NetworkFactory::Http2Status status) { + switch (status) { + case NetworkFactory::Http2Status::DontSet: + m_enableHttp2 = qApp->settings()->value(GROUP(Network), SETTING(Network::EnableHttp2)).toBool(); + break; + + case NetworkFactory::Http2Status::Enabled: + m_enableHttp2 = true; + break; + + case NetworkFactory::Http2Status::Disabled: + m_enableHttp2 = false; + break; + } +} + void BaseNetworkAccessManager::loadSettings() { const QNetworkProxy::ProxyType selected_proxy_type = static_cast(qApp->settings()->value(GROUP(Proxy), SETTING(Proxy::Type)).toInt()); @@ -66,6 +82,14 @@ QNetworkReply* BaseNetworkAccessManager::createRequest(QNetworkAccessManager::Op #if QT_VERSION >= 0x050F00 // Qt >= 5.15.0 new_request.setAttribute(QNetworkRequest::Attribute::Http2AllowedAttribute, m_enableHttp2); + + if (m_enableHttp2) { + qDebugNN << LOGSEC_NETWORK << "Enabling HTTP/2 for this network request."; + } +#endif + +#if QT_VERSION >= 0x060300 // Qt >= 6.3.0 + new_request.setAttribute(QNetworkRequest::Attribute::Http2CleartextAllowedAttribute, m_enableHttp2); #endif // new_request.setMaximumRedirectsAllowed(0); diff --git a/src/librssguard/network-web/basenetworkaccessmanager.h b/src/librssguard/network-web/basenetworkaccessmanager.h index 7b9fddb41..c4e881df6 100644 --- a/src/librssguard/network-web/basenetworkaccessmanager.h +++ b/src/librssguard/network-web/basenetworkaccessmanager.h @@ -3,6 +3,8 @@ #ifndef BASENETWORKACCESSMANAGER_H #define BASENETWORKACCESSMANAGER_H +#include "network-web/networkfactory.h" + #include // This is base class for all network access managers. @@ -12,6 +14,8 @@ class BaseNetworkAccessManager : public QNetworkAccessManager { public: explicit BaseNetworkAccessManager(QObject* parent = nullptr); + void setSpecificHtpp2Status(NetworkFactory::Http2Status status); + public slots: void loadSettings(); diff --git a/src/librssguard/network-web/downloader.cpp b/src/librssguard/network-web/downloader.cpp index 35eda45fc..463d990e3 100644 --- a/src/librssguard/network-web/downloader.cpp +++ b/src/librssguard/network-web/downloader.cpp @@ -443,6 +443,10 @@ QUrl Downloader::lastUrl() const { return m_lastUrl; } +void Downloader::setHttp2Status(NetworkFactory::Http2Status status) { + m_downloadManager->setSpecificHtpp2Status(status); +} + QMap Downloader::lastHeaders() const { return m_lastHeaders; } diff --git a/src/librssguard/network-web/downloader.h b/src/librssguard/network-web/downloader.h index 7b109a2dc..62fa99bfb 100644 --- a/src/librssguard/network-web/downloader.h +++ b/src/librssguard/network-web/downloader.h @@ -7,6 +7,7 @@ #include "network-web/gemini/geminiclient.h" #include "network-web/gemini/geminiparser.h" #include "network-web/httpresponse.h" +#include "network-web/networkfactory.h" #include #include @@ -34,6 +35,7 @@ class Downloader : public QObject { QMap lastHeaders() const; QUrl lastUrl() const; + void setHttp2Status(NetworkFactory::Http2Status status); void setProxy(const QNetworkProxy& proxy); public slots: diff --git a/src/librssguard/network-web/networkfactory.cpp b/src/librssguard/network-web/networkfactory.cpp index 02ee8b102..1a4b73e7b 100644 --- a/src/librssguard/network-web/networkfactory.cpp +++ b/src/librssguard/network-web/networkfactory.cpp @@ -167,7 +167,8 @@ QNetworkReply::NetworkError NetworkFactory::downloadIcon(const QList>& additional_headers, - const QNetworkProxy& custom_proxy) { + const QNetworkProxy& custom_proxy, + Http2Status http2_status) { QNetworkReply::NetworkError network_result = QNetworkReply::NetworkError::UnknownNetworkError; for (const auto& url : urls) { @@ -271,7 +272,8 @@ NetworkResult NetworkFactory::performNetworkOperation(const QString& url, bool protected_contents, const QString& username, const QString& password, - const QNetworkProxy& custom_proxy) { + const QNetworkProxy& custom_proxy, + Http2Status http2_status) { Downloader downloader; QEventLoop loop; NetworkResult result; @@ -289,6 +291,7 @@ NetworkResult NetworkFactory::performNetworkOperation(const QString& url, downloader.setProxy(custom_proxy); } + downloader.setHttp2Status(http2_status); downloader.manipulateData(url, operation, input_data, timeout, protected_contents, username, password); loop.exec(); @@ -301,7 +304,7 @@ NetworkResult NetworkFactory::performNetworkOperation(const QString& url, result.m_headers = downloader.lastHeaders(); result.m_url = downloader.lastUrl(); - qDebugNN << LOGSEC_NETWORK << "URLS\n" << url << "\n" << result.m_url.toString(); + qDebugNN << LOGSEC_NETWORK << "URLS\nRequest: " << url << "\nResponse: " << result.m_url.toString(); return result; } @@ -315,7 +318,8 @@ NetworkResult NetworkFactory::performNetworkOperation(const QString& url, bool protected_contents, const QString& username, const QString& password, - const QNetworkProxy& custom_proxy) { + const QNetworkProxy& custom_proxy, + Http2Status http2_status) { Downloader downloader; QEventLoop loop; NetworkResult result; @@ -333,6 +337,7 @@ NetworkResult NetworkFactory::performNetworkOperation(const QString& url, downloader.setProxy(custom_proxy); } + downloader.setHttp2Status(http2_status); downloader.manipulateData(url, operation, input_data, timeout, protected_contents, username, password); loop.exec(); @@ -345,7 +350,7 @@ NetworkResult NetworkFactory::performNetworkOperation(const QString& url, result.m_headers = downloader.lastHeaders(); result.m_url = downloader.lastUrl(); - qDebugNN << LOGSEC_NETWORK << "URLS\n" << url << "\n" << result.m_url.toString(); + qDebugNN << LOGSEC_NETWORK << "URLS\nRequest: " << url << "\nResponse: " << result.m_url.toString(); return result; } diff --git a/src/librssguard/network-web/networkfactory.h b/src/librssguard/network-web/networkfactory.h index 1706a0815..f3d0566ea 100644 --- a/src/librssguard/network-web/networkfactory.h +++ b/src/librssguard/network-web/networkfactory.h @@ -5,7 +5,6 @@ #include "definitions/typedefs.h" #include "network-web/httpresponse.h" -#include "services/abstract/feed.h" #include #include @@ -30,8 +29,6 @@ struct RSSGUARD_DLLSPEC NetworkResult { const QList& cook); }; -class Downloader; - class RSSGUARD_DLLSPEC NetworkFactory { Q_DECLARE_TR_FUNCTIONS(NetworkFactory) @@ -45,6 +42,12 @@ class RSSGUARD_DLLSPEC NetworkFactory { Token = 2 }; + enum class Http2Status { + DontSet = 0, // Use application-wide setting. + Enabled = 1, + Disabled = 2 + }; + static QStringList extractFeedLinksFromHtmlPage(const QUrl& url, const QString& html); static QPair generateBasicAuthHeader(NetworkAuthentication protection, const QString& username, @@ -61,7 +64,8 @@ class RSSGUARD_DLLSPEC NetworkFactory { QPixmap& output, const QList>& additional_headers, const QNetworkProxy& custom_proxy = - QNetworkProxy::ProxyType::DefaultProxy); + QNetworkProxy::ProxyType::DefaultProxy, + Http2Status http2_status = Http2Status::DontSet); static NetworkResult performNetworkOperation(const QString& url, int timeout, const QByteArray& input_data, @@ -73,7 +77,8 @@ class RSSGUARD_DLLSPEC NetworkFactory { const QString& username = QString(), const QString& password = QString(), const QNetworkProxy& custom_proxy = - QNetworkProxy::ProxyType::DefaultProxy); + QNetworkProxy::ProxyType::DefaultProxy, + Http2Status http2_status = Http2Status::DontSet); static NetworkResult performNetworkOperation(const QString& url, int timeout, QHttpMultiPart* input_data, @@ -85,7 +90,8 @@ class RSSGUARD_DLLSPEC NetworkFactory { const QString& username = QString(), const QString& password = QString(), const QNetworkProxy& custom_proxy = - QNetworkProxy::ProxyType::DefaultProxy); + QNetworkProxy::ProxyType::DefaultProxy, + Http2Status http2_status = Http2Status::DontSet); }; Q_DECLARE_METATYPE(NetworkFactory::NetworkAuthentication) diff --git a/src/librssguard/services/abstract/gui/formfeeddetails.cpp b/src/librssguard/services/abstract/gui/formfeeddetails.cpp index e2a7386d7..48429c40d 100644 --- a/src/librssguard/services/abstract/gui/formfeeddetails.cpp +++ b/src/librssguard/services/abstract/gui/formfeeddetails.cpp @@ -61,7 +61,7 @@ void FormFeedDetails::apply() { } if (isChangeAllowed(m_ui->m_mcbFeedRtl)) { - fd->setIsRtl(m_ui->m_cbFeedRTL->isChecked()); + fd->setIsRtl(m_ui->m_cbFeedRtl->isChecked()); } m_ui->m_wdgArticleLimiting->saveFeed(fd, m_isBatchEdit); @@ -127,7 +127,7 @@ void FormFeedDetails::loadFeedData() { m_ui->m_mcbOpenArticlesAutomatically->addActionWidget(m_ui->m_cbOpenArticlesAutomatically); m_ui->m_mcbDisableFeed->addActionWidget(m_ui->m_cbDisableFeed); m_ui->m_mcbSuppressFeed->addActionWidget(m_ui->m_cbSuppressFeed); - m_ui->m_mcbFeedRtl->addActionWidget(m_ui->m_cbFeedRTL); + m_ui->m_mcbFeedRtl->addActionWidget(m_ui->m_cbFeedRtl); } else { // We hide batch selectors. @@ -158,7 +158,7 @@ void FormFeedDetails::loadFeedData() { ->setCurrentIndex(m_ui->m_cmbAutoUpdateType->findData(QVariant::fromValue(int(fd->autoUpdateType())))); m_ui->m_spinAutoUpdateInterval->setValue(fd->autoUpdateInterval()); m_ui->m_cbOpenArticlesAutomatically->setChecked(fd->openArticlesDirectly()); - m_ui->m_cbFeedRTL->setChecked(fd->isRtl()); + m_ui->m_cbFeedRtl->setChecked(fd->isRtl()); m_ui->m_cbDisableFeed->setChecked(fd->isSwitchedOff()); m_ui->m_cbSuppressFeed->setChecked(fd->isQuiet()); diff --git a/src/librssguard/services/abstract/gui/formfeeddetails.ui b/src/librssguard/services/abstract/gui/formfeeddetails.ui index eea8c49b8..5aa85fc89 100644 --- a/src/librssguard/services/abstract/gui/formfeeddetails.ui +++ b/src/librssguard/services/abstract/gui/formfeeddetails.ui @@ -131,7 +131,7 @@ - + Right-to-left layout @@ -146,10 +146,10 @@ - Qt::Horizontal + Qt::Orientation::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok false @@ -177,10 +177,18 @@ + m_tabWidget + m_mcbAutoDownloading + m_cmbAutoUpdateType + m_spinAutoUpdateInterval + m_mcbOpenArticlesAutomatically m_cbOpenArticlesAutomatically + m_mcbSuppressFeed m_cbSuppressFeed + m_mcbDisableFeed m_cbDisableFeed - m_cbFeedRTL + m_mcbFeedRtl + m_cbFeedRtl