From 06645269475561027790e0b58602647a92d6599d Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Fri, 29 Dec 2017 20:41:14 +0900 Subject: Allow to customize and connect to the used QNetworkAccessManager from clients We don't really want to let the world know that we use the only instance of NAM; instead, we provide a point of customisation to whatever NAM is created in ConnectionData, in the form of a static customizeNetworkAccess() method that gets a function to run on a/the created NAM. This function can do additional configuration on NAM (such as setting a proxy factory, network configuration, or caching) and/or connect to its signals, such as sslErrors() and proxyAuthenticationRequired(). Closes #143. --- connectiondata.cpp | 53 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 22 deletions(-) (limited to 'connectiondata.cpp') diff --git a/connectiondata.cpp b/connectiondata.cpp index 70791952..4bfddd00 100644 --- a/connectiondata.cpp +++ b/connectiondata.cpp @@ -24,20 +24,10 @@ using namespace QMatrixClient; -QNetworkAccessManager* createNam() -{ - auto nam = new QNetworkAccessManager(); - // See #109. Once Qt bearer management gets better, this workaround - // should become unnecessary. - nam->connect(nam, &QNetworkAccessManager::networkAccessibleChanged, - nam, [=] { - nam->setNetworkAccessible(QNetworkAccessManager::Accessible); - }); - return nam; -} - struct ConnectionData::Private { + explicit Private(const QUrl& url) : baseUrl(url) { } + QUrl baseUrl; QByteArray accessToken; QString lastEvent; @@ -45,19 +35,19 @@ struct ConnectionData::Private mutable unsigned int txnCounter = 0; const qint64 id = QDateTime::currentMSecsSinceEpoch(); + + static QNetworkAccessManager* createNam(); + static nam_customizer_t customizeNam; }; +ConnectionData::nam_customizer_t ConnectionData::Private::customizeNam = + [] (auto* /* unused */) { }; + ConnectionData::ConnectionData(QUrl baseUrl) - : d(new Private) -{ - nam(); // Just to ensure NAM is created - d->baseUrl = baseUrl; -} + : d(std::make_unique(baseUrl)) +{ } -ConnectionData::~ConnectionData() -{ - delete d; -} +ConnectionData::~ConnectionData() = default; QByteArray ConnectionData::accessToken() const { @@ -69,9 +59,21 @@ QUrl ConnectionData::baseUrl() const return d->baseUrl; } +QNetworkAccessManager* ConnectionData::Private::createNam() +{ + auto nam = new QNetworkAccessManager; + // See #109. Once Qt bearer management gets better, this workaround + // should become unnecessary. + nam->connect(nam, &QNetworkAccessManager::networkAccessibleChanged, + [nam] { nam->setNetworkAccessible(QNetworkAccessManager::Accessible); + }); + customizeNam(nam); + return nam; +} + QNetworkAccessManager* ConnectionData::nam() const { - static auto nam = createNam(); + static auto nam = d->createNam(); return nam; } @@ -124,3 +126,10 @@ QByteArray ConnectionData::generateTxnId() const return QByteArray::number(d->id) + 'q' + QByteArray::number(++d->txnCounter); } + +void +ConnectionData::customizeNetworkAccess(ConnectionData::nam_customizer_t customizer) +{ + Private::customizeNam = customizer; +} + -- cgit v1.2.3 From e2147ca36d22194582f76faf8b6fc89623172084 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Fri, 29 Dec 2017 23:23:32 +0900 Subject: Don't use generic lambdas in initialisers This seems to upset MSVC. --- connectiondata.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'connectiondata.cpp') diff --git a/connectiondata.cpp b/connectiondata.cpp index 4bfddd00..11015dbf 100644 --- a/connectiondata.cpp +++ b/connectiondata.cpp @@ -41,7 +41,7 @@ struct ConnectionData::Private }; ConnectionData::nam_customizer_t ConnectionData::Private::customizeNam = - [] (auto* /* unused */) { }; + [] (QNetworkAccessManager* /* unused */) { }; ConnectionData::ConnectionData(QUrl baseUrl) : d(std::make_unique(baseUrl)) -- cgit v1.2.3 From 4377a868f0d69ca92afca13b0087aee2d97bd7ac Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sat, 30 Dec 2017 17:48:25 +0900 Subject: QMatrixClient::NetworkAccessManager (singleton Qt NAM that remembers ignored SSL errors) Closes #145. --- CMakeLists.txt | 1 + connectiondata.cpp | 31 ++------------------ connectiondata.h | 5 ---- libqmatrixclient.pri | 6 ++-- networkaccessmanager.cpp | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ networkaccessmanager.h | 49 ++++++++++++++++++++++++++++++++ 6 files changed, 130 insertions(+), 36 deletions(-) create mode 100644 networkaccessmanager.cpp create mode 100644 networkaccessmanager.h (limited to 'connectiondata.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index 9fea5b0c..463bfea7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ message( STATUS ) # Set up source files set(libqmatrixclient_SRCS + networkaccessmanager.cpp connectiondata.cpp connection.cpp logging.cpp diff --git a/connectiondata.cpp b/connectiondata.cpp index 11015dbf..4e9bc77e 100644 --- a/connectiondata.cpp +++ b/connectiondata.cpp @@ -18,10 +18,9 @@ #include "connectiondata.h" +#include "networkaccessmanager.h" #include "logging.h" -#include - using namespace QMatrixClient; struct ConnectionData::Private @@ -35,14 +34,8 @@ struct ConnectionData::Private mutable unsigned int txnCounter = 0; const qint64 id = QDateTime::currentMSecsSinceEpoch(); - - static QNetworkAccessManager* createNam(); - static nam_customizer_t customizeNam; }; -ConnectionData::nam_customizer_t ConnectionData::Private::customizeNam = - [] (QNetworkAccessManager* /* unused */) { }; - ConnectionData::ConnectionData(QUrl baseUrl) : d(std::make_unique(baseUrl)) { } @@ -59,22 +52,9 @@ QUrl ConnectionData::baseUrl() const return d->baseUrl; } -QNetworkAccessManager* ConnectionData::Private::createNam() -{ - auto nam = new QNetworkAccessManager; - // See #109. Once Qt bearer management gets better, this workaround - // should become unnecessary. - nam->connect(nam, &QNetworkAccessManager::networkAccessibleChanged, - [nam] { nam->setNetworkAccessible(QNetworkAccessManager::Accessible); - }); - customizeNam(nam); - return nam; -} - QNetworkAccessManager* ConnectionData::nam() const { - static auto nam = d->createNam(); - return nam; + return NetworkAccessManager::instance(); } void ConnectionData::setBaseUrl(QUrl baseUrl) @@ -126,10 +106,3 @@ QByteArray ConnectionData::generateTxnId() const return QByteArray::number(d->id) + 'q' + QByteArray::number(++d->txnCounter); } - -void -ConnectionData::customizeNetworkAccess(ConnectionData::nam_customizer_t customizer) -{ - Private::customizeNam = customizer; -} - diff --git a/connectiondata.h b/connectiondata.h index 9f17a9b5..7a2f2e90 100644 --- a/connectiondata.h +++ b/connectiondata.h @@ -20,7 +20,6 @@ #include -#include #include class QNetworkAccessManager; @@ -49,10 +48,6 @@ namespace QMatrixClient QByteArray generateTxnId() const; - using nam_customizer_t = - std::function; - static void customizeNetworkAccess(nam_customizer_t customizer); - private: struct Private; std::unique_ptr d; diff --git a/libqmatrixclient.pri b/libqmatrixclient.pri index 5910554c..8ee3634c 100644 --- a/libqmatrixclient.pri +++ b/libqmatrixclient.pri @@ -33,7 +33,8 @@ HEADERS += \ $$files($$PWD/jobs/generated/*.h, false) \ $$PWD/logging.h \ $$PWD/settings.h \ - $$PWD/networksettings.h + $$PWD/networksettings.h \ + $$PWD/networkaccessmanager.h SOURCES += \ $$PWD/connectiondata.cpp \ @@ -61,4 +62,5 @@ SOURCES += \ $$files($$PWD/jobs/generated/*.cpp, false) \ $$PWD/logging.cpp \ $$PWD/settings.cpp \ - $$PWD/networksettings.cpp + $$PWD/networksettings.cpp \ + $$PWD/networkaccessmanager.cpp diff --git a/networkaccessmanager.cpp b/networkaccessmanager.cpp new file mode 100644 index 00000000..7fb2f602 --- /dev/null +++ b/networkaccessmanager.cpp @@ -0,0 +1,74 @@ +/****************************************************************************** + * Copyright (C) 2018 Kitsune Ral + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "networkaccessmanager.h" + +#include + +using namespace QMatrixClient; + +class NetworkAccessManager::Private +{ + public: + QList ignoredSslErrors; +}; + +NetworkAccessManager::NetworkAccessManager() : d(std::make_unique()) +{ } + +QList NetworkAccessManager::ignoredSslErrors() const +{ + return d->ignoredSslErrors; +} + +void NetworkAccessManager::addIgnoredSslError(const QSslError& error) +{ + d->ignoredSslErrors << error; +} + +void NetworkAccessManager::clearIgnoredSslErrors() +{ + d->ignoredSslErrors.clear(); +} + +static NetworkAccessManager* createNam() +{ + auto nam = new NetworkAccessManager; + // See #109. Once Qt bearer management gets better, this workaround + // should become unnecessary. + nam->connect(nam, &QNetworkAccessManager::networkAccessibleChanged, + [nam] { nam->setNetworkAccessible(QNetworkAccessManager::Accessible); }); + return nam; +} + +NetworkAccessManager*NetworkAccessManager::instance() +{ + static auto* nam = createNam(); + return nam; +} + +NetworkAccessManager::~NetworkAccessManager() = default; + +QNetworkReply* NetworkAccessManager::createRequest(Operation op, + const QNetworkRequest& request, QIODevice* outgoingData) +{ + auto reply = + QNetworkAccessManager::createRequest(op, request, outgoingData); + reply->ignoreSslErrors(d->ignoredSslErrors); + return reply; +} diff --git a/networkaccessmanager.h b/networkaccessmanager.h new file mode 100644 index 00000000..ea08c591 --- /dev/null +++ b/networkaccessmanager.h @@ -0,0 +1,49 @@ +/****************************************************************************** + * Copyright (C) 2018 Kitsune Ral + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include + +#include + +namespace QMatrixClient +{ + class NetworkAccessManager : public QNetworkAccessManager + { + Q_OBJECT + public: + NetworkAccessManager(); + ~NetworkAccessManager() override; + + QList ignoredSslErrors() const; + void addIgnoredSslError(const QSslError& error); + void clearIgnoredSslErrors(); + + /** Get a pointer to the singleton */ + static NetworkAccessManager* instance(); + + private: + QNetworkReply * createRequest(Operation op, + const QNetworkRequest &request, + QIODevice *outgoingData = Q_NULLPTR) override; + + class Private; + std::unique_ptr d; + }; +} // namespace QMatrixClient -- cgit v1.2.3