mirror of
https://github.com/zhuzichu520/FluentUI.git
synced 2025-07-03 00:25:25 +08:00
remove FluHttp
This commit is contained in:
12
src/Def.h
12
src/Def.h
@ -14,18 +14,6 @@ Q_ENUM_NS(Scope)
|
||||
QML_NAMED_ELEMENT(FluViewModelType)
|
||||
}
|
||||
|
||||
namespace FluHttpType {
|
||||
Q_NAMESPACE
|
||||
enum CacheMode {
|
||||
NoCache = 0x0000,
|
||||
RequestFailedReadCache = 0x0001,
|
||||
IfNoneCacheRequest = 0x0002,
|
||||
FirstCacheThenRequest = 0x0004,
|
||||
};
|
||||
Q_ENUM_NS(CacheMode)
|
||||
QML_NAMED_ELEMENT(FluHttpType)
|
||||
}
|
||||
|
||||
namespace FluNetworkType {
|
||||
Q_NAMESPACE
|
||||
enum CacheMode {
|
||||
|
@ -16,7 +16,6 @@ FRAMELESSHELPER_USE_NAMESPACE
|
||||
FluApp::FluApp(QObject *parent):QObject{parent}{
|
||||
connect(this,&FluApp::useSystemAppBarChanged,this,[=]{FramelessConfig::instance()->set(Global::Option::UseSystemAppBar,_useSystemAppBar);});
|
||||
vsync(true);
|
||||
httpInterceptor(nullptr);
|
||||
useSystemAppBar(false);
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <QJsonObject>
|
||||
#include <QQmlEngine>
|
||||
#include "FluRegister.h"
|
||||
#include "FluHttpInterceptor.h"
|
||||
#include "stdafx.h"
|
||||
#include "singleton.h"
|
||||
|
||||
@ -22,7 +21,6 @@ class FluApp : public QObject
|
||||
Q_PROPERTY_AUTO(bool,vsync)
|
||||
Q_PROPERTY_AUTO(QString,initialRoute);
|
||||
Q_PROPERTY_AUTO(QJsonObject,routes);
|
||||
Q_PROPERTY_AUTO(FluHttpInterceptor*,httpInterceptor);
|
||||
Q_PROPERTY_AUTO(bool,useSystemAppBar);
|
||||
QML_NAMED_ELEMENT(FluApp)
|
||||
QML_SINGLETON
|
||||
|
681
src/FluHttp.cpp
681
src/FluHttp.cpp
@ -1,681 +0,0 @@
|
||||
#include "FluHttp.h"
|
||||
|
||||
#include <QThreadPool>
|
||||
#include <QEventLoop>
|
||||
#include <QNetworkReply>
|
||||
#include <QUrlQuery>
|
||||
#include <QHttpMultiPart>
|
||||
#include <QGuiApplication>
|
||||
#include <QJsonDocument>
|
||||
#include <QStandardPaths>
|
||||
#include <QTextStream>
|
||||
#include <QDir>
|
||||
#include "Def.h"
|
||||
#include "FluApp.h"
|
||||
#include "FluTools.h"
|
||||
|
||||
HttpRequest::HttpRequest(QObject *parent):QObject{parent}{
|
||||
}
|
||||
|
||||
QMap<QString, QVariant> HttpRequest::toMap(){
|
||||
QVariant _params;
|
||||
bool isPostString = method() == "postString";
|
||||
if(params().isNull()){
|
||||
if(isPostString){
|
||||
_params = "";
|
||||
}else{
|
||||
_params = QMap<QString,QVariant>();
|
||||
}
|
||||
}else{
|
||||
_params = params();
|
||||
}
|
||||
QVariant _headers;
|
||||
if(headers().isNull()){
|
||||
_headers = QMap<QString,QVariant>();
|
||||
}else{
|
||||
_headers = headers();
|
||||
}
|
||||
QMap<QString, QVariant> request = {
|
||||
{"url",url()},
|
||||
{"headers",_headers.toMap()},
|
||||
{"method",method()},
|
||||
{"downloadSavePath",downloadSavePath()}
|
||||
};
|
||||
if(isPostString){
|
||||
request.insert("params",_params.toString());
|
||||
}else{
|
||||
request.insert("params",_params.toMap());
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
QString HttpRequest::httpId(){
|
||||
return FluTools::getInstance()->sha256(QJsonDocument::fromVariant(QVariant(toMap())).toJson(QJsonDocument::Compact));
|
||||
}
|
||||
|
||||
HttpCallable::HttpCallable(QObject *parent):QObject{parent}{
|
||||
}
|
||||
|
||||
FluHttp::FluHttp(QObject *parent):QObject{parent}{
|
||||
retry(3);
|
||||
timeout(15000);
|
||||
cacheMode(FluHttpType::CacheMode::NoCache);
|
||||
cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)+"/httpcache");
|
||||
breakPointDownload(false);
|
||||
}
|
||||
|
||||
FluHttp::~FluHttp(){
|
||||
cancel();
|
||||
}
|
||||
|
||||
void FluHttp::cancel(){
|
||||
foreach (QPointer<QNetworkReply> item, _cacheReply) {
|
||||
if(item){
|
||||
item->abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FluHttp::post(HttpRequest* r,HttpCallable* c){
|
||||
auto request = QPointer(r);
|
||||
auto callable = QPointer(c);
|
||||
request->method("post");
|
||||
auto requestMap = request->toMap();
|
||||
auto httpId = request->httpId();
|
||||
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
|
||||
QThreadPool::globalInstance()->start([=](){
|
||||
onStart(callable);
|
||||
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){
|
||||
onCache(callable,readCache(httpId));
|
||||
onFinish(callable,request);
|
||||
return;
|
||||
}
|
||||
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){
|
||||
onCache(callable,readCache(httpId));
|
||||
}
|
||||
QNetworkAccessManager manager;
|
||||
manager.setTransferTimeout(timeout());
|
||||
for (int i = 0; i < retry(); ++i) {
|
||||
QUrl url(request->url());
|
||||
QNetworkRequest req(url);
|
||||
addHeaders(&req,data["headers"].toMap());
|
||||
QHttpMultiPart multiPart(QHttpMultiPart::FormDataType);
|
||||
for (const auto& each : data["params"].toMap().toStdMap())
|
||||
{
|
||||
const QString& key = each.first;
|
||||
const QString& value = each.second.toString();
|
||||
QString dispositionHeader = QString("form-data; name=\"%1\"").arg(key);
|
||||
QHttpPart part;
|
||||
part.setHeader(QNetworkRequest::ContentDispositionHeader, dispositionHeader);
|
||||
part.setBody(value.toUtf8());
|
||||
multiPart.append(part);
|
||||
}
|
||||
QNetworkReply* reply = manager.post(req,&multiPart);
|
||||
if(!QPointer(qApp)){
|
||||
reply->deleteLater();
|
||||
reply = nullptr;
|
||||
return;
|
||||
}
|
||||
_cacheReply.append(reply);
|
||||
QEventLoop loop;
|
||||
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
||||
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
|
||||
loop.exec();
|
||||
QString result = QString::fromUtf8(reply->readAll());
|
||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
QString errorString = reply->errorString();
|
||||
QNetworkReply::NetworkError error = reply->error();
|
||||
bool isSuccess = error == QNetworkReply::NoError;
|
||||
reply->deleteLater();
|
||||
reply = nullptr;
|
||||
if (isSuccess) {
|
||||
handleCache(httpId,result);
|
||||
onSuccess(callable,result);
|
||||
break;
|
||||
}else{
|
||||
if(i == retry()-1){
|
||||
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){
|
||||
onCache(callable,readCache(httpId));
|
||||
}
|
||||
onError(callable,status,errorString,result);
|
||||
}
|
||||
}
|
||||
if(error == QNetworkReply::OperationCanceledError){
|
||||
break;
|
||||
}
|
||||
}
|
||||
onFinish(callable,request);
|
||||
});
|
||||
}
|
||||
|
||||
void FluHttp::postString(HttpRequest* r,HttpCallable* c){
|
||||
auto request = QPointer(r);
|
||||
auto callable = QPointer(c);
|
||||
request->method("postString");
|
||||
auto requestMap = request->toMap();
|
||||
auto httpId = request->httpId();
|
||||
QString params = request->params().toString();
|
||||
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
|
||||
QThreadPool::globalInstance()->start([=](){
|
||||
onStart(callable);
|
||||
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){
|
||||
onCache(callable,readCache(httpId));
|
||||
onFinish(callable,request);
|
||||
return;
|
||||
}
|
||||
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){
|
||||
onCache(callable,readCache(httpId));
|
||||
}
|
||||
QNetworkAccessManager manager;
|
||||
manager.setTransferTimeout(timeout());
|
||||
for (int i = 0; i < retry(); ++i) {
|
||||
QUrl url(request->url());
|
||||
QNetworkRequest req(url);
|
||||
addHeaders(&req,data["headers"].toMap());
|
||||
QString contentType = QString("text/plain;charset=utf-8");
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
|
||||
QNetworkReply* reply = manager.post(req,params.toUtf8());
|
||||
if(!QPointer(qApp)){
|
||||
reply->deleteLater();
|
||||
reply = nullptr;
|
||||
return;
|
||||
}
|
||||
_cacheReply.append(reply);
|
||||
QEventLoop loop;
|
||||
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
||||
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
|
||||
loop.exec();
|
||||
QString result = QString::fromUtf8(reply->readAll());
|
||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
QString errorString = reply->errorString();
|
||||
QNetworkReply::NetworkError error = reply->error();
|
||||
bool isSuccess = error == QNetworkReply::NoError;
|
||||
reply->deleteLater();
|
||||
reply = nullptr;
|
||||
if (isSuccess) {
|
||||
handleCache(httpId,result);
|
||||
onSuccess(callable,result);
|
||||
break;
|
||||
}else{
|
||||
if(i == retry()-1){
|
||||
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){
|
||||
onCache(callable,readCache(httpId));
|
||||
}
|
||||
onError(callable,status,errorString,result);
|
||||
}
|
||||
}
|
||||
if(error == QNetworkReply::OperationCanceledError){
|
||||
break;
|
||||
}
|
||||
}
|
||||
onFinish(callable,request);
|
||||
});
|
||||
}
|
||||
|
||||
void FluHttp::postJson(HttpRequest* r,HttpCallable* c){
|
||||
auto request = QPointer(r);
|
||||
auto callable = QPointer(c);
|
||||
request->method("postJson");
|
||||
auto requestMap = request->toMap();
|
||||
auto httpId = request->httpId();
|
||||
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
|
||||
QThreadPool::globalInstance()->start([=](){
|
||||
onStart(callable);
|
||||
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){
|
||||
onCache(callable,readCache(httpId));
|
||||
onFinish(callable,request);
|
||||
return;
|
||||
}
|
||||
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){
|
||||
onCache(callable,readCache(httpId));
|
||||
}
|
||||
QNetworkAccessManager manager;
|
||||
manager.setTransferTimeout(timeout());
|
||||
for (int i = 0; i < retry(); ++i) {
|
||||
QUrl url(request->url());
|
||||
QNetworkRequest req(url);
|
||||
addHeaders(&req,data["headers"].toMap());
|
||||
QString contentType = QString("application/json;charset=utf-8");
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader, contentType);
|
||||
QNetworkReply* reply = manager.post(req,QJsonDocument::fromVariant(data["params"]).toJson());
|
||||
if(!QPointer(qApp)){
|
||||
reply->deleteLater();
|
||||
reply = nullptr;
|
||||
return;
|
||||
}
|
||||
_cacheReply.append(reply);
|
||||
QEventLoop loop;
|
||||
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
||||
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
|
||||
loop.exec();
|
||||
QString result = QString::fromUtf8(reply->readAll());
|
||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
QString errorString = reply->errorString();
|
||||
QNetworkReply::NetworkError error = reply->error();
|
||||
bool isSuccess = error == QNetworkReply::NoError;
|
||||
reply->deleteLater();
|
||||
reply = nullptr;
|
||||
if (isSuccess) {
|
||||
handleCache(httpId,result);
|
||||
onSuccess(callable,result);
|
||||
break;
|
||||
}else{
|
||||
if(i == retry()-1){
|
||||
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){
|
||||
onCache(callable,readCache(httpId));
|
||||
}
|
||||
onError(callable,status,errorString,result);
|
||||
}
|
||||
}
|
||||
if(error == QNetworkReply::OperationCanceledError){
|
||||
break;
|
||||
}
|
||||
}
|
||||
onFinish(callable,request);
|
||||
});
|
||||
}
|
||||
|
||||
void FluHttp::get(HttpRequest* r,HttpCallable* c){
|
||||
auto request = QPointer(r);
|
||||
auto callable = QPointer(c);
|
||||
request->method("get");
|
||||
auto requestMap = request->toMap();
|
||||
auto httpId = request->httpId();
|
||||
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
|
||||
QThreadPool::globalInstance()->start([=](){
|
||||
onStart(callable);
|
||||
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){
|
||||
onCache(callable,readCache(httpId));
|
||||
}
|
||||
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){
|
||||
onCache(callable,readCache(httpId));
|
||||
onFinish(callable,request);
|
||||
return;
|
||||
}
|
||||
QNetworkAccessManager manager;
|
||||
manager.setTransferTimeout(timeout());
|
||||
for (int i = 0; i < retry(); ++i) {
|
||||
QUrl url(request->url());
|
||||
addQueryParam(&url,data["params"].toMap());
|
||||
QNetworkRequest req(url);
|
||||
addHeaders(&req,data["headers"].toMap());
|
||||
QNetworkReply* reply = manager.get(req);
|
||||
if(!QPointer(qApp)){
|
||||
reply->deleteLater();
|
||||
reply = nullptr;
|
||||
return;
|
||||
}
|
||||
_cacheReply.append(reply);
|
||||
QEventLoop loop;
|
||||
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
||||
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
|
||||
loop.exec();
|
||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
QString errorString = reply->errorString();
|
||||
QNetworkReply::NetworkError error = reply->error();
|
||||
bool isSuccess = error == QNetworkReply::NoError;
|
||||
QString result = QString::fromUtf8(reply->readAll());
|
||||
if (isSuccess) {
|
||||
handleCache(httpId,result);
|
||||
onSuccess(callable,result);
|
||||
break;
|
||||
}else{
|
||||
if(i == retry()-1){
|
||||
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){
|
||||
onCache(callable,readCache(httpId));
|
||||
}
|
||||
onError(callable,status,errorString,result);
|
||||
}
|
||||
}
|
||||
reply->deleteLater();
|
||||
reply = nullptr;
|
||||
if(error == QNetworkReply::OperationCanceledError){
|
||||
break;
|
||||
}
|
||||
}
|
||||
onFinish(callable,request);
|
||||
});
|
||||
}
|
||||
|
||||
void FluHttp::download(HttpRequest* r,HttpCallable* c){
|
||||
auto request = QPointer(r);
|
||||
auto callable = QPointer(c);
|
||||
request->method("download");
|
||||
auto requestMap = request->toMap();
|
||||
auto httpId = request->httpId();
|
||||
auto savePath = request->downloadSavePath();
|
||||
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
|
||||
QThreadPool::globalInstance()->start([=](){
|
||||
onStart(callable);
|
||||
QNetworkAccessManager manager;
|
||||
QUrl url(request->url());
|
||||
addQueryParam(&url,data["params"].toMap());
|
||||
QNetworkRequest req(url);
|
||||
addHeaders(&req,data["headers"].toMap());
|
||||
QSharedPointer<QFile> file(new QFile(savePath));
|
||||
QDir dir = QFileInfo(savePath).path();
|
||||
if (!dir.exists(dir.path())){
|
||||
dir.mkpath(dir.path());
|
||||
}
|
||||
qint64 seek = 0;
|
||||
auto filePath = getCacheFilePath(httpId);
|
||||
QSharedPointer<QFile> fileCache(new QFile(filePath));
|
||||
if(fileCache->exists() && file->exists() && _breakPointDownload){
|
||||
QJsonObject cacheInfo = QJsonDocument::fromJson(readCache(httpId).toUtf8()).object();
|
||||
qint64 fileSize = cacheInfo.value("fileSize").toDouble();
|
||||
qint64 contentLength = cacheInfo.value("contentLength").toDouble();
|
||||
if(fileSize == contentLength && file->size() == contentLength){
|
||||
onDownloadProgress(callable,fileSize,contentLength);
|
||||
onSuccess(callable,savePath);
|
||||
onFinish(callable,request);
|
||||
return;
|
||||
}
|
||||
if(fileSize==file->size()){
|
||||
req.setRawHeader("Range", QString("bytes=%1-").arg(fileSize).toUtf8());
|
||||
seek = fileSize;
|
||||
file->open(QIODevice::WriteOnly|QIODevice::Append);
|
||||
}else{
|
||||
file->open(QIODevice::WriteOnly|QIODevice::Truncate);
|
||||
}
|
||||
}else{
|
||||
file->open(QIODevice::WriteOnly|QIODevice::Truncate);
|
||||
}
|
||||
QNetworkReply* reply = manager.get(req);
|
||||
if(!QPointer(qApp)){
|
||||
reply->deleteLater();
|
||||
reply = nullptr;
|
||||
return;
|
||||
}
|
||||
_cacheReply.append(reply);
|
||||
QEventLoop loop;
|
||||
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
||||
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
|
||||
if (!fileCache->open(QIODevice::WriteOnly|QIODevice::Truncate))
|
||||
{
|
||||
qDebug()<<"FileCache Error";
|
||||
}
|
||||
connect(reply,&QNetworkReply::readyRead,reply,[reply,file,fileCache,requestMap,callable,seek,this]{
|
||||
if (!reply || !file || reply->error() != QNetworkReply::NoError)
|
||||
{
|
||||
return;
|
||||
}
|
||||
QMap<QString, QVariant> downMap = requestMap;
|
||||
qint64 contentLength = reply->header(QNetworkRequest::ContentLengthHeader).toLongLong()+seek;
|
||||
downMap.insert("contentLength",contentLength);
|
||||
QString eTag = reply->header(QNetworkRequest::ETagHeader).toString();
|
||||
downMap.insert("eTag",eTag);
|
||||
file->write(reply->readAll());
|
||||
file->flush();
|
||||
downMap.insert("fileSize",file->size());
|
||||
fileCache->resize(0);
|
||||
fileCache->write(FluTools::getInstance()->toBase64(QJsonDocument::fromVariant(QVariant(downMap)).toJson()).toUtf8());
|
||||
fileCache->flush();
|
||||
onDownloadProgress(callable,file->size(),contentLength);
|
||||
});
|
||||
loop.exec();
|
||||
if (reply->error() == QNetworkReply::NoError) {
|
||||
onSuccess(callable,savePath);
|
||||
}else{
|
||||
onError(callable,reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(),reply->errorString(),"");
|
||||
}
|
||||
reply->deleteLater();
|
||||
reply = nullptr;
|
||||
onFinish(callable,request);
|
||||
});
|
||||
}
|
||||
|
||||
void FluHttp::upload(HttpRequest* request,HttpCallable* callable){
|
||||
request->method("upload");
|
||||
auto requestMap = request->toMap();
|
||||
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
|
||||
QThreadPool::globalInstance()->start([=](){
|
||||
onStart(callable);
|
||||
QNetworkAccessManager manager;
|
||||
manager.setTransferTimeout(timeout());
|
||||
QUrl url(request->url());
|
||||
QNetworkRequest req(url);
|
||||
addHeaders(&req,data["headers"].toMap());
|
||||
QHttpMultiPart multiPart(QHttpMultiPart::FormDataType);
|
||||
for (const auto& each : data["params"].toMap().toStdMap())
|
||||
{
|
||||
const QString& key = each.first;
|
||||
const QString& filePath = each.second.toString();
|
||||
QFile *file = new QFile(filePath);
|
||||
file->open(QIODevice::ReadOnly);
|
||||
file->setParent(&multiPart);
|
||||
QString dispositionHeader = QString("form-data; name=\"%1\"; filename=\"%2\"").arg(key,filePath);
|
||||
QHttpPart part;
|
||||
part.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
|
||||
part.setHeader(QNetworkRequest::ContentDispositionHeader, dispositionHeader);
|
||||
part.setBodyDevice(file);
|
||||
multiPart.append(part);
|
||||
}
|
||||
QNetworkReply* reply = manager.post(req,&multiPart);
|
||||
if(!QPointer(qApp)){
|
||||
reply->deleteLater();
|
||||
reply = nullptr;
|
||||
return;
|
||||
}
|
||||
_cacheReply.append(reply);
|
||||
QEventLoop loop;
|
||||
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
||||
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop,reply](){reply->abort(),loop.quit();});
|
||||
connect(reply,&QNetworkReply::uploadProgress,reply,[=](qint64 bytesSent, qint64 bytesTotal){
|
||||
onUploadProgress(callable,bytesSent,bytesTotal);
|
||||
});
|
||||
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) {
|
||||
onSuccess(callable,result);
|
||||
}else{
|
||||
onError(callable,status,errorString,result);
|
||||
}
|
||||
onFinish(callable,request);
|
||||
});
|
||||
}
|
||||
|
||||
void FluHttp::deleteResource(HttpRequest* request,HttpCallable* callable)
|
||||
{
|
||||
request->method("deleteResource");
|
||||
auto requestMap = request->toMap();
|
||||
auto httpId = request->httpId();
|
||||
QMap<QString, QVariant> data = invokeIntercept(requestMap).toMap();
|
||||
QThreadPool::globalInstance()->start([=](){
|
||||
onStart(callable);
|
||||
if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){
|
||||
onCache(callable,readCache(httpId));
|
||||
}
|
||||
if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){
|
||||
onCache(callable,readCache(httpId));
|
||||
onFinish(callable,request);
|
||||
return;
|
||||
}
|
||||
QNetworkAccessManager manager;
|
||||
manager.setTransferTimeout(timeout());
|
||||
for (int i = 0; i < retry(); ++i) {
|
||||
QUrl url(request->url());
|
||||
addQueryParam(&url,data["params"].toMap());
|
||||
QNetworkRequest req(url);
|
||||
addHeaders(&req,data["headers"].toMap());
|
||||
QEventLoop loop;
|
||||
QNetworkReply* reply = manager.deleteResource(req);
|
||||
_cacheReply.append(reply);
|
||||
connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){loop.quit();});
|
||||
connect(qApp,&QGuiApplication::aboutToQuit,&manager, [&loop](){loop.quit();});
|
||||
loop.exec();
|
||||
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
QString errorString = reply->errorString();
|
||||
bool isSuccess = reply->error() == QNetworkReply::NoError;
|
||||
QString result = QString::fromUtf8(reply->readAll());
|
||||
if (isSuccess) {
|
||||
handleCache(httpId,result);
|
||||
onSuccess(callable,result);
|
||||
break;
|
||||
}else{
|
||||
if(i == retry()-1){
|
||||
if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){
|
||||
onCache(callable,readCache(httpId));
|
||||
}
|
||||
onError(callable,status,errorString,result);
|
||||
}
|
||||
}
|
||||
QNetworkReply::NetworkError error = reply->error();
|
||||
if(error == QNetworkReply::OperationCanceledError){
|
||||
break;
|
||||
}
|
||||
reply->deleteLater();
|
||||
reply = nullptr;
|
||||
}
|
||||
onFinish(callable,request);
|
||||
});
|
||||
}
|
||||
|
||||
QVariant FluHttp::invokeIntercept(QMap<QString, QVariant> request){
|
||||
if(!FluApp::getInstance()->httpInterceptor()){
|
||||
return request;
|
||||
}
|
||||
QVariant target;
|
||||
QMetaObject::invokeMethod(FluApp::getInstance()->httpInterceptor(), "onIntercept",Q_RETURN_ARG(QVariant,target),Q_ARG(QVariant, request));
|
||||
return target;
|
||||
}
|
||||
|
||||
void FluHttp::addQueryParam(QUrl* url,const QMap<QString, QVariant>& params){
|
||||
QMapIterator<QString, QVariant> iter(params);
|
||||
QUrlQuery urlQuery(*url);
|
||||
while (iter.hasNext())
|
||||
{
|
||||
iter.next();
|
||||
urlQuery.addQueryItem(iter.key(), iter.value().toString());
|
||||
}
|
||||
url->setQuery(urlQuery);
|
||||
}
|
||||
|
||||
void FluHttp::addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& headers){
|
||||
QMapIterator<QString, QVariant> iter(headers);
|
||||
while (iter.hasNext())
|
||||
{
|
||||
iter.next();
|
||||
request->setRawHeader(iter.key().toUtf8(), iter.value().toString().toUtf8());
|
||||
}
|
||||
}
|
||||
|
||||
QString FluHttp::readCache(const QString& httpId){
|
||||
auto filePath = getCacheFilePath(httpId);
|
||||
QString result;
|
||||
QFile file(filePath);
|
||||
if(!file.exists()){
|
||||
return result;
|
||||
}
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
QTextStream stream(&file);
|
||||
result = FluTools::getInstance()->fromBase64(stream.readAll().toUtf8());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool FluHttp::cacheExists(const QString& httpId){
|
||||
return QFile(getCacheFilePath(httpId)).exists();
|
||||
}
|
||||
|
||||
QString FluHttp::getCacheFilePath(const QString& httpId){
|
||||
QString path = FluTools::getInstance()->toLocalPath(QUrl(_cacheDir));
|
||||
QDir dir = path;
|
||||
if (!dir.exists(path)){
|
||||
dir.mkpath(path);
|
||||
}
|
||||
auto filePath = path+"/"+httpId;
|
||||
return filePath;
|
||||
}
|
||||
|
||||
void FluHttp::handleCache(const QString& httpId,const QString& result){
|
||||
if(_cacheMode==FluHttpType::CacheMode::NoCache){
|
||||
return;
|
||||
}
|
||||
auto filePath = getCacheFilePath(httpId);
|
||||
QSharedPointer<QFile> file(new QFile(filePath));
|
||||
QIODevice::OpenMode mode = QIODevice::WriteOnly|QIODevice::Truncate;
|
||||
if (!file->open(mode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
file->write(FluTools::getInstance()->toBase64(result).toUtf8());
|
||||
}
|
||||
|
||||
qreal FluHttp::getBreakPointProgress(HttpRequest* request){
|
||||
request->method("download");
|
||||
auto httpId = request->httpId();
|
||||
QSharedPointer<QFile> file(new QFile(request->downloadSavePath()));
|
||||
auto filePath = getCacheFilePath(httpId);
|
||||
QSharedPointer<QFile> fileCache(new QFile(filePath));
|
||||
if(fileCache->exists() && file->exists() && _breakPointDownload){
|
||||
QJsonObject cacheInfo = QJsonDocument::fromJson(readCache(httpId).toUtf8()).object();
|
||||
double fileSize = cacheInfo.value("fileSize").toDouble();
|
||||
double contentLength = cacheInfo.value("contentLength").toDouble();
|
||||
if(fileSize == contentLength && file->size() == contentLength){
|
||||
return 1;
|
||||
}
|
||||
if(fileSize==file->size()){
|
||||
return fileSize/contentLength;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
HttpRequest* FluHttp::newRequest(QString url){
|
||||
HttpRequest* request = new HttpRequest(this);
|
||||
request->url(url);
|
||||
return request;
|
||||
}
|
||||
|
||||
void FluHttp::onStart(QPointer<HttpCallable> callable){
|
||||
if (!callable.isNull()) {
|
||||
Q_EMIT callable->start();
|
||||
}
|
||||
}
|
||||
|
||||
void FluHttp::onFinish(QPointer<HttpCallable> callable,QPointer<HttpRequest> request){
|
||||
if (!callable.isNull()) {
|
||||
Q_EMIT callable->finish();
|
||||
}
|
||||
if(request&&request->parent()->inherits("FluHttp")){
|
||||
request->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void FluHttp::onError(QPointer<HttpCallable> callable,int status,QString errorString,QString result){
|
||||
if (!callable.isNull()) {
|
||||
Q_EMIT callable->error(status,errorString,result);
|
||||
}
|
||||
}
|
||||
|
||||
void FluHttp::onSuccess(QPointer<HttpCallable> callable,QString result){
|
||||
if (!callable.isNull()) {
|
||||
Q_EMIT callable->success(result);
|
||||
}
|
||||
}
|
||||
|
||||
void FluHttp::onCache(QPointer<HttpCallable> callable,QString result){
|
||||
if (!callable.isNull()) {
|
||||
Q_EMIT callable->cache(result);
|
||||
}
|
||||
}
|
||||
|
||||
void FluHttp::onDownloadProgress(QPointer<HttpCallable> callable,qint64 recv,qint64 total){
|
||||
if (!callable.isNull()) {
|
||||
Q_EMIT callable->downloadProgress(recv,total);
|
||||
}
|
||||
}
|
||||
|
||||
void FluHttp::onUploadProgress(QPointer<HttpCallable> callable,qint64 sent,qint64 total){
|
||||
if (!callable.isNull()) {
|
||||
Q_EMIT callable->uploadProgress(sent,total);
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
#ifndef FLUHTTP_H
|
||||
#define FLUHTTP_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QtQml/qqml.h>
|
||||
#include <QFile>
|
||||
#include <QJsonValue>
|
||||
#include <QNetworkAccessManager>
|
||||
#include "stdafx.h"
|
||||
|
||||
class HttpRequest : public QObject{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(QString,url);
|
||||
# if (QT_VERSION == QT_VERSION_CHECK(6, 4, 3))
|
||||
Q_PROPERTY_AUTO(QJsonValue,params);
|
||||
Q_PROPERTY_AUTO(QJsonValue,headers);
|
||||
# else
|
||||
Q_PROPERTY_AUTO(QVariant,params);
|
||||
Q_PROPERTY_AUTO(QVariant,headers);
|
||||
# endif
|
||||
Q_PROPERTY_AUTO(QString,method);
|
||||
Q_PROPERTY_AUTO(QString,downloadSavePath);
|
||||
QML_NAMED_ELEMENT(HttpRequest)
|
||||
public:
|
||||
explicit HttpRequest(QObject *parent = nullptr);
|
||||
QMap<QString, QVariant> toMap();
|
||||
Q_INVOKABLE QString httpId();
|
||||
};
|
||||
|
||||
class HttpCallable : public QObject{
|
||||
Q_OBJECT
|
||||
QML_NAMED_ELEMENT(HttpCallable)
|
||||
public:
|
||||
explicit HttpCallable(QObject *parent = nullptr);
|
||||
Q_SIGNAL void start();
|
||||
Q_SIGNAL void finish();
|
||||
Q_SIGNAL void error(int status,QString errorString,QString result);
|
||||
Q_SIGNAL void success(QString result);
|
||||
Q_SIGNAL void cache(QString result);
|
||||
Q_SIGNAL void downloadProgress(qint64 recv, qint64 total);
|
||||
Q_SIGNAL void uploadProgress(qint64 sent, qint64 total);
|
||||
};
|
||||
|
||||
class FluHttp : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY_AUTO(int,retry);
|
||||
Q_PROPERTY_AUTO(int,timeout)
|
||||
Q_PROPERTY_AUTO(int,cacheMode);
|
||||
Q_PROPERTY_AUTO(QString,cacheDir);
|
||||
Q_PROPERTY_AUTO(bool,breakPointDownload);
|
||||
QML_NAMED_ELEMENT(FluHttp)
|
||||
private:
|
||||
QVariant invokeIntercept(QMap<QString, QVariant> request);
|
||||
void addQueryParam(QUrl* url,const QMap<QString, QVariant>& params);
|
||||
void addHeaders(QNetworkRequest* request,const QMap<QString, QVariant>& params);
|
||||
void handleCache(const QString& httpId, const QString& result);
|
||||
QString readCache(const QString& httpId);
|
||||
bool cacheExists(const QString& httpId);
|
||||
QString getCacheFilePath(const QString& httpId);
|
||||
void onStart(QPointer<HttpCallable> callable);
|
||||
void onFinish(QPointer<HttpCallable> callable,QPointer<HttpRequest> request);
|
||||
void onError(QPointer<HttpCallable> callable,int status,QString errorString,QString result);
|
||||
void onSuccess(QPointer<HttpCallable> callable,QString result);
|
||||
void onCache(QPointer<HttpCallable> callable,QString result);
|
||||
void onDownloadProgress(QPointer<HttpCallable> callable,qint64 recv,qint64 total);
|
||||
void onUploadProgress(QPointer<HttpCallable> callable,qint64 sent,qint64 total);
|
||||
public:
|
||||
explicit FluHttp(QObject *parent = nullptr);
|
||||
~FluHttp();
|
||||
Q_INVOKABLE HttpRequest* newRequest(QString url = "");
|
||||
Q_INVOKABLE void get(HttpRequest* request,HttpCallable* callable);
|
||||
Q_INVOKABLE void post(HttpRequest* request,HttpCallable* callable);
|
||||
Q_INVOKABLE void postString(HttpRequest* request,HttpCallable* callable);
|
||||
Q_INVOKABLE void postJson(HttpRequest* request,HttpCallable* callable);
|
||||
Q_INVOKABLE void download(HttpRequest* request,HttpCallable* callable);
|
||||
Q_INVOKABLE void upload(HttpRequest* request,HttpCallable* callable);
|
||||
Q_INVOKABLE void deleteResource(HttpRequest* request,HttpCallable* callable);
|
||||
Q_INVOKABLE qreal getBreakPointProgress(HttpRequest* request);
|
||||
Q_INVOKABLE void cancel();
|
||||
private:
|
||||
QList<QPointer<QNetworkReply>> _cacheReply;
|
||||
};
|
||||
|
||||
#endif // FLUHTTP_H
|
@ -1,4 +0,0 @@
|
||||
#include "FluHttpInterceptor.h"
|
||||
|
||||
FluHttpInterceptor::FluHttpInterceptor(QObject *parent):QObject{parent}{
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
#ifndef FLUHTTPINTERCEPTOR_H
|
||||
#define FLUHTTPINTERCEPTOR_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QtQml/qqml.h>
|
||||
|
||||
class FluHttpInterceptor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_NAMED_ELEMENT(FluHttpInterceptor)
|
||||
public:
|
||||
explicit FluHttpInterceptor(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
#endif // FLUHTTPINTERCEPTOR_H
|
@ -121,19 +121,22 @@ NetworkParams* NetworkParams::toDownload(QString destPath,bool append){
|
||||
return this;
|
||||
}
|
||||
|
||||
NetworkParams* NetworkParams::bind(QObject* target){
|
||||
_target = target;
|
||||
return this;
|
||||
}
|
||||
|
||||
QString NetworkParams::buildCacheKey(){
|
||||
QJsonObject obj;
|
||||
obj.insert("url",_url);
|
||||
obj.insert("method",method2String());
|
||||
obj.insert("body",_body);
|
||||
obj.insert("query",QString(QJsonDocument::fromVariant(_queryMap).toJson(QJsonDocument::Compact)));
|
||||
obj.insert("param",QString(QJsonDocument::fromVariant(_paramMap).toJson(QJsonDocument::Compact)));
|
||||
obj.insert("header",QString(QJsonDocument::fromVariant(_headerMap).toJson(QJsonDocument::Compact)));
|
||||
obj.insert("file",QString(QJsonDocument::fromVariant(_fileMap).toJson(QJsonDocument::Compact)));
|
||||
obj.insert("query",QJsonDocument::fromVariant(_queryMap).object());
|
||||
obj.insert("param",QJsonDocument::fromVariant(_paramMap).object());
|
||||
obj.insert("header",QJsonDocument::fromVariant(_headerMap).object());
|
||||
obj.insert("file",QJsonDocument::fromVariant(_fileMap).object());
|
||||
if(_downloadParam){
|
||||
QJsonObject downObj;
|
||||
QString _destPath;
|
||||
bool _append;
|
||||
downObj.insert("destPath",_downloadParam->_destPath);
|
||||
downObj.insert("append",_downloadParam->_append);
|
||||
obj.insert("download",downObj);
|
||||
@ -275,10 +278,16 @@ void FluNetwork::handleDownload(NetworkParams* params,NetworkCallable* c){
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
reply = manager->get(request);
|
||||
destFile->setParent(reply);
|
||||
cacheFile->setParent(reply);
|
||||
if(params->_target){
|
||||
connect(params->_target,&QObject::destroyed,this,[reply]{
|
||||
if(reply){
|
||||
reply->abort();
|
||||
}
|
||||
});
|
||||
}
|
||||
connect(reply,&QNetworkReply::readyRead,reply,[reply,seek,destFile,cacheFile,callable]{
|
||||
if (!reply || !destFile || reply->error() != QNetworkReply::NoError)
|
||||
{
|
||||
|
@ -66,6 +66,7 @@ public:
|
||||
Q_INVOKABLE NetworkParams* setRetry(int val);
|
||||
Q_INVOKABLE NetworkParams* setCacheMode(int val);
|
||||
Q_INVOKABLE NetworkParams* toDownload(QString destPath,bool append = false);
|
||||
Q_INVOKABLE NetworkParams* bind(QObject* target);
|
||||
Q_INVOKABLE void go(NetworkCallable* result);
|
||||
QString buildCacheKey();
|
||||
QString method2String();
|
||||
@ -73,6 +74,7 @@ public:
|
||||
int getRetry();
|
||||
public:
|
||||
DownloadParam* _downloadParam = nullptr;
|
||||
QObject* _target = nullptr;
|
||||
Method _method;
|
||||
Type _type;
|
||||
QString _url;
|
||||
|
@ -8,8 +8,6 @@
|
||||
#include "FluTheme.h"
|
||||
#include "FluTools.h"
|
||||
#include "FluTextStyle.h"
|
||||
#include "FluHttp.h"
|
||||
#include "FluHttpInterceptor.h"
|
||||
#include "FluWatermark.h"
|
||||
#include "FluCaptcha.h"
|
||||
#include "FluEventBus.h"
|
||||
@ -36,10 +34,6 @@ void FluentUI::registerTypes(const char *uri){
|
||||
qmlRegisterType<ScreenshotBackground>(uri,major,minor,"ScreenshotBackground");
|
||||
qmlRegisterType<Screenshot>(uri,major,minor,"Screenshot");
|
||||
qmlRegisterType<FluColorSet>(uri,major,minor,"FluColorSet");
|
||||
qmlRegisterType<FluHttpInterceptor>(uri,major,minor,"FluHttpInterceptor");
|
||||
qmlRegisterType<FluHttp>(uri,major,minor,"FluHttp");
|
||||
qmlRegisterType<HttpCallable>(uri,major,minor,"HttpCallable");
|
||||
qmlRegisterType<HttpRequest>(uri,major,minor,"HttpRequest");
|
||||
qmlRegisterType<FluEvent>(uri,major,minor,"FluEvent");
|
||||
qmlRegisterType<FluViewModel>(uri,major,minor,"FluViewModel");
|
||||
qmlRegisterType<FluTreeModel>(uri,major,minor,"FluTreeModel");
|
||||
@ -144,7 +138,6 @@ void FluentUI::registerTypes(const char *uri){
|
||||
|
||||
|
||||
qmlRegisterUncreatableMetaObject(Fluent_Awesome::staticMetaObject, uri,major,minor,"FluentIcons", "Access to enums & flags only");
|
||||
qmlRegisterUncreatableMetaObject(FluHttpType::staticMetaObject, uri,major,minor,"FluHttpType", "Access to enums & flags only");
|
||||
qmlRegisterUncreatableMetaObject(FluThemeType::staticMetaObject, uri,major,minor,"FluThemeType", "Access to enums & flags only");
|
||||
qmlRegisterUncreatableMetaObject(FluPageType::staticMetaObject, uri,major,minor,"FluPageType", "Access to enums & flags only");
|
||||
qmlRegisterUncreatableMetaObject(FluWindowType::staticMetaObject, uri,major,minor,"FluWindowType", "Access to enums & flags only");
|
||||
|
Reference in New Issue
Block a user