利用Qt实现Https网络请求
#ifndef NETWORKACCESS_H
#define NETWORKACCESS_H
#include <QByteArray>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QObject>
#include <QPair>
#include <QUrl>
#include <QVector>
struct NetworkReply
{
QNetworkReply::NetworkError error = QNetworkReply::HostNotFoundError;
QByteArray data;
QString ErrorStr();
};
class NetworkAccess : public QObject
{
Q_OBJECT
public:
typedef QVector<QPair<QByteArray, QByteArray>> RawHeaderPairs;
explicit NetworkAccess(QObject *p_parent = nullptr);
void AsyncRequest(const QUrl &url);
static NetworkReply Request(const QUrl &url);
static NetworkReply Request(const QUrl &url, const RawHeaderPairs &raw_header);
static NetworkReply Put(const QUrl &url, const RawHeaderPairs &raw_header, const QByteArray &data);
static NetworkReply Post(const QUrl &url, const RawHeaderPairs &raw_header, const QByteArray &data);
static NetworkReply Delete(const QUrl &url, const RawHeaderPairs &raw_header, const QByteArray &data);
Q_SIGNALS:
void SgnRequestFinished(const NetworkReply &reply, const QString &url);
private:
static void HandleReply(QNetworkReply *reply, NetworkReply &m_reply);
static QNetworkRequest NetworkRequest(const QUrl &url);
static NetworkReply SendRequest(const QUrl &url,
const RawHeaderPairs &header,
const QByteArray &action,
const QByteArray &data);
private:
QNetworkAccessManager net_access_mgr_;
};
#endif // NETWORKACCESS_H
#include "network_access.h"
#include <QEventLoop>
#include <QMetaEnum>
#include <QNetworkReply>
#include <QScopedPointer>
#include <QThread>
QString NetworkReply::ErrorStr()
{
static const auto index_enum = QNetworkReply::staticMetaObject.indexOfEnumerator("NetworkError");
const auto meta_enum = QNetworkReply::staticMetaObject.enumerator(index_enum);
return meta_enum.key(error);
}
NetworkAccess::NetworkAccess(QObject * p_parent)
: QObject(p_parent)
{
connect(&net_access_mgr_, &QNetworkAccessManager::finished,
this, [this](QNetworkReply * p_reply) {
NetworkReply reply;
NetworkAccess::HandleReply(p_reply, reply);
emit SgnRequestFinished(reply, p_reply->request().url().toString());
});
}
void NetworkAccess::AsyncRequest(const QUrl & url)
{
if (!url.isValid()) {
return;
}
net_access_mgr_.get(NetworkRequest(url));
}
NetworkReply NetworkAccess::Request(const QUrl & url)
{
return Request(url, RawHeaderPairs());
}
NetworkReply NetworkAccess::Request(const QUrl & url, const RawHeaderPairs & raw_header)
{
return SendRequest(url, raw_header, "GET", QByteArray());
}
NetworkReply NetworkAccess::Put(const QUrl & url, const RawHeaderPairs & raw_header, const QByteArray & data)
{
return SendRequest(url, raw_header, "PUT", data);
}
NetworkReply NetworkAccess::Post(const QUrl & url, const RawHeaderPairs & raw_header, const QByteArray & data)
{
return SendRequest(url, raw_header, "POST", data);
}
NetworkReply NetworkAccess::Delete(const QUrl & url, const RawHeaderPairs & raw_header, const QByteArray & data)
{
return SendRequest(url, raw_header, "DELETE", data);
}
void NetworkAccess::HandleReply(QNetworkReply * reply, NetworkReply & m_reply)
{
m_reply.error = reply->error();
m_reply.data = reply->readAll();
if (m_reply.error != QNetworkReply::NoError) {
qWarning() << "request reply error" << m_reply.error << reply->request().url() << m_reply.data;
}
reply->deleteLater();
}
QNetworkRequest NetworkAccess::NetworkRequest(const QUrl & url)
{
QNetworkRequest request(url);
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
return request;
}
NetworkReply NetworkAccess::SendRequest(
const QUrl & url,
const RawHeaderPairs & header,
const QByteArray & action,
const QByteArray & data)
{
QEventLoop loop;
NetworkReply reply;
if (!url.isValid()) {
return reply;
}
QNetworkAccessManager net_access_mgr;
connect(&net_access_mgr, &QNetworkAccessManager::finished,
[=, &reply, &loop](QNetworkReply * p_reply) {
HandleReply(p_reply, reply);
loop.quit();
});
auto request(NetworkRequest(url));
for (const auto & header : header) {
request.setRawHeader(header.first, header.second);
}
net_access_mgr.sendCustomRequest(request, action, data);
loop.exec();
return reply;
}