summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew A. de Laix <alain@lindenlab.com>2010-11-05 15:56:33 -0700
committerAndrew A. de Laix <alain@lindenlab.com>2010-11-05 15:56:33 -0700
commit02c362b8ccad08f290ca99a738ca6ad1546c7df6 (patch)
tree2145ebf9cdc81f41c04c0281a763958b3d375075
parentfbee6e83fbe92e38480fa3172125f764c83f69b0 (diff)
implement download cancel (untested).
-rw-r--r--indra/viewer_components/updater/llupdatedownloader.cpp37
-rw-r--r--indra/viewer_components/updater/llupdatedownloader.h3
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.