diff options
Diffstat (limited to 'indra/viewer_components')
6 files changed, 177 insertions, 106 deletions
| diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp index 6d0758b226..734747c811 100644 --- a/indra/viewer_components/updater/llupdatechecker.cpp +++ b/indra/viewer_components/updater/llupdatechecker.cpp @@ -143,8 +143,8 @@ void LLUpdateChecker::Implementation::completed(U32 status,  				LL_WARNS("UpdaterService")  					<< "update response using " << sProtocolVersion -					<< " was 404... retry at " << retryUrl -					<< " with legacy protocol" +					<< " was 404... retry with legacy protocol" << mProtocol +					<< "\n at " << retryUrl  					<< LL_ENDL;  				mHttpClient.get(retryUrl, this); @@ -164,22 +164,9 @@ void LLUpdateChecker::Implementation::completed(U32 status,  			mClient.error(reason);  		}  	} -	else if(!content.asBoolean()) -	{ -		LL_INFOS("UpdaterService") << "up to date" << LL_ENDL; -		mClient.upToDate(); -	} -	else if(content["required"].asBoolean()) -	{ -		LL_INFOS("UpdaterService") << "version invalid" << LL_ENDL; -		LLURI uri(content["url"].asString()); -		mClient.requiredUpdate(content["version"].asString(), uri, content["hash"].asString()); -	}  	else  	{ -		LL_INFOS("UpdaterService") << "newer version " << content["version"].asString() << " available" << LL_ENDL; -		LLURI uri(content["url"].asString()); -		mClient.optionalUpdate(content["version"].asString(), uri, content["hash"].asString()); +		mClient.response(content);  	}  } @@ -215,8 +202,10 @@ std::string LLUpdateChecker::Implementation::buildUrl(std::string const & hostUr      {          platform = "mac";      } -#else +#elif LL_LINUX  	static const char * platform = "lnx"; +#else +#   error "unsupported platform"  #endif  	LLSD path; diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h index b60f21549e..55806137d7 100644 --- a/indra/viewer_components/updater/llupdatechecker.h +++ b/indra/viewer_components/updater/llupdatechecker.h @@ -117,18 +117,8 @@ public:  	// An error occurred while checking for an update.  	virtual void error(std::string const & message) = 0; -	// A newer version is available, but the current version may still be used. -	virtual void optionalUpdate(std::string const & newVersion, -								LLURI const & uri, -								std::string const & hash) = 0; -	 -	// A newer version is available, and the current version is no longer valid.  -	virtual void requiredUpdate(std::string const & newVersion, -								LLURI const & uri, -								std::string const & hash) = 0; -	 -	// The checked version is up to date; no newer version exists. -	virtual void upToDate(void) = 0; +	// A successful response was received from the viewer version manager +	virtual void response(LLSD const & content) = 0;  }; diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp index 001dd5ed16..c28ad76c77 100644 --- a/indra/viewer_components/updater/llupdatedownloader.cpp +++ b/indra/viewer_components/updater/llupdatedownloader.cpp @@ -50,7 +50,9 @@ public:  	void cancel(void);  	void download(LLURI const & uri,  				  std::string const & hash, +				  std::string const & updateChannel,  				  std::string const & updateVersion, +				  std::string const & info_url,  				  bool required);  	bool isDownloading(void);  	size_t onHeader(void * header, size_t size); @@ -125,10 +127,12 @@ void LLUpdateDownloader::cancel(void)  void LLUpdateDownloader::download(LLURI const & uri,  								  std::string const & hash, +								  std::string const & updateChannel,  								  std::string const & updateVersion, +								  std::string const & info_url,  								  bool required)  { -	mImplementation->download(uri, hash, updateVersion, required); +	mImplementation->download(uri, hash, updateChannel, updateVersion, info_url, required);  } @@ -222,18 +226,28 @@ void LLUpdateDownloader::Implementation::cancel(void)  void LLUpdateDownloader::Implementation::download(LLURI const & uri,  												  std::string const & hash, +												  std::string const & updateChannel,  												  std::string const & updateVersion, +												  std::string const & info_url,  												  bool required) -{ +{   	if(isDownloading()) mClient.downloadError("download in progress");  	mDownloadRecordPath = downloadMarkerPath();  	mDownloadData = LLSD();  	mDownloadData["required"] = required; +	mDownloadData["update_channel"] = updateChannel;  	mDownloadData["update_version"] = updateVersion; -	try { +	if (!info_url.empty()) +	{ +		mDownloadData["info_url"] = info_url; +	} +	try +	{  		startDownloading(uri, hash); -	} catch(DownloadError const & e) { +	} +	catch(DownloadError const & e) +	{  		mClient.downloadError(e.what());  	}  } @@ -249,47 +263,65 @@ void LLUpdateDownloader::Implementation::resume(void)  {  	mCancelled = false; -	if(isDownloading()) { +	if(isDownloading()) +	{  		mClient.downloadError("download in progress");  	}  	mDownloadRecordPath = downloadMarkerPath();  	llifstream dataStream(mDownloadRecordPath); -	if(!dataStream) { +	if(!dataStream) +	{  		mClient.downloadError("no download marker");  		return;  	}  	LLSDSerialize::fromXMLDocument(mDownloadData, dataStream); -	if(!mDownloadData.asBoolean()) { +	if(!mDownloadData.asBoolean()) +	{  		mClient.downloadError("no download information in marker");  		return;  	}  	std::string filePath = mDownloadData["path"].asString(); -	try { -		if(LLFile::isfile(filePath)) { +	try +	{ +		if(LLFile::isfile(filePath)) +		{  			llstat fileStatus;  			LLFile::stat(filePath, &fileStatus); -			if(fileStatus.st_size != mDownloadData["size"].asInteger()) { +			if(fileStatus.st_size != mDownloadData["size"].asInteger()) +			{  				resumeDownloading(fileStatus.st_size); -			} else if(!validateDownload()) { +			} +			else if(!validateDownload()) +			{  				LLFile::remove(filePath);  				download(LLURI(mDownloadData["url"].asString()),  						 mDownloadData["hash"].asString(), +						 mDownloadData["update_channel"].asString(),  						 mDownloadData["update_version"].asString(), +						 mDownloadData["info_url"].asString(),  						 mDownloadData["required"].asBoolean()); -			} else { +			} +			else +			{  				mClient.downloadComplete(mDownloadData);  			} -		} else { +		} +		else +		{  			download(LLURI(mDownloadData["url"].asString()),  					 mDownloadData["hash"].asString(), +					 mDownloadData["update_channel"].asString(),  					 mDownloadData["update_version"].asString(), +					 mDownloadData["info_url"].asString(),  					 mDownloadData["required"].asBoolean());  		} -	} catch(DownloadError & e) { +	} +	catch(DownloadError & e) +	{  		mClient.downloadError(e.what());  	}  } @@ -297,13 +329,18 @@ void LLUpdateDownloader::Implementation::resume(void)  void LLUpdateDownloader::Implementation::setBandwidthLimit(U64 bytesPerSecond)  { -	if((mBandwidthLimit != bytesPerSecond) && isDownloading() && !mDownloadData["required"].asBoolean()) { +	if((mBandwidthLimit != bytesPerSecond) && isDownloading() && !mDownloadData["required"].asBoolean()) +	{  		llassert(mCurl != 0);  		mBandwidthLimit = bytesPerSecond;  		CURLcode code = curl_easy_setopt(mCurl, CURLOPT_MAX_RECV_SPEED_LARGE, &mBandwidthLimit); -		if(code != CURLE_OK) LL_WARNS("UpdaterService") << -			"unable to change dowload bandwidth" << LL_ENDL; -	} else { +		if(code != CURLE_OK) +		{ +			LL_WARNS("UpdaterService") << "unable to change dowload bandwidth" << LL_ENDL; +		} +	} +	else +	{  		mBandwidthLimit = bytesPerSecond;  	}  } @@ -381,29 +418,44 @@ void LLUpdateDownloader::Implementation::run(void)  {  	CURLcode code = curl_easy_perform(mCurl);  	mDownloadStream.close(); -	if(code == CURLE_OK) { +	if(code == CURLE_OK) +	{  		LLFile::remove(mDownloadRecordPath); -		if(validateDownload()) { +		if(validateDownload()) +		{  			LL_INFOS("UpdaterService") << "download successful" << LL_ENDL;  			mClient.downloadComplete(mDownloadData); -		} else { +		} +		else +		{  			LL_INFOS("UpdaterService") << "download failed hash check" << LL_ENDL;  			std::string filePath = mDownloadData["path"].asString(); -			if(filePath.size() != 0) LLFile::remove(filePath); +			if(filePath.size() != 0) +			{ +				LLFile::remove(filePath); +			}  			mClient.downloadError("failed hash check");  		} -	} else if(mCancelled && (code == CURLE_WRITE_ERROR)) { +	} +	else if(mCancelled && (code == CURLE_WRITE_ERROR)) +	{  		LL_INFOS("UpdaterService") << "download canceled by user" << LL_ENDL;  		// Do not call back client. -	} else { +	} +	else +	{  		LL_WARNS("UpdaterService") << "download failed with error '" <<  			curl_easy_strerror(code) << "'" << LL_ENDL;  		LLFile::remove(mDownloadRecordPath); -		if(mDownloadData.has("path")) LLFile::remove(mDownloadData["path"].asString()); +		if(mDownloadData.has("path")) +		{ +			LLFile::remove(mDownloadData["path"].asString()); +		}  		mClient.downloadError("curl error");  	} -	if(mHeaderList) { +	if(mHeaderList) +	{  		curl_slist_free_all(mHeaderList);  		mHeaderList = 0;  	} @@ -421,13 +473,16 @@ void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & u  		curl_easy_reset(mCurl);  	} -	if(mCurl == 0) throw DownloadError("failed to initialize curl"); - +	if(mCurl == 0) +	{ +		throw DownloadError("failed to initialize curl"); +	}  	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_NOSIGNAL, true));  	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_FOLLOWLOCATION, true));  	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, &write_function));  	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, this)); -	if(processHeader) { +	if(processHeader) +	{  	   throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERFUNCTION, &header_function));  	   throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERDATA, this));  	} @@ -456,7 +511,10 @@ void LLUpdateDownloader::Implementation::resumeDownloading(size_t startByte)  	boost::format rangeHeaderFormat("Range: bytes=%u-");  	rangeHeaderFormat % startByte;  	mHeaderList = curl_slist_append(mHeaderList, rangeHeaderFormat.str().c_str()); -	if(mHeaderList == 0) throw DownloadError("cannot add Range header"); +	if(mHeaderList == 0) +	{ +		throw DownloadError("cannot add Range header"); +	}  	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPHEADER, mHeaderList));  	mDownloadStream.open(mDownloadData["path"].asString(), @@ -508,19 +566,26 @@ bool LLUpdateDownloader::Implementation::validateDownload(void)  {  	std::string filePath = mDownloadData["path"].asString();  	llifstream fileStream(filePath, std::ios_base::in | std::ios_base::binary); -	if(!fileStream) return false; +	if(!fileStream) +	{ +		return false; +	}  	std::string hash = mDownloadData["hash"].asString(); -	if(hash.size() != 0) { +	if(hash.size() != 0) +	{  		LL_INFOS("UpdaterService") << "checking hash..." << LL_ENDL;  		char digest[33];  		LLMD5(fileStream).hex_digest(digest); -		if(hash != digest) { -			LL_WARNS("UpdaterService") << "download hash mismatch; expeted " << hash << +		if(hash != digest) +		{ +			LL_WARNS("UpdaterService") << "download hash mismatch; expected " << hash <<  				" but download is " << digest << LL_ENDL;  		}  		return hash == digest; -	} else { +	} +	else +	{  		return true; // No hash check provided.  	}  } diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h index 0d635640cf..f759988f12 100644 --- a/indra/viewer_components/updater/llupdatedownloader.h +++ b/indra/viewer_components/updater/llupdatedownloader.h @@ -54,7 +54,9 @@ public:  	// Start a new download.  	void download(LLURI const & uri,  				  std::string const & hash,  +				  std::string const & updateChannel,  				  std::string const & updateVersion, +				  std::string const & info_url,  				  bool required=false);  	// Returns true if a download is in progress. diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp index c6c89655d3..324b051b21 100644 --- a/indra/viewer_components/updater/llupdaterservice.cpp +++ b/indra/viewer_components/updater/llupdaterservice.cpp @@ -140,13 +140,9 @@ public:  	// LLUpdateChecker::Client:  	virtual void error(std::string const & message); -	virtual void optionalUpdate(std::string const & newVersion, -								LLURI const & uri, -								std::string const & hash); -	virtual void requiredUpdate(std::string const & newVersion, -								LLURI const & uri, -								std::string const & hash); -	virtual void upToDate(void); +	 +	// A successful response was received from the viewer version manager +	virtual void response(LLSD const & content);  	// LLUpdateDownloader::Client  	void downloadComplete(LLSD const & data); @@ -155,6 +151,7 @@ public:  	bool onMainLoop(LLSD const & event);  private: +	std::string mNewChannel;  	std::string mNewVersion;  	void restartTimer(unsigned int seconds); @@ -334,9 +331,13 @@ bool LLUpdaterServiceImpl::checkForInstall(bool launchInstaller)  				if((result == 0) && mAppExitCallback)  				{  					mAppExitCallback(); -				} else if(result != 0) { +				} +				else if(result != 0) +				{  					LL_WARNS("UpdaterService") << "failed to run update install script" << LL_ENDL; -				} else { +				} +				else +				{  					; // No op.  				}  			} @@ -364,6 +365,7 @@ bool LLUpdaterServiceImpl::checkForResume()  			{  				mIsDownloading = true;  				mNewVersion = download_info["update_version"].asString(); +				mNewChannel = download_info["update_channel"].asString();  				mUpdateDownloader.resume();  				result = true;  			} @@ -372,7 +374,10 @@ bool LLUpdaterServiceImpl::checkForResume()  				// The viewer that started this download is not the same as this viewer; ignore.  				LL_INFOS("UpdaterService") << "ignoring partial download from different viewer version" << LL_ENDL;;  				std::string path = download_info["path"].asString(); -				if(!path.empty()) LLFile::remove(path); +				if(!path.empty()) +				{ +					LLFile::remove(path); +				}  				LLFile::remove(download_marker_path);  			}  		}  @@ -389,36 +394,43 @@ void LLUpdaterServiceImpl::error(std::string const & message)  	}  } -void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion, -										  LLURI const & uri, -										  std::string const & hash) -{ -	stopTimer(); -	mNewVersion = newVersion; -	mIsDownloading = true; -	setState(LLUpdaterService::DOWNLOADING); -	mUpdateDownloader.download(uri, hash, newVersion, false); -} - -void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion, -										  LLURI const & uri, -										  std::string const & hash) -{ -	stopTimer(); -	mNewVersion = newVersion; -	mIsDownloading = true; -	setState(LLUpdaterService::DOWNLOADING); -	mUpdateDownloader.download(uri, hash, newVersion, true); -} - -void LLUpdaterServiceImpl::upToDate(void) +// A successful response was received from the viewer version manager +void LLUpdaterServiceImpl::response(LLSD const & content)  { -	if(mIsChecking) +	if(!content.asBoolean()) // an empty response means "no update"  	{ -		restartTimer(mCheckPeriod); -	} +		LL_INFOS("UpdaterService") << "up to date" << LL_ENDL; +		if(mIsChecking) +		{ +			restartTimer(mCheckPeriod); +		} -	setState(LLUpdaterService::UP_TO_DATE); +		setState(LLUpdaterService::UP_TO_DATE); +	} +	else +	{ +		// there is an update available... +		stopTimer(); +		mNewChannel = content["channel"].asString(); +		if (mNewChannel.empty()) +		{ +			LL_INFOS("UpdaterService") << "no channel supplied, assuming current channel" << LL_ENDL; +			mNewChannel = mChannel; +		} +		mNewVersion = content["version"].asString(); +		mIsDownloading = true; +		setState(LLUpdaterService::DOWNLOADING); +		BOOL required = content["required"].asBoolean(); +		LLURI url(content["url"].asString()); +		std::string more_info = content["more_info"].asString(); +		LL_DEBUGS("UpdaterService") +			<< "Starting download of " +			<< ( required ? "required" : "optional" ) << " update " +			<< "to channel '" << mNewChannel << "' version " << mNewVersion +			<< "more info '" << more_info << "'" +			<< LL_ENDL; +		mUpdateDownloader.download(url, content["hash"].asString(), mNewChannel, mNewVersion, more_info, required); +	}  }  void LLUpdaterServiceImpl::downloadComplete(LLSD const & data)  @@ -436,9 +448,19 @@ void LLUpdaterServiceImpl::downloadComplete(LLSD const & data)  	payload["type"] = LLSD(LLUpdaterService::DOWNLOAD_COMPLETE);  	payload["required"] = data["required"];  	payload["version"] = mNewVersion; +	payload["channel"] = mNewChannel; +	payload["info_url"] = data["info_url"];  	event["payload"] = payload; +	LL_DEBUGS("UpdaterService") +		<< "Download complete " +		<< ( data["required"].asBoolean() ? "required" : "optional" ) +		<< "channel " << mNewChannel +		<< "version " << mNewVersion +		<< "info " << data["info_url"].asString() +		<< LL_ENDL; +  	LLEventPumps::instance().obtain("mainlooprepeater").post(event); -	 +  	setState(LLUpdaterService::TERMINAL);  } @@ -512,15 +534,18 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)  		// Check for failed install.  		if(LLFile::isfile(ll_install_failed_marker_path()))  		{ +			LL_DEBUGS("UpdaterService") << "found marker " << ll_install_failed_marker_path() << LL_ENDL;;  			int requiredValue = 0;   			{  				llifstream stream(ll_install_failed_marker_path());  				stream >> requiredValue; -				if(stream.fail()) requiredValue = 0; +				if(stream.fail()) +				{ +					requiredValue = 0; +				}  			}  			// TODO: notify the user. -			LL_INFOS("UpdaterService") << "found marker " << ll_install_failed_marker_path() << LL_ENDL;; -			LL_INFOS("UpdaterService") << "last install attempt failed" << LL_ENDL;; +			LL_WARNS("UpdaterService") << "last install attempt failed" << LL_ENDL;;  			LLFile::remove(ll_install_failed_marker_path());  			LLSD event; diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index ddaaccc051..51b63dcb7b 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -53,7 +53,7 @@ void LLUpdateChecker::checkVersion(std::string const & hostUrl,  								   bool                willing_to_test)  {}  LLUpdateDownloader::LLUpdateDownloader(Client & ) {} -void LLUpdateDownloader::download(LLURI const & , std::string const &, std::string const &, bool){} +void LLUpdateDownloader::download(LLURI const & , std::string const &, std::string const &, std::string const &, std::string const &, bool){}  class LLDir_Mock : public LLDir  { | 
