From ddee70cdca8d4522edc3410d2f95b7ec1e828206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E5=AD=90=E6=A5=9A=5Czhuzi?= Date: Wed, 6 Sep 2023 00:22:37 +0800 Subject: [PATCH] add breakPointDownload property --- example/qml-Qt6/page/T_Http.qml | 1 + example/qml/page/T_Http.qml | 1 + src/FluHttp.cpp | 55 +++++++++++++++++++++------------ src/FluHttp.h | 1 + 4 files changed, 38 insertions(+), 20 deletions(-) diff --git a/example/qml-Qt6/page/T_Http.qml b/example/qml-Qt6/page/T_Http.qml index b1e99646..1ca46ff0 100644 --- a/example/qml-Qt6/page/T_Http.qml +++ b/example/qml-Qt6/page/T_Http.qml @@ -233,6 +233,7 @@ FluContentPage{ HttpCallable{ id:callable_download onStart: { + btn_download.progress = 0 btn_download.disabled = true } onFinish: { diff --git a/example/qml/page/T_Http.qml b/example/qml/page/T_Http.qml index 31098456..95d5ae21 100644 --- a/example/qml/page/T_Http.qml +++ b/example/qml/page/T_Http.qml @@ -235,6 +235,7 @@ FluContentPage{ HttpCallable{ id:callable_download onStart: { + btn_download.progress = 0 btn_download.disabled = true } onFinish: { diff --git a/src/FluHttp.cpp b/src/FluHttp.cpp index a70a3213..60f830ca 100644 --- a/src/FluHttp.cpp +++ b/src/FluHttp.cpp @@ -25,6 +25,7 @@ FluHttp::FluHttp(QObject *parent) timeout(15000); cacheMode(FluHttpType::CacheMode::NoCache); cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)+"/httpcache"); + breakPointDownload(true); } FluHttp::~FluHttp(){ @@ -267,42 +268,56 @@ void FluHttp::download(QString url,HttpCallable* callable,QString savePath,QMap< QNetworkRequest request(_url); addHeaders(&request,data["headers"].toMap()); QSharedPointer file(new QFile(savePath)); - QIODevice::OpenMode mode = QIODevice::WriteOnly|QIODevice::Truncate; - if (!file->open(mode)) - { - Q_EMIT callable->error(-1,QString("Url: %1 %2 Non-Writable").arg(request.url().toString(),file->fileName()),""); - Q_EMIT callable->finish(); - return; - } QEventLoop loop; connect(&manager,&QNetworkAccessManager::finished,&manager,[&loop](QNetworkReply *reply){ loop.quit(); }); + auto filePath = getCacheFilePath(data); + qint64 seek = 0; + QSharedPointer fileCache(new QFile(filePath)); + if(fileCache->exists() && file->exists() && _breakPointDownload){ + QJsonObject cacheInfo = QJsonDocument::fromJson(readCache(data).toUtf8()).object(); + auto fileSize = cacheInfo.value("fileSize").toInteger(); + auto contentLength = cacheInfo.value("contentLength").toInteger(); + if(fileSize == contentLength && file->size() == contentLength){ + Q_EMIT callable->downloadProgress(fileSize,contentLength); + Q_EMIT callable->success(savePath); + Q_EMIT callable->finish(); + return; + } + if(fileSize==file->size()){ + request.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(request); _cacheReply.append(reply); - auto filePath = getCacheFilePath(data); - QSharedPointer fileCache(new QFile(filePath)); - if (!fileCache->open(mode)) + if (!fileCache->open(QIODevice::WriteOnly|QIODevice::Truncate)) { qDebug()<<"FileCache Error"; } - connect(reply,&QNetworkReply::readyRead,reply,[reply,file,fileCache,data]{ + connect(reply,&QNetworkReply::readyRead,reply,[reply,file,fileCache,data,callable,seek]{ if (!reply || !file || reply->error() != QNetworkReply::NoError) { return; } - file->write(reply->readAll()); - fileCache->resize(0); QMap downMap = data; - QVariant etagHeader = reply->header(QNetworkRequest::ETagHeader); - if (etagHeader.isValid()) { - downMap.insert("ETag",etagHeader.toString()); - } + 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()); - }); - connect(reply,&QNetworkReply::downloadProgress,reply,[=](qint64 bytesReceived, qint64 bytesTotal){ - Q_EMIT callable->downloadProgress(bytesReceived,bytesTotal); + fileCache->flush(); + Q_EMIT callable->downloadProgress(file->size(),contentLength); }); loop.exec(); if (reply->error() == QNetworkReply::NoError) { diff --git a/src/FluHttp.h b/src/FluHttp.h index 7eca9bde..f071d360 100644 --- a/src/FluHttp.h +++ b/src/FluHttp.h @@ -29,6 +29,7 @@ class FluHttp : public QObject 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 request);