diff options
author | Andrew A. de Laix <alain@lindenlab.com> | 2010-11-05 15:56:33 -0700 |
---|---|---|
committer | Andrew A. de Laix <alain@lindenlab.com> | 2010-11-05 15:56:33 -0700 |
commit | 02c362b8ccad08f290ca99a738ca6ad1546c7df6 (patch) | |
tree | 2145ebf9cdc81f41c04c0281a763958b3d375075 | |
parent | fbee6e83fbe92e38480fa3172125f764c83f69b0 (diff) |
implement download cancel (untested).
-rw-r--r-- | indra/viewer_components/updater/llupdatedownloader.cpp | 37 | ||||
-rw-r--r-- | indra/viewer_components/updater/llupdatedownloader.h | 3 |
2 files changed, 27 insertions, 13 deletions
diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index 102f2f9eec..eaef230a8f 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -46,11 +46,12 @@ public: void cancel(void); void download(LLURI const & uri, std::string const & hash); bool isDownloading(void); - void onHeader(void * header, size_t size); - void onBody(void * header, size_t size); + size_t onHeader(void * header, size_t size); + size_t onBody(void * header, size_t size); void resume(void); private: + bool mCancelled; LLUpdateDownloader::Client & mClient; CURL * mCurl; LLSD mDownloadData; @@ -137,28 +138,27 @@ namespace { size_t write_function(void * data, size_t blockSize, size_t blocks, void * downloader) { size_t bytes = blockSize * blocks; - reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)->onBody(data, bytes); - return bytes; + return reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)->onBody(data, bytes); } size_t header_function(void * data, size_t blockSize, size_t blocks, void * downloader) { size_t bytes = blockSize * blocks; - reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)->onHeader(data, bytes); - return bytes; + return reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)->onHeader(data, bytes); } } LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & client): LLThread("LLUpdateDownloader"), + mCancelled(false), mClient(client), mCurl(0), mDownloadRecordPath(LLUpdateDownloader::downloadMarkerPath()) { CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case. - llassert(code = CURLE_OK); // TODO: real error handling here. + llassert(code == CURLE_OK); // TODO: real error handling here. } @@ -170,7 +170,7 @@ LLUpdateDownloader::Implementation::~Implementation() void LLUpdateDownloader::Implementation::cancel(void) { - llassert(!"not implemented"); + mCancelled = true; } @@ -231,12 +231,12 @@ void LLUpdateDownloader::Implementation::resume(void) } -void LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size) +size_t LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size) { char const * headerPtr = reinterpret_cast<const char *> (buffer); std::string header(headerPtr, headerPtr + size); size_t colonPosition = header.find(':'); - if(colonPosition == std::string::npos) return; // HTML response; ignore. + if(colonPosition == std::string::npos) return size; // HTML response; ignore. if(header.substr(0, colonPosition) == "Content-Length") { try { @@ -257,20 +257,25 @@ void LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size) } else { ; // No op. } + + return size; } -void LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size) +size_t LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size) { + if(mCancelled) return 0; // Forces a write error which will halt curl thread. + mDownloadStream.write(reinterpret_cast<const char *>(buffer), size); + return size; } void LLUpdateDownloader::Implementation::run(void) { CURLcode code = curl_easy_perform(mCurl); - LLFile::remove(mDownloadRecordPath); if(code == CURLE_OK) { + LLFile::remove(mDownloadRecordPath); if(validateDownload()) { LL_INFOS("UpdateDownload") << "download successful" << LL_ENDL; mClient.downloadComplete(mDownloadData); @@ -280,9 +285,13 @@ void LLUpdateDownloader::Implementation::run(void) if(filePath.size() != 0) LLFile::remove(filePath); mClient.downloadError("failed hash check"); } + } else if(mCancelled && (code == CURLE_WRITE_ERROR)) { + LL_INFOS("UpdateDownload") << "download canceled by user" << LL_ENDL; + // Do not call back client. } else { LL_WARNS("UpdateDownload") << "download failed with error '" << curl_easy_strerror(code) << "'" << LL_ENDL; + LLFile::remove(mDownloadRecordPath); mClient.downloadError("curl error"); } } @@ -381,6 +390,10 @@ bool LLUpdateDownloader::Implementation::validateDownload(void) LL_INFOS("UpdateDownload") << "checking hash..." << LL_ENDL; char digest[33]; LLMD5(fileStream).hex_digest(digest); + if(hash != digest) { + LL_WARNS("UpdateDownload") << "download hash mismatch; expeted " << hash << + " but download is " << digest << LL_ENDL; + } return hash == digest; } else { return true; // No hash check provided. diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h index dc8ecc378a..491a638f9a 100644 --- a/indra/viewer_components/updater/llupdatedownloader.h +++ b/indra/viewer_components/updater/llupdatedownloader.h @@ -47,7 +47,8 @@ public: LLUpdateDownloader(Client & client); - // Cancel any in progress download; a no op if none is in progress. + // Cancel any in progress download; a no op if none is in progress. The + // client will not receive a complete or error callback. void cancel(void); // Start a new download. |