Save URL in NetworkRequest.

This commit is contained in:
Patrick Sean Klein 2023-05-09 22:59:40 +01:00
parent 7de7c8bcb3
commit b4249ea941
No known key found for this signature in database
GPG Key ID: B6D50F39A56F6906
2 changed files with 85 additions and 73 deletions

View File

@ -1,10 +1,10 @@
#include "NetworkRequest.h" #include "NetworkRequest.h"
#include "NetworkManager.h" #include "NetworkManager.h"
#include <QString>
#include <QtNetwork/QNetworkAccessManager> #include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply> #include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkRequest>
#include <QString>
namespace namespace
{ {
@ -17,16 +17,18 @@ namespace
} }
return url; return url;
} }
} } // namespace
void NetworkRequest::fetch(const QUrl& url) void NetworkRequest::fetch(const QUrl& url)
{ {
reset(); reset();
m_url = url;
QNetworkRequest request(url); QNetworkRequest request(url);
// Set headers // Set headers
for(const auto &[header, value] : qAsConst(m_headers)) { for (const auto& [header, value] : qAsConst(m_headers)) {
request.setRawHeader(header.toUtf8(), value.toUtf8()); request.setRawHeader(header.toUtf8(), value.toUtf8());
} }
@ -47,9 +49,9 @@ void NetworkRequest::fetchFinished()
m_reply->deleteLater(); m_reply->deleteLater();
m_reply = nullptr; m_reply = nullptr;
if(error != QNetworkReply::NoError) { if (error != QNetworkReply::NoError) {
// Do not emit on abort. // Do not emit on abort.
if(error != QNetworkReply::OperationCanceledError) { if (error != QNetworkReply::OperationCanceledError) {
emit failure(); emit failure();
} }
return; return;
@ -74,7 +76,7 @@ void NetworkRequest::fetchFinished()
// Parse content type // Parse content type
auto tokens = contentTypeHeader.split(";", Qt::SkipEmptyParts); auto tokens = contentTypeHeader.split(";", Qt::SkipEmptyParts);
m_content_type = tokens[0].trimmed(); m_content_type = tokens[0].trimmed();
for(int i = 1; i < tokens.size(); ++i) { for (int i = 1; i < tokens.size(); ++i) {
auto parameterTokens = tokens[i].split("="); auto parameterTokens = tokens[i].split("=");
m_content_type_parameters[parameterTokens[0]] = parameterTokens[1]; m_content_type_parameters[parameterTokens[0]] = parameterTokens[1];
} }
@ -99,7 +101,7 @@ void NetworkRequest::reset()
void NetworkRequest::cancel() void NetworkRequest::cancel()
{ {
if(m_reply) { if (m_reply) {
m_reply->abort(); m_reply->abort();
} }
} }
@ -111,10 +113,7 @@ NetworkRequest::~NetworkRequest()
QUrl NetworkRequest::url() const QUrl NetworkRequest::url() const
{ {
if(m_reply) { return m_url;
return m_reply->url();
}
return {};
} }
void NetworkRequest::setMaxRedirects(int maxRedirects) void NetworkRequest::setMaxRedirects(int maxRedirects)
@ -122,9 +121,15 @@ void NetworkRequest::setMaxRedirects(int maxRedirects)
m_maxRedirects = std::max(0, maxRedirects); m_maxRedirects = std::max(0, maxRedirects);
} }
NetworkRequest::NetworkRequest(int maxRedirects, std::chrono::milliseconds timeoutDuration, NetworkRequest::NetworkRequest(int maxRedirects,
QList<QPair<QString, QString>> headers, QNetworkAccessManager* manager) std::chrono::milliseconds timeoutDuration,
: m_reply(nullptr), m_maxRedirects(maxRedirects), m_redirects(0), m_timeoutDuration(timeoutDuration), m_headers(headers) QList<QPair<QString, QString>> headers,
QNetworkAccessManager* manager)
: m_reply(nullptr)
, m_maxRedirects(maxRedirects)
, m_redirects(0)
, m_timeoutDuration(timeoutDuration)
, m_headers(headers)
{ {
m_manager = manager ? manager : getNetMgr(); m_manager = manager ? manager : getNetMgr();
connect(&m_timeout, &QTimer::timeout, this, &NetworkRequest::fetchTimeout); connect(&m_timeout, &QTimer::timeout, this, &NetworkRequest::fetchTimeout);
@ -156,9 +161,9 @@ NetworkRequest createRequest(int maxRedirects,
QNetworkAccessManager* manager) QNetworkAccessManager* manager)
{ {
// Append user agent unless given // Append user agent unless given
if(std::none_of(additionalHeaders.begin(), additionalHeaders.end(), [](const auto& pair) { if (std::none_of(additionalHeaders.begin(), additionalHeaders.end(), [](const auto& pair) {
return pair.first == "User-Agent"; return pair.first == "User-Agent";
})) { })) {
additionalHeaders.append(QPair{"User-Agent", "KeePassXC"}); additionalHeaders.append(QPair{"User-Agent", "KeePassXC"});
} }
return NetworkRequest(maxRedirects, timeoutDuration, additionalHeaders, manager); return NetworkRequest(maxRedirects, timeoutDuration, additionalHeaders, manager);

View File

@ -17,11 +17,11 @@
#ifndef KEEPASSXC_NETWORKREQUEST_H #ifndef KEEPASSXC_NETWORKREQUEST_H
#define KEEPASSXC_NETWORKREQUEST_H #define KEEPASSXC_NETWORKREQUEST_H
#include <QObject>
#include <QList>
#include <QUrl>
#include <QHash> #include <QHash>
#include <QList>
#include <QObject>
#include <QTimer> #include <QTimer>
#include <QUrl>
class QNetworkReply; class QNetworkReply;
class QNetworkAccessManager; class QNetworkAccessManager;
@ -32,67 +32,74 @@ class QNetworkAccessManager;
* response can be obtained by calling the url(), ContentType(), and ContentTypeParameters() * response can be obtained by calling the url(), ContentType(), and ContentTypeParameters()
* methods. * methods.
*/ */
class NetworkRequest : public QObject { class NetworkRequest : public QObject
Q_OBJECT {
Q_OBJECT
QNetworkAccessManager* m_manager; QNetworkAccessManager* m_manager;
QNetworkReply* m_reply; QNetworkReply* m_reply;
QByteArray m_bytes; QByteArray m_bytes;
// Response information // Response information
QString m_content_type; QString m_content_type;
QHash<QString, QString> m_content_type_parameters; QHash<QString, QString> m_content_type_parameters;
// Request parameters // Request parameters
QTimer m_timeout; QTimer m_timeout;
int m_maxRedirects; int m_maxRedirects;
int m_redirects; int m_redirects;
std::chrono::milliseconds m_timeoutDuration; std::chrono::milliseconds m_timeoutDuration;
QList<QPair<QString, QString>> m_headers; QList<QPair<QString, QString>> m_headers;
public: QUrl m_url;
// TODO Disallow insecure connections by default?
explicit NetworkRequest(int maxRedirects, std::chrono::milliseconds timeoutDuration,
QList<QPair<QString, QString>> headers, QNetworkAccessManager* manager = nullptr);
~NetworkRequest() override;
void setMaxRedirects(int maxRedirects); public:
void setTimeout(std::chrono::milliseconds timeoutDuration); // TODO Disallow insecure connections by default?
explicit NetworkRequest(int maxRedirects,
std::chrono::milliseconds timeoutDuration,
QList<QPair<QString, QString>> headers,
QNetworkAccessManager* manager = nullptr);
~NetworkRequest() override;
// TODO Should it be single shot vs multiple shot? void setMaxRedirects(int maxRedirects);
void fetch(const QUrl& url); void setTimeout(std::chrono::milliseconds timeoutDuration);
void cancel();
QUrl url() const; // TODO Should it be single shot vs multiple shot?
/** void fetch(const QUrl& url);
* @return The MIME Type set in the Content-Type header. Empty string if Content-Type was not set. void cancel();
*/
const QString& ContentType() const;
/**
* @return Any parameters set in the Content-Type header.
*/
const QHash<QString, QString>& ContentTypeParameters() const;
private:
void reset();
private slots:
void fetchFinished();
void fetchReadyRead();
void fetchTimeout();
signals:
void success(QByteArray);
void failure();
};
QUrl url() const;
/** /**
* Creates a NetworkRequest with default parameters. * @return The MIME Type set in the Content-Type header. Empty string if Content-Type was not set.
* @param maxRedirects
* @param timeoutDuration
* @param headers
* @param manager
* @return
*/ */
NetworkRequest createRequest(int maxRedirects = 5, const QString& ContentType() const;
std::chrono::milliseconds timeoutDuration = std::chrono::milliseconds(5000), /**
QList<QPair<QString, QString>> additionalHeaders = {}, QNetworkAccessManager* manager = nullptr); * @return Any parameters set in the Content-Type header.
*/
const QHash<QString, QString>& ContentTypeParameters() const;
private:
void reset();
private slots:
void fetchFinished();
void fetchReadyRead();
void fetchTimeout();
signals:
void success(QByteArray);
void failure();
};
/**
* Creates a NetworkRequest with default parameters.
* @param maxRedirects
* @param timeoutDuration
* @param headers
* @param manager
* @return
*/
NetworkRequest createRequest(int maxRedirects = 5,
std::chrono::milliseconds timeoutDuration = std::chrono::milliseconds(5000),
QList<QPair<QString, QString>> additionalHeaders = {},
QNetworkAccessManager* manager = nullptr);
#endif // KEEPASSXC_NETWORKREQUEST_H #endif // KEEPASSXC_NETWORKREQUEST_H