Fix FSData to download files only if there are newer versions on the server

master
Ansariel 2017-11-29 22:22:44 +01:00
parent a6a960e73a
commit 409c001755
8 changed files with 92 additions and 23 deletions

View File

@ -539,6 +539,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
long sslHostV(0L);
long dnsCacheTimeout(-1L);
long nobody(0L);
long last_modified(0L); // <FS:Ansariel> GetIfModified request
if (mReqOptions)
{
@ -547,6 +548,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
sslHostV = mReqOptions->getSSLVerifyHost() ? 2L : 0L;
dnsCacheTimeout = mReqOptions->getDNSCacheTimeout();
nobody = mReqOptions->getHeadersOnly() ? 1L : 0L;
last_modified = mReqOptions->getLastModified(); // <FS:Ansariel> GetIfModified request
}
code = curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, follow_redirect);
check_curl_easy_code(code, CURLOPT_FOLLOWLOCATION);
@ -559,6 +561,16 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
code = curl_easy_setopt(mCurlHandle, CURLOPT_NOBODY, nobody);
check_curl_easy_code(code, CURLOPT_NOBODY);
// <FS:Ansariel> GetIfModified request
if (last_modified > 0)
{
code = curl_easy_setopt(mCurlHandle, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
check_curl_easy_code(code, CURLOPT_TIMECONDITION);
code = curl_easy_setopt(mCurlHandle, CURLOPT_TIMEVALUE, last_modified);
check_curl_easy_code(code, CURLOPT_TIMEVALUE);
}
// </FS:Ansariel>
// The Linksys WRT54G V5 router has an issue with frequent
// DNS lookups from LAN machines. If they happen too often,
// like for every HTTP request, the router gets annoyed after

View File

@ -46,7 +46,8 @@ HttpOptions::HttpOptions() :
mVerifyPeer(false),
mVerifyHost(false),
mDNSCacheTimeout(-1L),
mNoBody(false)
mNoBody(false),
mLastModified(0) // <FS:Ansariel> GetIfModified request
{}
@ -125,4 +126,11 @@ void HttpOptions::setHeadersOnly(bool nobody)
setWantHeaders(true);
}
// <FS:Ansariel> GetIfModified request
void HttpOptions::setLastModified(long last_modified)
{
mLastModified = last_modified;
}
// </FS:Ansariel>
} // end namespace LLCore

View File

@ -177,6 +177,14 @@ public:
{
return mNoBody;
}
// <FS:Ansariel> GetIfModified request
void setLastModified(long last_modified);
long getLastModified() const
{
return mLastModified;
}
// </FS:Ansariel>
protected:
bool mWantHeaders;
@ -192,6 +200,7 @@ protected:
bool mVerifyHost;
int mDNSCacheTimeout;
bool mNoBody;
long mLastModified; // <FS:Ansariel> GetIfModified request
}; // end class HttpOptions

View File

@ -116,13 +116,38 @@ namespace FSCoreHttpUtil
boost::bind(trivialGetCoroRaw, url, LLCore::HttpRequest::DEFAULT_POLICY_ID, aHeader, options, success, failure));
}
LLCore::HttpHeaders::ptr_t createModifiedSinceHeader( time_t aTime )
void trivialGetCoro(const std::string &url, const time_t& last_modified, completionCallback_t success, completionCallback_t failure)
{
std::string strDate = LLDate::toHTTPDateString( gmtime( &aTime ), "%A, %d %b %Y %H:%M:%S GMT" );
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("trivialGetCoro", LLCore::HttpRequest::DEFAULT_POLICY_ID));
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
LLCore::HttpHeaders::ptr_t pHeader( new LLCore::HttpHeaders() );
pHeader->append( "If-Modified-Since", strDate );
return pHeader;
httpOpts->setWantHeaders(true);
httpOpts->setLastModified((long)last_modified);
LLSD result = httpAdapter->getAndSuspend(httpRequest, url, httpOpts);
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (!status)
{
if (failure)
{
failure(httpResults);
}
}
else
{
if (success)
{
success(result);
}
}
}
void callbackHttpGet(const std::string &url, const time_t& last_modified, completionCallback_t success, completionCallback_t failure)
{
LLCoros::instance().launch("HttpCoroutineAdapter::genericGetCoro", boost::bind(&trivialGetCoro, url, last_modified, success, failure));
}
}

View File

@ -38,10 +38,12 @@ namespace FSCoreHttpUtil
LLCore::HttpHeaders::ptr_t aHeader = LLCore::HttpHeaders::ptr_t(), LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t());
void callbackHttpGetRaw(const std::string &url, completionCallback_t success = NULL, completionCallback_t failure = NULL,
LLCore::HttpHeaders::ptr_t aHeader = LLCore::HttpHeaders::ptr_t(), LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t());
void callbackHttpGet(const std::string &url, const time_t& last_modified, completionCallback_t success, completionCallback_t failure);
void trivialGetCoroRaw(std::string url, LLCore::HttpRequest::policy_t policyId, LLCore::HttpHeaders::ptr_t aHeader, LLCore::HttpOptions::ptr_t options, completionCallback_t success, completionCallback_t failure);
void trivialPostCoroRaw(std::string url, LLCore::HttpRequest::policy_t policyId, LLCore::BufferArray::ptr_t postData, LLCore::HttpHeaders::ptr_t aHeader, LLCore::HttpOptions::ptr_t options,
completionCallback_t success, completionCallback_t failure);
void trivialGetCoro(const std::string &url, const time_t& last_modified, completionCallback_t success, completionCallback_t failure);
}
#endif // FS_COREHTTPUTIL_H

View File

@ -237,14 +237,14 @@ void downloadCompleteScript( LLSD const &aData, std::string const &aURL, std::st
{
LL_DEBUGS() << aData << LL_ENDL;
LLSD header = aData[ LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS ][ LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD( aData[ LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS ] );
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD( aData[ LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS ] );
LLDate lastModified;
if (header.has("last-modified"))
{
lastModified.secondsSinceEpoch( FSCommon::secondsSinceEpochFromString( "%a, %d %b %Y %H:%M:%S %ZP", header["last-modified"].asString() ) );
}
const LLSD::Binary &rawData = aData[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
const LLSD::Binary &rawData = aData[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
if ( status.getType() == HTTP_NOT_MODIFIED )
{
@ -285,7 +285,19 @@ void downloadCompleteScript( LLSD const &aData, std::string const &aURL, std::st
void downloadError( LLSD const &aData, std::string const &aURL )
{
LL_WARNS() << "Failed to download " << aURL << ": " << aData << LL_ENDL;
// FSData::getInstance()->processResponder(getContent(), mURL, false, mLastModified);
FSData::instance().checkDone(aURL);
}
void FSData::checkDone(const std::string& url)
{
if (url == mFSDataURL)
{
mFSDataDone = true;
}
else if (url == mAgentsURL)
{
mAgentsDone = true;
}
}
// call this just before the login screen and after the LLProxy has been setup.
@ -303,11 +315,8 @@ void FSData::startDownload()
last_modified = stat_data.st_mtime;
}
LL_INFOS("fsdata") << "Downloading data.xml from " << mFSDataURL << " with last modifed of " << last_modified << LL_ENDL;
FSCoreHttpUtil::callbackHttpGet(mFSDataURL, last_modified, boost::bind(downloadComplete, _1, mFSDataURL), boost::bind(downloadError, _1, mFSDataURL));
LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet( mFSDataURL, boost::bind( downloadComplete, _1, mFSDataURL ), boost::bind( downloadError, _1, mFSDataURL ) );
//LLHTTPClient::getIfModified(mFSDataURL, new FSDownloader(mFSDataURL), last_modified, mHeaders, HTTP_TIMEOUT);
last_modified = 0;
if(!LLFile::stat(mFSdataDefaultsFilename, &stat_data))
{
@ -316,7 +325,7 @@ void FSData::startDownload()
std::string filename = llformat("defaults.%s.xml", LLVersionInfo::getShortVersion().c_str());
mFSdataDefaultsUrl = mBaseURL + "/" + filename;
LL_INFOS("fsdata") << "Downloading defaults.xml from " << mFSdataDefaultsUrl << " with last modifed of " << last_modified << LL_ENDL;
LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet( mFSdataDefaultsUrl, boost::bind( downloadComplete, _1, mFSdataDefaultsUrl ), boost::bind( downloadError, _1, mFSdataDefaultsUrl ) );
FSCoreHttpUtil::callbackHttpGet(mFSdataDefaultsUrl, last_modified, boost::bind(downloadComplete, _1, mFSdataDefaultsUrl), boost::bind(downloadError, _1, mFSdataDefaultsUrl));
#if OPENSIM
std::string filenames[] = {"scriptlibrary_ossl.xml", "scriptlibrary_aa.xml"};
@ -330,7 +339,10 @@ void FSData::startDownload()
}
std::string url = mBaseURL + "/" + script_name;
LL_INFOS("fsdata") << "Downloading " << script_name << " from " << url << " with last modifed of " << last_modified << LL_ENDL;
FSCoreHttpUtil::callbackHttpGetRaw( url, boost::bind( downloadCompleteScript, _1, url, filename ), boost::bind( downloadError, _1, url ) );
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
httpOpts->setWantHeaders(true);
httpOpts->setLastModified((long)last_modified);
FSCoreHttpUtil::callbackHttpGetRaw( url, boost::bind( downloadCompleteScript, _1, url, filename ), boost::bind( downloadError, _1, url ), LLCore::HttpHeaders::ptr_t(), httpOpts);
}
#endif
}
@ -375,8 +387,8 @@ void FSData::downloadAgents()
last_modified = stat_data.st_mtime;
}
LL_INFOS("fsdata") << "Downloading agents.xml from " << mAgentsURL << " with last modifed of " << last_modified << LL_ENDL;
LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet( mAgentsURL, boost::bind( downloadComplete, _1, mAgentsURL ), boost::bind( downloadError, _1, mAgentsURL ) );
FSCoreHttpUtil::callbackHttpGet(mAgentsURL, last_modified, boost::bind(downloadComplete, _1, mAgentsURL), boost::bind(downloadError, _1, mAgentsURL));
if (mAssetsURL.empty())
{
return;
@ -389,7 +401,7 @@ void FSData::downloadAgents()
last_modified = stat_data.st_mtime;
}
LL_INFOS("fsdata") << "Downloading assets.xml from " << mAssetsURL << " with last modifed of " << last_modified << LL_ENDL;
LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet( mAssetsURL, boost::bind( downloadComplete, _1, mAssetsURL ), boost::bind( downloadError, _1, mAssetsURL ) );
FSCoreHttpUtil::callbackHttpGet(mAssetsURL, last_modified, boost::bind(downloadComplete, _1, mAssetsURL), boost::bind(downloadError, _1, mAssetsURL));
}
void FSData::processData(const LLSD& fs_data)
@ -455,7 +467,7 @@ void FSData::processData(const LLSD& fs_data)
last_modified = stat_data.st_mtime;
}
LL_INFOS("fsdata") << "Downloading client_list_v2.xml from " << LEGACY_CLIENT_LIST_URL << " with last modifed of " << last_modified << LL_ENDL;
LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet( LEGACY_CLIENT_LIST_URL, boost::bind( downloadComplete, _1, LEGACY_CLIENT_LIST_URL ), boost::bind( downloadError, _1, LEGACY_CLIENT_LIST_URL ) );
FSCoreHttpUtil::callbackHttpGet(LEGACY_CLIENT_LIST_URL, last_modified, boost::bind(downloadComplete, _1, LEGACY_CLIENT_LIST_URL), boost::bind(downloadError, _1, LEGACY_CLIENT_LIST_URL));
}
else if(use_legacy_tags)
{

View File

@ -79,9 +79,9 @@ public:
std::string getOpenSimMOTD() { return mOpensimMOTD; }
bool getFSDataDone() { return mFSDataDone; }
bool getAgentsDone() { return mAgentsDone; }
void checkDone(const std::string& url);
bool isAgentFlag(const LLUUID& agent_id, FSData::flags_t flag);
private:
static void sendInfo(const LLUUID& destination, const LLUUID& sessionid, const std::string& my_name, EInstantMessage dialog);

View File

@ -375,6 +375,7 @@ void downloadGridlistComplete( LLSD const &aData )
void downloadGridlistError( LLSD const &aData, std::string const &aURL )
{
LL_WARNS() << "Failed to download grid list from " << aURL << LL_ENDL;
sGridListRequestReady = true;
}
void downloadGridstatusComplete( LLSD const &aData )
@ -884,7 +885,7 @@ bool idle_startup()
}
std::string url = gSavedSettings.getString("GridListDownloadURL");
LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet( url, boost::bind( downloadGridlistComplete, _1 ), boost::bind( downloadGridlistError, _1, url ) );
FSCoreHttpUtil::callbackHttpGet(url, last_modified, boost::bind(downloadGridlistComplete, _1), boost::bind(downloadGridlistError, _1, url));
}
#ifdef OPENSIM // <FS:AW optional opensim support>
// Fetch grid infos as needed