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 /indra/viewer_components | |
| parent | fbee6e83fbe92e38480fa3172125f764c83f69b0 (diff) | |
implement download cancel (untested).
Diffstat (limited to 'indra/viewer_components')
| -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. | 
