diff --git a/example/qml-Qt6/page/T_Http.qml b/example/qml-Qt6/page/T_Http.qml index 6360fc75..99a9b1dd 100644 --- a/example/qml-Qt6/page/T_Http.qml +++ b/example/qml-Qt6/page/T_Http.qml @@ -132,16 +132,53 @@ FluContentPage{ } } FluProgressButton{ + property bool downloading: false property string saveFilePath: FluTools.getApplicationDirPath()+ "/download/big_buck_bunny.mp4" property string resourcePath: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" id:btn_breakpoint_download implicitWidth: parent.width implicitHeight: 36 - text: progress === 1 ? "打开文件" : "断点下载文件" + text: { + if(downloading){ + return "暂停下载" + } + if(progress === 0){ + return "断点下载文件" + }else if(progress === 1){ + return "打开文件" + }else{ + return "继续下载" + } + } + HttpCallable{ + id:callable_breakpoint_download + onStart: { + btn_breakpoint_download.downloading = true + } + onFinish: { + btn_breakpoint_download.downloading = false + } + onError: + (status,errorString,result)=>{ + console.debug(status+";"+errorString+";"+result) + } + onSuccess: + (result)=>{ + showSuccess(result) + } + onDownloadProgress: + (recv,total)=>{ + btn_breakpoint_download.progress = recv/total + } + } Component.onCompleted: { progress = http_breakpoint_download.breakPointDownloadProgress(resourcePath,saveFilePath) } onClicked: { + if(downloading){ + http_breakpoint_download.cancel() + return + } if(progress === 1){ FluTools.showFileInFolder(saveFilePath) }else{ @@ -260,7 +297,6 @@ FluContentPage{ btn_upload.progress = sent/total } } - FileDialog { id: file_dialog onAccepted: { @@ -275,30 +311,6 @@ FluContentPage{ } } - HttpCallable{ - id:callable_breakpoint_download - onStart: { - btn_breakpoint_download.disabled = true - } - onFinish: { - btn_breakpoint_download.disabled = false - } - onError: - (status,errorString,result)=>{ - btn_breakpoint_download.progress = 0 - showError(errorString) - console.debug(status+";"+errorString+";"+result) - } - onSuccess: - (result)=>{ - showSuccess(result) - } - onDownloadProgress: - (recv,total)=>{ - btn_breakpoint_download.progress = recv/total - } - } - HttpCallable{ id:callable_download onStart: { @@ -323,7 +335,6 @@ FluContentPage{ btn_download.progress = recv/total } } - FolderDialog { id: folder_dialog currentFolder: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0] diff --git a/example/qml/page/T_Http.qml b/example/qml/page/T_Http.qml index 6a98a4da..7ab9e324 100644 --- a/example/qml/page/T_Http.qml +++ b/example/qml/page/T_Http.qml @@ -133,16 +133,53 @@ FluContentPage{ } } FluProgressButton{ + property bool downloading: false property string saveFilePath: FluTools.getApplicationDirPath()+ "/download/big_buck_bunny.mp4" property string resourcePath: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" id:btn_breakpoint_download implicitWidth: parent.width implicitHeight: 36 - text: progress === 1 ? "打开文件" : "断点下载文件" + text: { + if(downloading){ + return "暂停下载" + } + if(progress === 0){ + return "断点下载文件" + }else if(progress === 1){ + return "打开文件" + }else{ + return "继续下载" + } + } + HttpCallable{ + id:callable_breakpoint_download + onStart: { + btn_breakpoint_download.downloading = true + } + onFinish: { + btn_breakpoint_download.downloading = false + } + onError: + (status,errorString,result)=>{ + console.debug(status+";"+errorString+";"+result) + } + onSuccess: + (result)=>{ + showSuccess(result) + } + onDownloadProgress: + (recv,total)=>{ + btn_breakpoint_download.progress = recv/total + } + } Component.onCompleted: { progress = http_breakpoint_download.breakPointDownloadProgress(resourcePath,saveFilePath) } onClicked: { + if(downloading){ + http_breakpoint_download.cancel() + return + } if(progress === 1){ FluTools.showFileInFolder(saveFilePath) }else{ @@ -261,7 +298,6 @@ FluContentPage{ btn_upload.progress = sent/total } } - FileDialog { id: file_dialog onAccepted: { @@ -276,30 +312,6 @@ FluContentPage{ } } - HttpCallable{ - id:callable_breakpoint_download - onStart: { - btn_breakpoint_download.disabled = true - } - onFinish: { - btn_breakpoint_download.disabled = false - } - onError: - (status,errorString,result)=>{ - btn_breakpoint_download.progress = 0 - showError(errorString) - console.debug(status+";"+errorString+";"+result) - } - onSuccess: - (result)=>{ - showSuccess(result) - } - onDownloadProgress: - (recv,total)=>{ - btn_breakpoint_download.progress = recv/total - } - } - HttpCallable{ id:callable_download onStart: { @@ -324,7 +336,6 @@ FluContentPage{ btn_download.progress = recv/total } } - FolderDialog { id: folder_dialog currentFolder: StandardPaths.standardLocations(StandardPaths.DownloadLocation)[0] diff --git a/src/FluHttp.cpp b/src/FluHttp.cpp index 9bd9ff80..63e5e61d 100644 --- a/src/FluHttp.cpp +++ b/src/FluHttp.cpp @@ -43,15 +43,16 @@ void FluHttp::cancel(){ void FluHttp::post(QString url,HttpCallable* callable,QMap params,QMap headers){ QThreadPool::globalInstance()->start([=](){ auto requestMap = toRequest(url,params,headers,"post"); + auto httpId = toHttpId(requestMap); QMap data = invokeIntercept(requestMap).toMap(); Q_EMIT callable->start(); - if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(requestMap)){ - Q_EMIT callable->cache(readCache(requestMap)); + if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){ + Q_EMIT callable->cache(readCache(httpId)); Q_EMIT callable->finish(); return; } - if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(requestMap)){ - Q_EMIT callable->cache(readCache(requestMap)); + if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){ + Q_EMIT callable->cache(readCache(httpId)); } for (int i = 0; i < retry(); ++i) { QNetworkAccessManager manager; @@ -84,13 +85,13 @@ void FluHttp::post(QString url,HttpCallable* callable,QMap pa reply->deleteLater(); reply = nullptr; if (isSuccess) { - handleCache(requestMap,result); + handleCache(httpId,result); Q_EMIT callable->success(result); break; }else{ if(i == retry()-1){ - if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(requestMap)){ - Q_EMIT callable->cache(readCache(requestMap)); + if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){ + Q_EMIT callable->cache(readCache(httpId)); } Q_EMIT callable->error(status,errorString,result); } @@ -103,15 +104,16 @@ void FluHttp::post(QString url,HttpCallable* callable,QMap pa void FluHttp::postString(QString url,HttpCallable* callable,QString params,QMap headers){ QThreadPool::globalInstance()->start([=](){ auto requestMap = toRequest(url,params,headers,"postString"); + auto httpId = toHttpId(requestMap); QMap data = invokeIntercept(requestMap).toMap(); Q_EMIT callable->start(); - if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(requestMap)){ - Q_EMIT callable->cache(readCache(requestMap)); + if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){ + Q_EMIT callable->cache(readCache(httpId)); Q_EMIT callable->finish(); return; } - if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(requestMap)){ - Q_EMIT callable->cache(readCache(requestMap)); + if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){ + Q_EMIT callable->cache(readCache(httpId)); } for (int i = 0; i < retry(); ++i) { QNetworkAccessManager manager; @@ -135,13 +137,13 @@ void FluHttp::postString(QString url,HttpCallable* callable,QString params,QMap< reply->deleteLater(); reply = nullptr; if (isSuccess) { - handleCache(requestMap,result); + handleCache(httpId,result); Q_EMIT callable->success(result); break; }else{ if(i == retry()-1){ - if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(requestMap)){ - Q_EMIT callable->cache(readCache(requestMap)); + if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){ + Q_EMIT callable->cache(readCache(httpId)); } Q_EMIT callable->error(status,errorString,result); } @@ -154,15 +156,16 @@ void FluHttp::postString(QString url,HttpCallable* callable,QString params,QMap< void FluHttp::postJson(QString url,HttpCallable* callable,QMap params,QMap headers){ QThreadPool::globalInstance()->start([=](){ auto requestMap = toRequest(url,params,headers,"postJson"); + auto httpId = toHttpId(requestMap); QMap data = invokeIntercept(requestMap).toMap(); Q_EMIT callable->start(); - if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(requestMap)){ - Q_EMIT callable->cache(readCache(requestMap)); + if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){ + Q_EMIT callable->cache(readCache(httpId)); Q_EMIT callable->finish(); return; } - if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(requestMap)){ - Q_EMIT callable->cache(readCache(requestMap)); + if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){ + Q_EMIT callable->cache(readCache(httpId)); } for (int i = 0; i < retry(); ++i) { QNetworkAccessManager manager; @@ -186,13 +189,13 @@ void FluHttp::postJson(QString url,HttpCallable* callable,QMapdeleteLater(); reply = nullptr; if (isSuccess) { - handleCache(requestMap,result); + handleCache(httpId,result); Q_EMIT callable->success(result); break; }else{ if(i == retry()-1){ - if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(requestMap)){ - Q_EMIT callable->cache(readCache(requestMap)); + if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){ + Q_EMIT callable->cache(readCache(httpId)); } Q_EMIT callable->error(status,errorString,result); } @@ -205,13 +208,14 @@ void FluHttp::postJson(QString url,HttpCallable* callable,QMap params,QMap headers){ QThreadPool::globalInstance()->start([=](){ auto requestMap = toRequest(url,params,headers,"get"); + auto httpId = toHttpId(requestMap); QMap data = invokeIntercept(requestMap).toMap(); Q_EMIT callable->start(); - if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(requestMap)){ - Q_EMIT callable->cache(readCache(requestMap)); + if(_cacheMode == FluHttpType::CacheMode::FirstCacheThenRequest && cacheExists(httpId)){ + Q_EMIT callable->cache(readCache(httpId)); } - if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(requestMap)){ - Q_EMIT callable->cache(readCache(requestMap)); + if(_cacheMode == FluHttpType::CacheMode::IfNoneCacheRequest && cacheExists(httpId)){ + Q_EMIT callable->cache(readCache(httpId)); Q_EMIT callable->finish(); return; } @@ -236,13 +240,13 @@ void FluHttp::get(QString url,HttpCallable* callable,QMap par reply->deleteLater(); reply = nullptr; if (isSuccess) { - handleCache(requestMap,result); + handleCache(httpId,result); Q_EMIT callable->success(result); break; }else{ if(i == retry()-1){ - if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(requestMap)){ - Q_EMIT callable->cache(readCache(requestMap)); + if(_cacheMode == FluHttpType::CacheMode::RequestFailedReadCache && cacheExists(httpId)){ + Q_EMIT callable->cache(readCache(httpId)); } Q_EMIT callable->error(status,errorString,result); } @@ -256,6 +260,7 @@ void FluHttp::download(QString url,HttpCallable* callable,QString savePath,QMap< QThreadPool::globalInstance()->start([=](){ auto requestMap = toRequest(url,params,headers,"download"); requestMap.insert("savePath",savePath); + auto httpId = toHttpId(requestMap); QMap data = invokeIntercept(requestMap).toMap(); Q_EMIT callable->start(); QNetworkAccessManager manager; @@ -273,10 +278,10 @@ void FluHttp::download(QString url,HttpCallable* callable,QString savePath,QMap< loop.quit(); }); qint64 seek = 0; - auto filePath = getCacheFilePath(requestMap); + auto filePath = getCacheFilePath(httpId); QSharedPointer fileCache(new QFile(filePath)); if(fileCache->exists() && file->exists() && _breakPointDownload){ - QJsonObject cacheInfo = QJsonDocument::fromJson(readCache(requestMap).toUtf8()).object(); + 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){ @@ -420,8 +425,8 @@ void FluHttp::addHeaders(QNetworkRequest* request,const QMap& } } -QString FluHttp::readCache(const QMap& request){ - auto filePath = getCacheFilePath(request); +QString FluHttp::readCache(const QString& httpId){ + auto filePath = getCacheFilePath(httpId); QString result; QFile file(filePath); if(!file.exists()){ @@ -434,25 +439,24 @@ QString FluHttp::readCache(const QMap& request){ return result; } -bool FluHttp::cacheExists(const QMap& request){ - return QFile(getCacheFilePath(request)).exists(); +bool FluHttp::cacheExists(const QString& httpId){ + return QFile(getCacheFilePath(httpId)).exists(); } -QString FluHttp::getCacheFilePath(const QMap& request){ - auto fileName = FluTools::getInstance()->sha256(QJsonDocument::fromVariant(QVariant(request)).toJson()); +QString FluHttp::getCacheFilePath(const QString& httpId){ QDir dir = _cacheDir; if (!dir.exists(_cacheDir)){ dir.mkpath(_cacheDir); } - auto filePath = _cacheDir+"/"+fileName; + auto filePath = _cacheDir+"/"+httpId; return filePath; } -void FluHttp::handleCache(QMap request,const QString& result){ +void FluHttp::handleCache(const QString& httpId,const QString& result){ if(_cacheMode==FluHttpType::CacheMode::NoCache){ return; } - auto filePath = getCacheFilePath(request); + auto filePath = getCacheFilePath(httpId); QSharedPointer file(new QFile(filePath)); QIODevice::OpenMode mode = QIODevice::WriteOnly|QIODevice::Truncate; if (!file->open(mode)) @@ -465,11 +469,12 @@ void FluHttp::handleCache(QMap request,const QString& result) qreal FluHttp::breakPointDownloadProgress(QString url,QString savePath,QMap params,QMap headers){ auto requestMap = toRequest(url,params,headers,"download"); requestMap.insert("savePath",savePath); + auto httpId = toHttpId(requestMap); QSharedPointer file(new QFile(savePath)); - auto filePath = getCacheFilePath(requestMap); + auto filePath = getCacheFilePath(httpId); QSharedPointer fileCache(new QFile(filePath)); if(fileCache->exists() && file->exists() && _breakPointDownload){ - QJsonObject cacheInfo = QJsonDocument::fromJson(readCache(requestMap).toUtf8()).object(); + 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){ @@ -484,3 +489,7 @@ qreal FluHttp::breakPointDownloadProgress(QString url,QString savePath,QMap& map){ + return FluTools::getInstance()->sha256(QJsonDocument::fromVariant(QVariant(map)).toJson()); +} diff --git a/src/FluHttp.h b/src/FluHttp.h index 6f75ca9f..74343328 100644 --- a/src/FluHttp.h +++ b/src/FluHttp.h @@ -34,12 +34,13 @@ class FluHttp : public QObject private: QVariant invokeIntercept(QMap request,Qt::ConnectionType type = Qt::BlockingQueuedConnection); QMap toRequest(const QString& url,const QVariant& params,const QVariant& headers,const QString& method); + QString toHttpId(const QMap& map); void addQueryParam(QUrl* url,const QMap& params); void addHeaders(QNetworkRequest* request,const QMap& params); - void handleCache(QMap request, const QString& result); - QString readCache(const QMap& request); - bool cacheExists(const QMap& request); - QString getCacheFilePath(const QMap& request); + void handleCache(const QString& httpId, const QString& result); + QString readCache(const QString& httpId); + bool cacheExists(const QString& httpId); + QString getCacheFilePath(const QString& httpId); public: explicit FluHttp(QObject *parent = nullptr); ~FluHttp();