diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index 5e3cb61e22..44d9f828d1 100644 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -539,6 +539,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service) long sslHostV(0L); long dnsCacheTimeout(-1L); long nobody(0L); + long last_modified(0L); // 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(); // 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); + // 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); + } + // + // 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 diff --git a/indra/llcorehttp/httpoptions.cpp b/indra/llcorehttp/httpoptions.cpp index df5aa52fa9..fa0b5a00c2 100644 --- a/indra/llcorehttp/httpoptions.cpp +++ b/indra/llcorehttp/httpoptions.cpp @@ -46,7 +46,8 @@ HttpOptions::HttpOptions() : mVerifyPeer(false), mVerifyHost(false), mDNSCacheTimeout(-1L), - mNoBody(false) + mNoBody(false), + mLastModified(0) // GetIfModified request {} @@ -125,4 +126,11 @@ void HttpOptions::setHeadersOnly(bool nobody) setWantHeaders(true); } +// GetIfModified request +void HttpOptions::setLastModified(long last_modified) +{ + mLastModified = last_modified; +} +// + } // end namespace LLCore diff --git a/indra/llcorehttp/httpoptions.h b/indra/llcorehttp/httpoptions.h index 8a6de61b04..59435328f3 100644 --- a/indra/llcorehttp/httpoptions.h +++ b/indra/llcorehttp/httpoptions.h @@ -177,6 +177,14 @@ public: { return mNoBody; } + + // GetIfModified request + void setLastModified(long last_modified); + long getLastModified() const + { + return mLastModified; + } + // protected: bool mWantHeaders; @@ -192,6 +200,7 @@ protected: bool mVerifyHost; int mDNSCacheTimeout; bool mNoBody; + long mLastModified; // GetIfModified request }; // end class HttpOptions diff --git a/indra/llmessage/fscorehttputil.cpp b/indra/llmessage/fscorehttputil.cpp index 5bb7109846..52ba06d2d3 100644 --- a/indra/llmessage/fscorehttputil.cpp +++ b/indra/llmessage/fscorehttputil.cpp @@ -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)); } } diff --git a/indra/llmessage/fscorehttputil.h b/indra/llmessage/fscorehttputil.h index c3f43fcdcb..f94032c226 100644 --- a/indra/llmessage/fscorehttputil.h +++ b/indra/llmessage/fscorehttputil.h @@ -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 diff --git a/indra/newview/fsdata.cpp b/indra/newview/fsdata.cpp index 0468d08681..30e8f0522e 100644 --- a/indra/newview/fsdata.cpp +++ b/indra/newview/fsdata.cpp @@ -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) { diff --git a/indra/newview/fsdata.h b/indra/newview/fsdata.h index 45c13ebca1..8cca1f48a6 100644 --- a/indra/newview/fsdata.h +++ b/indra/newview/fsdata.h @@ -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); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 22bef6aaea..dd2fe49d18 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -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 // // Fetch grid infos as needed