This commit is contained in:
zhuzichu 2023-07-24 16:48:45 +08:00
parent d0e283747e
commit db805ef85d
2 changed files with 152 additions and 53 deletions

View File

@ -5,12 +5,14 @@
#include <QNetworkReply> #include <QNetworkReply>
#include <QUrlQuery> #include <QUrlQuery>
#include <QHttpMultiPart> #include <QHttpMultiPart>
#include <QJsonDocument>
#include "FluApp.h" #include "FluApp.h"
FluHttp::FluHttp(QObject *parent) FluHttp::FluHttp(QObject *parent)
: QObject{parent} : QObject{parent}
{ {
retry(3);
timeout(15000);
} }
FluHttp::~FluHttp(){ FluHttp::~FluHttp(){
@ -33,34 +35,121 @@ void FluHttp::post(QVariantMap params,QVariantMap headers){
QVariantMap data = invokeIntercept(params,headers,"post").toMap(); QVariantMap data = invokeIntercept(params,headers,"post").toMap();
QThreadPool::globalInstance()->start([=](){ QThreadPool::globalInstance()->start([=](){
Q_EMIT start(); Q_EMIT start();
QNetworkAccessManager manager; for (int i = 0; i < retry(); ++i) {
QUrl url(_url); QNetworkAccessManager manager;
QNetworkRequest request(url); manager.setTransferTimeout(timeout());
addHeaders(&request,data["headers"].toMap()); QUrl url(_url);
QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); QNetworkRequest request(url);
QString contentType = QString("multipart/form-data;boundary=%1").arg(multiPart->boundary()); addHeaders(&request,data["headers"].toMap());
request.setHeader(QNetworkRequest::ContentTypeHeader, contentType); QHttpMultiPart multiPart(QHttpMultiPart::FormDataType);
for (const auto& each : data["params"].toMap().toStdMap()) QString contentType = QString("multipart/form-data;boundary=%1").arg(multiPart.boundary());
{ request.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
const QString& key = each.first; for (const auto& each : data["params"].toMap().toStdMap())
const QString& value = each.second.toString(); {
QString dispositionHeader = QString("form-data; name=\"%1\"").arg(key); const QString& key = each.first;
QHttpPart part; const QString& value = each.second.toString();
part.setHeader(QNetworkRequest::ContentDispositionHeader, dispositionHeader); QString dispositionHeader = QString("form-data; name=\"%1\"").arg(key);
part.setBody(value.toUtf8()); QHttpPart part;
multiPart->append(part); part.setHeader(QNetworkRequest::ContentDispositionHeader, dispositionHeader);
part.setBody(value.toUtf8());
multiPart.append(part);
}
QEventLoop loop;
QNetworkReply* reply = manager.post(request,&multiPart);
_cache.append(reply);
connect(&manager,&QNetworkAccessManager::finished,this,[&loop](QNetworkReply *reply){
loop.quit();
});
loop.exec();
QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
bool isSuccess = reply->error() == QNetworkReply::NoError;
reply->deleteLater();
reply = nullptr;
if (isSuccess) {
Q_EMIT success(result);
break;
}else{
if(i == retry()-1){
Q_EMIT error(status,errorString);
}
}
} }
QEventLoop loop; Q_EMIT finish();
QNetworkReply* reply = manager.post(request,multiPart); });
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); }
loop.exec();
if (reply->error() == QNetworkReply::NoError) { void FluHttp::postString(QString params,QVariantMap headers){
Q_EMIT success(QString::fromUtf8(reply->readAll())); QVariantMap data = invokeIntercept(params,headers,"postString").toMap();
}else{ QThreadPool::globalInstance()->start([=](){
Q_EMIT error(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString()); Q_EMIT start();
for (int i = 0; i < retry(); ++i) {
QNetworkAccessManager manager;
manager.setTransferTimeout(timeout());
QUrl url(_url);
QNetworkRequest request(url);
addHeaders(&request,data["headers"].toMap());
QEventLoop loop;
QNetworkReply* reply = manager.post(request,params.toUtf8());
_cache.append(reply);
connect(&manager,&QNetworkAccessManager::finished,this,[&loop](QNetworkReply *reply){
loop.quit();
});
loop.exec();
QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
bool isSuccess = reply->error() == QNetworkReply::NoError;
reply->deleteLater();
reply = nullptr;
if (isSuccess) {
Q_EMIT success(result);
break;
}else{
if(i == retry()-1){
Q_EMIT error(status,errorString);
}
}
}
Q_EMIT finish();
});
}
void FluHttp::postJson(QVariantMap params,QVariantMap headers){
QVariantMap data = invokeIntercept(params,headers,"postJson").toMap();
QThreadPool::globalInstance()->start([=](){
Q_EMIT start();
for (int i = 0; i < retry(); ++i) {
QNetworkAccessManager manager;
manager.setTransferTimeout(timeout());
QUrl url(_url);
QNetworkRequest request(url);
addHeaders(&request,data["headers"].toMap());
QString contentType = QString("application/json;charset=utf-8");
request.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
QEventLoop loop;
QNetworkReply* reply = manager.post(request,QJsonDocument::fromVariant(data["params"]).toJson());
_cache.append(reply);
connect(&manager,&QNetworkAccessManager::finished,this,[&loop](QNetworkReply *reply){
loop.quit();
});
loop.exec();
QString result = QString::fromUtf8(reply->readAll());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
bool isSuccess = reply->error() == QNetworkReply::NoError;
reply->deleteLater();
reply = nullptr;
if (isSuccess) {
Q_EMIT success(result);
break;
}else{
if(i == retry()-1){
Q_EMIT error(status,errorString);
}
}
} }
reply->deleteLater();
reply = nullptr;
Q_EMIT finish(); Q_EMIT finish();
}); });
} }
@ -69,27 +158,35 @@ void FluHttp::get(QVariantMap params,QVariantMap headers){
QVariantMap data = invokeIntercept(params,headers,"get").toMap(); QVariantMap data = invokeIntercept(params,headers,"get").toMap();
QThreadPool::globalInstance()->start([=](){ QThreadPool::globalInstance()->start([=](){
Q_EMIT start(); Q_EMIT start();
QNetworkAccessManager manager; for (int i = 0; i < retry(); ++i) {
QUrl url(_url); QNetworkAccessManager manager;
addQueryParam(&url,data["params"].toMap()); manager.setTransferTimeout(timeout());
QNetworkRequest request(url); QUrl url(_url);
addHeaders(&request,data["headers"].toMap()); addQueryParam(&url,data["params"].toMap());
QEventLoop *loop = new QEventLoop(); QNetworkRequest request(url);
connect(&manager,&QNetworkAccessManager::finished,this,[=](QNetworkReply *reply){ addHeaders(&request,data["headers"].toMap());
loop->quit(); QEventLoop loop;
}); QNetworkReply* reply = manager.get(request);
QNetworkReply* reply = manager.get(request); _cache.append(reply);
_cache.append(reply); connect(&manager,&QNetworkAccessManager::finished,this,[&loop](QNetworkReply *reply){
loop->exec(); loop.quit();
if (reply->error() == QNetworkReply::NoError) { });
Q_EMIT success(QString::fromUtf8(reply->readAll())); loop.exec();
}else{ QString result = QString::fromUtf8(reply->readAll());
Q_EMIT error(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString()); int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QString errorString = reply->errorString();
bool isSuccess = reply->error() == QNetworkReply::NoError;
reply->deleteLater();
reply = nullptr;
if (isSuccess) {
Q_EMIT success(result);
break;
}else{
if(i == retry()-1){
Q_EMIT error(status,errorString);
}
}
} }
loop->deleteLater();
reply->deleteLater();
loop = nullptr;
reply = nullptr;
Q_EMIT finish(); Q_EMIT finish();
}); });
} }
@ -113,9 +210,9 @@ void FluHttp::download(QString path,QVariantMap params,QVariantMap headers){
Q_EMIT finish(); Q_EMIT finish();
return; return;
} }
QEventLoop *loop = new QEventLoop(); QEventLoop loop;
connect(&manager,&QNetworkAccessManager::finished,this,[=](QNetworkReply *reply){ connect(&manager,&QNetworkAccessManager::finished,this,[&loop](QNetworkReply *reply){
loop->quit(); loop.quit();
}); });
QPointer<QNetworkReply> reply = manager.get(request); QPointer<QNetworkReply> reply = manager.get(request);
_cache.append(reply); _cache.append(reply);
@ -125,17 +222,15 @@ void FluHttp::download(QString path,QVariantMap params,QVariantMap headers){
connect(reply,&QNetworkReply::readyRead,this,[=](){ connect(reply,&QNetworkReply::readyRead,this,[=](){
file->write(reply->readAll()); file->write(reply->readAll());
}); });
loop->exec(); loop.exec();
if (reply->error() == QNetworkReply::NoError) { if (reply->error() == QNetworkReply::NoError) {
Q_EMIT success(path); Q_EMIT success(path);
}else{ }else{
Q_EMIT error(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString()); Q_EMIT error(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString());
} }
file->close(); file->close();
loop->deleteLater();
file->deleteLater(); file->deleteLater();
reply->deleteLater(); reply->deleteLater();
loop = nullptr;
file = nullptr; file = nullptr;
reply = nullptr; reply = nullptr;
Q_EMIT finish(); Q_EMIT finish();

View File

@ -11,6 +11,8 @@ class FluHttp : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(QString,url); Q_PROPERTY_AUTO(QString,url);
Q_PROPERTY_AUTO(int,retry);
Q_PROPERTY_AUTO(int,timeout)
QML_NAMED_ELEMENT(FluHttp) QML_NAMED_ELEMENT(FluHttp)
private: private:
QVariant invokeIntercept(const QVariant& params,const QVariant& headers,const QString& method); QVariant invokeIntercept(const QVariant& params,const QVariant& headers,const QString& method);
@ -27,6 +29,8 @@ public:
Q_SIGNAL void downloadProgress(qint64 recv, qint64 total); Q_SIGNAL void downloadProgress(qint64 recv, qint64 total);
Q_INVOKABLE void get(QVariantMap params = {},QVariantMap headers = {}); Q_INVOKABLE void get(QVariantMap params = {},QVariantMap headers = {});
Q_INVOKABLE void post(QVariantMap params = {},QVariantMap headers = {}); Q_INVOKABLE void post(QVariantMap params = {},QVariantMap headers = {});
Q_INVOKABLE void postString(QString params = "",QVariantMap headers = {});
Q_INVOKABLE void postJson(QVariantMap params = {},QVariantMap headers = {});
Q_INVOKABLE void download(QString path,QVariantMap params = {},QVariantMap headers = {}); Q_INVOKABLE void download(QString path,QVariantMap params = {},QVariantMap headers = {});
Q_INVOKABLE void cancel(); Q_INVOKABLE void cancel();
private: private: