1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
|
#ifndef NETWORK_ACCESS_MANAGER_HPP__
#define NETWORK_ACCESS_MANAGER_HPP__
#include <QList>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QSslError>
#include <QString>
#include "JS8_Main/JS8MessageBox.h"
class QNetworkRequest;
class QIODevice;
class QWidget;
// sub-class QNAM to keep a list of accepted SSL errors and allow
// them in future replies
class NetworkAccessManager : public QNetworkAccessManager {
public:
NetworkAccessManager(QWidget *parent) : QNetworkAccessManager(parent) {
// handle SSL errors that have not been cached as allowed
// exceptions and offer them to the user to add to the ignored
// exception cache
connect(
this, &QNetworkAccessManager::sslErrors,
[this, &parent](QNetworkReply *reply,
QList<QSslError> const &errors) {
QString message;
QList<QSslError> new_errors;
for (auto const &error : errors) {
if (!allowed_ssl_errors_.contains(error)) {
new_errors << error;
message += '\n' +
reply->request().url().toDisplayString() +
": " + error.errorString();
}
}
if (new_errors.size()) {
QString certs;
for (auto const &cert :
reply->sslConfiguration().peerCertificateChain()) {
certs += cert.toText() + '\n';
}
if (JS8MessageBox::Ignore ==
JS8MessageBox::query_message(
parent, tr("Network SSL Errors"), message, certs,
JS8MessageBox::Abort | JS8MessageBox::Ignore)) {
// accumulate new SSL error exceptions that have been
// allowed
allowed_ssl_errors_.append(new_errors);
reply->ignoreSslErrors(allowed_ssl_errors_);
}
} else {
// no new exceptions so silently ignore the ones already
// allowed
reply->ignoreSslErrors(allowed_ssl_errors_);
}
});
}
protected:
QNetworkReply *createRequest(Operation operation,
QNetworkRequest const &request,
QIODevice *outgoing_data = nullptr) override {
auto reply = QNetworkAccessManager::createRequest(operation, request,
outgoing_data);
// errors are usually certificate specific so passing all cached
// exceptions here is ok
reply->ignoreSslErrors(allowed_ssl_errors_);
return reply;
}
private:
QList<QSslError> allowed_ssl_errors_;
};
#endif
|