diff options
Diffstat (limited to 'indra')
-rwxr-xr-x | indra/llcorehttp/_httpoprequest.cpp | 4 | ||||
-rwxr-xr-x | indra/llcorehttp/httpresponse.cpp | 3 | ||||
-rwxr-xr-x | indra/llcorehttp/httpresponse.h | 11 | ||||
-rwxr-xr-x | indra/llmessage/llavatarnamecache.cpp | 286 | ||||
-rwxr-xr-x | indra/llmessage/llavatarnamecache.h | 7 | ||||
-rw-r--r-- | indra/llmessage/llcorehttputil.cpp | 96 | ||||
-rw-r--r-- | indra/llmessage/llcorehttputil.h | 30 | ||||
-rw-r--r-- | indra/llmessage/llhttpsdhandler.cpp | 12 | ||||
-rw-r--r-- | indra/llmessage/llhttpsdhandler.h | 11 | ||||
-rwxr-xr-x | indra/newview/llagent.cpp | 55 | ||||
-rwxr-xr-x | indra/newview/llagent.h | 10 | ||||
-rwxr-xr-x | indra/newview/llappearancemgr.cpp | 8 | ||||
-rwxr-xr-x | indra/newview/llmaterialmgr.cpp | 14 |
13 files changed, 405 insertions, 142 deletions
diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index 5768fe5a90..7c2309b31d 100755 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -260,7 +260,9 @@ void HttpOpRequest::visitNotifier(HttpRequest * request) response->setStatus(mStatus); response->setBody(mReplyBody); response->setHeaders(mReplyHeaders); - if (mReplyOffset || mReplyLength) + response->setRequestURL(mReqURL); + + if (mReplyOffset || mReplyLength) { // Got an explicit offset/length in response response->setRange(mReplyOffset, mReplyLength, mReplyFullLength); diff --git a/indra/llcorehttp/httpresponse.cpp b/indra/llcorehttp/httpresponse.cpp index 87e3426415..7d88f02527 100755 --- a/indra/llcorehttp/httpresponse.cpp +++ b/indra/llcorehttp/httpresponse.cpp @@ -41,7 +41,8 @@ HttpResponse::HttpResponse() mBufferArray(NULL), mHeaders(NULL), mRetries(0U), - m503Retries(0U) + m503Retries(0U), + mRequestUrl() {} diff --git a/indra/llcorehttp/httpresponse.h b/indra/llcorehttp/httpresponse.h index 39b582ff85..6c3b4da5e6 100755 --- a/indra/llcorehttp/httpresponse.h +++ b/indra/llcorehttp/httpresponse.h @@ -194,6 +194,16 @@ public: return mStats; } + void setRequestURL(const std::string &url) + { + mRequestUrl = url; + } + + const std::string &getRequestURL() const + { + return mRequestUrl; + } + protected: // Response data here @@ -206,6 +216,7 @@ protected: std::string mContentType; unsigned int mRetries; unsigned int m503Retries; + std::string mRequestUrl; TransferStats::ptr_t mStats; }; diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index d02a60b7b2..88859819e0 100755 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -33,9 +33,18 @@ #include "llhttpclient.h" #include "llsd.h" #include "llsdserialize.h" - +#include "httpresponse.h" +#include "llhttpsdhandler.h" #include <boost/tokenizer.hpp> +#include "httpcommon.h" +#include "httprequest.h" +#include "httpheaders.h" +#include "httpoptions.h" +#include "llcoros.h" +#include "lleventcoro.h" +#include "llcorehttputil.h" + #include <map> #include <set> @@ -90,6 +99,12 @@ namespace LLAvatarNameCache // Time-to-live for a temp cache entry. const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0; + LLCore::HttpRequest::ptr_t sHttpRequest; + LLCore::HttpHeaders::ptr_t sHttpHeaders; + LLCore::HttpOptions::ptr_t sHttpOptions; + LLCore::HttpRequest::policy_t sHttpPolicy; + LLCore::HttpRequest::priority_t sHttpPriority; + //----------------------------------------------------------------------- // Internal methods //----------------------------------------------------------------------- @@ -121,7 +136,13 @@ namespace LLAvatarNameCache // Erase expired names from cache void eraseUnrefreshed(); - bool expirationFromCacheControl(const LLSD& headers, F64 *expires); + //bool expirationFromCacheControl(LLCore::HttpHeaders *headers, F64 *expires); + bool expirationFromCacheControl(const LLSD& headers, F64 *expires); + + // This is a coroutine. The only parameter that can be specified as a reference is the self + void requestAvatarNameCache_(LLCoros::self& self, std::string url, std::vector<LLUUID> agentIds); + + void handleAvNameCacheSuccess(const LLSD &data, const LLSD &httpResult); } /* Sample response: @@ -163,94 +184,125 @@ namespace LLAvatarNameCache </llsd> */ -class LLAvatarNameResponder : public LLHTTPClient::Responder +// Coroutine for sending and processing avatar name cache requests. +// Do not call directly. See documentation in lleventcoro.h and llcoro.h for +// further explanation. +void LLAvatarNameCache::requestAvatarNameCache_(LLCoros::self& self, std::string url, std::vector<LLUUID> agentIds) { - LOG_CLASS(LLAvatarNameResponder); -private: - // need to store agent ids that are part of this request in case of - // an error, so we can flag them as unavailable - std::vector<LLUUID> mAgentIDs; - -public: - LLAvatarNameResponder(const std::vector<LLUUID>& agent_ids) - : mAgentIDs(agent_ids) - { } - -protected: - /*virtual*/ void httpSuccess() - { - const LLSD& content = getContent(); - if (!content.isMap()) - { - failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content); - return; - } - // Pull expiration out of headers if available - F64 expires = LLAvatarNameCache::nameExpirationFromHeaders(getResponseHeaders()); - F64 now = LLFrameTimer::getTotalSeconds(); + LLEventStream replyPump("NameCacheReply", true); + LLCoreHttpUtil::HttpCoroHandler::ptr_t httpHandler = + LLCoreHttpUtil::HttpCoroHandler::ptr_t(new LLCoreHttpUtil::HttpCoroHandler(replyPump)); - const LLSD& agents = content["agents"]; - LLSD::array_const_iterator it = agents.beginArray(); - for ( ; it != agents.endArray(); ++it) - { - const LLSD& row = *it; - LLUUID agent_id = row["id"].asUUID(); + LL_DEBUGS("AvNameCache") << "Entering coroutine " << LLCoros::instance().getName(self) + << " with url '" << url << "', requesting " << agentIds.size() << " Agent Ids" << LL_ENDL; - LLAvatarName av_name; - av_name.fromLLSD(row); + try + { + bool success = true; - // Use expiration time from header - av_name.mExpires = expires; + LLAvatarNameCache::sHttpRequest->requestGet( + LLAvatarNameCache::sHttpPolicy, LLAvatarNameCache::sHttpPriority, + url, LLAvatarNameCache::sHttpOptions.get(), + LLAvatarNameCache::sHttpHeaders.get(), httpHandler.get()); - LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << LL_ENDL; - av_name.dump(); - - // cache it and fire signals - LLAvatarNameCache::processName(agent_id, av_name); - } + LLSD results = waitForEventOn(self, replyPump); + LLSD httpResults; - // Same logic as error response case - const LLSD& unresolved_agents = content["bad_ids"]; - S32 num_unresolved = unresolved_agents.size(); - if (num_unresolved > 0) - { - LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result " << num_unresolved << " unresolved ids; " - << "expires in " << expires - now << " seconds" - << LL_ENDL; - it = unresolved_agents.beginArray(); - for ( ; it != unresolved_agents.endArray(); ++it) - { - const LLUUID& agent_id = *it; + LL_DEBUGS() << results << LL_ENDL; - LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result " - << "failed id " << agent_id - << LL_ENDL; + if (!results.isMap()) + { + LL_WARNS("AvNameCache") << " Invalid result returned from LLCoreHttpUtil::HttpCoroHandler." << LL_ENDL; + success = false; + } + else + { + httpResults = results["http_result"]; + success = httpResults["success"].asBoolean(); + if (!success) + { + LL_WARNS("AvNameCache") << "Error result from LLCoreHttpUtil::HttpCoroHandler. Code " + << httpResults["status"] << ": '" << httpResults["message"] << "'" << LL_ENDL; + } + } + if (!success) + { // on any sort of failure add dummy records for any agent IDs + // in this request that we do not have cached already + std::vector<LLUUID>::const_iterator it = agentIds.begin(); + for ( ; it != agentIds.end(); ++it) + { + const LLUUID& agent_id = *it; LLAvatarNameCache::handleAgentError(agent_id); - } - } - LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result " - << LLAvatarNameCache::sCache.size() << " cached names" - << LL_ENDL; + } + return; + } + + LLAvatarNameCache::handleAvNameCacheSuccess(results, httpResults); + } + catch (std::exception e) + { + LL_WARNS() << "Caught exception '" << e.what() << "'" << LL_ENDL; + } + catch (...) + { + LL_WARNS() << "Caught unknown exception." << LL_ENDL; + } +} - /*virtual*/ void httpFailure() - { - // If there's an error, it might be caused by PeopleApi, - // or when loading textures on startup and using a very slow - // network, this query may time out. - // What we should do depends on whether or not we have a cached name - LL_WARNS("AvNameCache") << dumpResponse() << LL_ENDL; - - // Add dummy records for any agent IDs in this request that we do not have cached already - std::vector<LLUUID>::const_iterator it = mAgentIDs.begin(); - for ( ; it != mAgentIDs.end(); ++it) - { - const LLUUID& agent_id = *it; - LLAvatarNameCache::handleAgentError(agent_id); - } - } -}; +void LLAvatarNameCache::handleAvNameCacheSuccess(const LLSD &data, const LLSD &httpResult) +{ + + LLSD headers = httpResult["headers"]; + // Pull expiration out of headers if available + F64 expires = LLAvatarNameCache::nameExpirationFromHeaders(headers); + F64 now = LLFrameTimer::getTotalSeconds(); + + const LLSD& agents = data["agents"]; + LLSD::array_const_iterator it = agents.beginArray(); + for (; it != agents.endArray(); ++it) + { + const LLSD& row = *it; + LLUUID agent_id = row["id"].asUUID(); + + LLAvatarName av_name; + av_name.fromLLSD(row); + + // Use expiration time from header + av_name.mExpires = expires; + + LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << LL_ENDL; + av_name.dump(); + + // cache it and fire signals + LLAvatarNameCache::processName(agent_id, av_name); + } + + // Same logic as error response case + const LLSD& unresolved_agents = data["bad_ids"]; + S32 num_unresolved = unresolved_agents.size(); + if (num_unresolved > 0) + { + LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result " << num_unresolved << " unresolved ids; " + << "expires in " << expires - now << " seconds" + << LL_ENDL; + it = unresolved_agents.beginArray(); + for (; it != unresolved_agents.endArray(); ++it) + { + const LLUUID& agent_id = *it; + + LL_WARNS("AvNameCache") << "LLAvatarNameResponder::result " + << "failed id " << agent_id + << LL_ENDL; + + LLAvatarNameCache::handleAgentError(agent_id); + } + } + LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result " + << LLAvatarNameCache::sCache.size() << " cached names" + << LL_ENDL; +} // Provide some fallback for agents that return errors void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id) @@ -353,12 +405,17 @@ void LLAvatarNameCache::requestNamesViaCapability() } } - if (!url.empty()) - { - LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability requested " - << ids << " ids" - << LL_ENDL; - LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids)); + if (!url.empty()) + { + LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaCapability requested " + << ids << " ids" + << LL_ENDL; + + std::string coroname = + LLCoros::instance().launch("LLAvatarNameCache::requestAvatarNameCache_", + boost::bind(&LLAvatarNameCache::requestAvatarNameCache_, _1, url, agent_ids)); + LL_DEBUGS("AvNameCache") << coroname << " with url '" << url << "', agent_ids.size()=" << agent_ids.size() << LL_ENDL; + } } @@ -422,11 +479,20 @@ void LLAvatarNameCache::initClass(bool running, bool usePeopleAPI) { sRunning = running; sUsePeopleAPI = usePeopleAPI; + + sHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest()); + sHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false); + sHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false); + sHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID; + sHttpPriority = 0; } void LLAvatarNameCache::cleanupClass() { - sCache.clear(); + sHttpRequest.reset(); + sHttpHeaders.reset(); + sHttpOptions.reset(); + sCache.clear(); } void LLAvatarNameCache::importFile(std::istream& istr) @@ -498,6 +564,8 @@ void LLAvatarNameCache::idle() // By convention, start running at first idle() call sRunning = true; + sHttpRequest->update(0L); + // *TODO: Possibly re-enabled this based on People API load measurements // 100 ms is the threshold for "user speed" operations, so we can // stall for about that long to batch up requests. @@ -697,6 +765,50 @@ void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_na sCache[agent_id] = av_name; } +#if 0 +F64 LLAvatarNameCache::nameExpirationFromHeaders(LLCore::HttpHeaders *headers) +{ + F64 expires = 0.0; + if (expirationFromCacheControl(headers, &expires)) + { + return expires; + } + else + { + // With no expiration info, default to an hour + const F64 DEFAULT_EXPIRES = 60.0 * 60.0; + F64 now = LLFrameTimer::getTotalSeconds(); + return now + DEFAULT_EXPIRES; + } +} + +bool LLAvatarNameCache::expirationFromCacheControl(LLCore::HttpHeaders *headers, F64 *expires) +{ + bool fromCacheControl = false; + F64 now = LLFrameTimer::getTotalSeconds(); + + // Allow the header to override the default + const std::string *cache_control; + + cache_control = headers->find(HTTP_IN_HEADER_CACHE_CONTROL); + + if (cache_control && !cache_control->empty()) + { + S32 max_age = 0; + if (max_age_from_cache_control(*cache_control, &max_age)) + { + *expires = now + (F64)max_age; + fromCacheControl = true; + } + } + LL_DEBUGS("AvNameCache") + << ( fromCacheControl ? "expires based on cache control " : "default expiration " ) + << "in " << *expires - now << " seconds" + << LL_ENDL; + + return fromCacheControl; +} +#else F64 LLAvatarNameCache::nameExpirationFromHeaders(const LLSD& headers) { F64 expires = 0.0; @@ -741,7 +853,7 @@ bool LLAvatarNameCache::expirationFromCacheControl(const LLSD& headers, F64 *exp return fromCacheControl; } - +#endif void LLAvatarNameCache::addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb) { diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index ea016b3125..fdfd4e972d 100755 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -29,7 +29,8 @@ #define LLAVATARNAMECACHE_H #include "llavatarname.h" // for convenience - +//#include "httpcommon.h" +//#include "httpheaders.h" #include <boost/signals2.hpp> class LLSD; @@ -49,7 +50,7 @@ namespace LLAvatarNameCache void importFile(std::istream& istr); void exportFile(std::ostream& ostr); - // On the viewer, usually a simulator capabilitity. + // On the viewer, usually a simulator capabilities. // If empty, name cache will fall back to using legacy name lookup system. void setNameLookupURL(const std::string& name_lookup_url); @@ -90,7 +91,7 @@ namespace LLAvatarNameCache // Compute name expiration time from HTTP Cache-Control header, // or return default value, in seconds from epoch. - F64 nameExpirationFromHeaders(const LLSD& headers); + F64 nameExpirationFromHeaders(const LLSD& headers); void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb); } diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp index 366a0b9460..991985b1cf 100644 --- a/indra/llmessage/llcorehttputil.cpp +++ b/indra/llmessage/llcorehttputil.cpp @@ -30,15 +30,17 @@ #include <sstream> #include "llcorehttputil.h" +#include "llhttpconstants.h" #include "llsdserialize.h" - using namespace LLCore; namespace LLCoreHttpUtil { + + // *TODO: Currently converts only from XML content. A mode // to convert using fromBinary() might be useful as well. Mesh // headers could use it. @@ -186,5 +188,97 @@ std::string responseToString(LLCore::HttpResponse * response) } +HttpCoroHandler::HttpCoroHandler(LLEventStream &reply) : + mReplyPump(reply) +{ +} + +void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response) +{ + LLSD result; + + LLCore::HttpStatus status = response->getStatus(); + + if (!status) + { + result = LLSD::emptyMap(); + LL_WARNS() + << "\n--------------------------------------------------------------------------\n" + << " Error[" << status.toULong() << "] cannot access url '" << response->getRequestURL() + << "' because " << status.toString() + << "\n--------------------------------------------------------------------------" + << LL_ENDL; + + } + else + { + const bool emit_parse_errors = false; + + bool parsed = !((response->getBodySize() == 0) || + !LLCoreHttpUtil::responseToLLSD(response, emit_parse_errors, result)); + + if (!parsed) + { + // Only emit a warning if we failed to parse when 'content-type' == 'application/llsd+xml' + LLCore::HttpHeaders::ptr_t headers(response->getHeaders()); + const std::string *contentType = (headers) ? headers->find(HTTP_IN_HEADER_CONTENT_TYPE) : NULL; + + if (contentType && (HTTP_CONTENT_LLSD_XML == *contentType)) + { + std::string thebody = LLCoreHttpUtil::responseToString(response); + LL_WARNS() << "Failed to deserialize . " << response->getRequestURL() << " [status:" << response->getStatus().toString() << "] " + << " body: " << thebody << LL_ENDL; + + // Replace the status with a new one indicating the failure. + status = LLCore::HttpStatus(499, "Failed to deserialize LLSD."); + } + } + + if (result.isUndefined()) + { + // If we've gotten to this point and the result LLSD is still undefined + // either there was an issue deserializing the body or the response was + // blank. Create an empty map to hold the result either way. + result = LLSD::emptyMap(); + } + } + + buildStatusEntry(response, status, result); + mReplyPump.post(result); +} + +void HttpCoroHandler::buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result) +{ + LLSD httpresults = LLSD::emptyMap(); + + httpresults["success"] = static_cast<LLSD::Boolean>(status); + httpresults["type"] = static_cast<LLSD::Integer>(status.getType()); + httpresults["status"] = static_cast<LLSD::Integer>(status.getStatus()); + httpresults["message"] = static_cast<LLSD::String>(status.getMessage()); + httpresults["url"] = static_cast<LLSD::String>(response->getRequestURL()); + + LLSD httpHeaders = LLSD::emptyMap(); + LLCore::HttpHeaders * hdrs = response->getHeaders(); + + if (hdrs) + { + for (LLCore::HttpHeaders::iterator it = hdrs->begin(); it != hdrs->end(); ++it) + { + if (!(*it).second.empty()) + { + httpHeaders[(*it).first] = (*it).second; + } + else + { + httpHeaders[(*it).first] = static_cast<LLSD::Boolean>(true); + } + } + } + + httpresults["headers"] = httpHeaders; + result["http_result"] = httpresults; +} + + } // end namespace LLCoreHttpUtil diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h index 8e26f413fe..0bc102a0a3 100644 --- a/indra/llmessage/llcorehttputil.h +++ b/indra/llmessage/llcorehttputil.h @@ -39,6 +39,7 @@ #include "bufferarray.h" #include "bufferstream.h" #include "llsd.h" +#include "llevents.h" /// /// The base llcorehttp library implements many HTTP idioms @@ -152,6 +153,35 @@ LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request, LLCore::HttpHeaders::ptr_t & headers, LLCore::HttpHandler * handler); +/// The HttpCoroHandler is a specialization of the LLCore::HttpHandler for +/// interacting with coroutines. When the request is completed the response +/// will be posted onto the supplied Event Pump. +/// +/// The LLSD posted back to the coroutine will have the following additions: +/// llsd["http_result"] -+- ["message"] - An error message returned from the HTTP status +/// +- ["status"] - The status code associated with the HTTP call +/// +- ["success"] - Success of failure of the HTTP call and LLSD parsing. +/// +- ["type"] - The LLCore::HttpStatus type associted with the HTTP call +/// +- ["url"] - The URL used to make the call. +/// +- ["headers"] - A map of name name value pairs with the HTTP headers. +/// + +/// +class HttpCoroHandler : public LLCore::HttpHandler +{ +public: + HttpCoroHandler(LLEventStream &reply); + + virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); + + typedef boost::shared_ptr<HttpCoroHandler> ptr_t; + +private: + void buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result); + + LLEventStream &mReplyPump; +}; + } // end namespace LLCoreHttpUtil diff --git a/indra/llmessage/llhttpsdhandler.cpp b/indra/llmessage/llhttpsdhandler.cpp index 72ecfe77e2..159d03b176 100644 --- a/indra/llmessage/llhttpsdhandler.cpp +++ b/indra/llmessage/llhttpsdhandler.cpp @@ -36,10 +36,8 @@ #include "llcorehttputil.h" //======================================================================== -LLHttpSDHandler::LLHttpSDHandler(const LLURI &uri): - mUri(uri) +LLHttpSDHandler::LLHttpSDHandler() { - } void LLHttpSDHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response) @@ -68,7 +66,7 @@ void LLHttpSDHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons { std::string thebody = LLCoreHttpUtil::responseToString(response); - LL_WARNS() << "Failed to deserialize . " << getUri() << " [status:" << response->getStatus().toString() << "] " + LL_WARNS() << "Failed to deserialize . " << response->getRequestURL() << " [status:" << response->getStatus().toString() << "] " << " body: " << thebody << LL_ENDL; } } @@ -83,8 +81,8 @@ void LLHttpSDHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons } //======================================================================== -LLHttpSDGenericHandler::LLHttpSDGenericHandler(const LLURI &uri, const std::string &caps) : - LLHttpSDHandler(uri), +LLHttpSDGenericHandler::LLHttpSDGenericHandler(const std::string &caps) : + LLHttpSDHandler(), mCaps(caps) { } @@ -99,7 +97,7 @@ void LLHttpSDGenericHandler::onFailure(LLCore::HttpResponse * response, LLCore:: LL_WARNS() << "\n--------------------------------------------------------------------------\n" << mCaps << " Error[" << status.toULong() << "] cannot access cap with url '" - << getUri() << "' because " << status.toString() + << response->getRequestURL() << "' because " << status.toString() << "\n--------------------------------------------------------------------------" << LL_ENDL; } diff --git a/indra/llmessage/llhttpsdhandler.h b/indra/llmessage/llhttpsdhandler.h index a2598c9709..7c28dbcab6 100644 --- a/indra/llmessage/llhttpsdhandler.h +++ b/indra/llmessage/llhttpsdhandler.h @@ -39,21 +39,14 @@ class LLHttpSDHandler : public LLCore::HttpHandler { public: - LLHttpSDHandler(const LLURI &uri); + LLHttpSDHandler(); virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); - inline const LLURI &getUri() const - { - return mUri; - } - protected: virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content) = 0; virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status) = 0; -private: - LLURI mUri; }; /// A trivial implementation of LLHttpSDHandler. This success and failure @@ -62,7 +55,7 @@ private: class LLHttpSDGenericHandler : public LLHttpSDHandler { public: - LLHttpSDGenericHandler(const LLURI &uri, const std::string &action); + LLHttpSDGenericHandler(const std::string &action); protected: virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content); diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 667d530e39..eeedda5c6d 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -325,7 +325,6 @@ bool LLAgent::isMicrophoneOn(const LLSD& sdname) // For a toggled version, see viewer.h for the // TOGGLE_HACKED_GODLIKE_VIEWER define, instead. // ************************************************************ -bool LLAgent::mActive = true; // Constructors and Destructors @@ -474,7 +473,9 @@ void LLAgent::init() mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false); mHttpPolicy = app_core_http.getPolicy(LLAppCoreHttp::AP_AGENT); - doOnIdleRepeating(boost::bind(&LLAgent::onIdle, this)); + // Now ensure that we get regular callbacks to poll for completion. + mBoundListener = LLEventPumps::instance().obtain("mainloop"). + listen(LLEventPump::inventName(), boost::bind(&LLAgent::pollHttp, this, _1)); mInitialized = TRUE; } @@ -484,7 +485,6 @@ void LLAgent::init() //----------------------------------------------------------------------------- void LLAgent::cleanup() { - mActive = false; mRegionp = NULL; if (mTeleportFinishedSlot.connected()) { @@ -494,6 +494,10 @@ void LLAgent::cleanup() { mTeleportFailedSlot.disconnect(); } + if (mBoundListener.connected()) + { + mBoundListener.disconnect(); + } } //----------------------------------------------------------------------------- @@ -517,16 +521,16 @@ LLAgent::~LLAgent() } //----------------------------------------------------------------------------- -// Idle processing +// pollHttp +// Polling done once per frame on the "mainloop" to support HTTP processing. //----------------------------------------------------------------------------- -bool LLAgent::onIdle() +bool LLAgent::pollHttp(const LLSD&) { - if (!LLAgent::mActive) - return true; - mHttpRequest->update(0L); - return false; + mHttpRequest->update(0L); + return false; } + // Handle any actions that need to be performed when the main app gains focus // (such as through alt-tab). //----------------------------------------------------------------------------- @@ -2548,8 +2552,8 @@ int LLAgent::convertTextToMaturity(char text) class LLMaturityHttpHandler : public LLHttpSDHandler { public: - LLMaturityHttpHandler(const std::string& capabilityURL, LLAgent *agent, U8 preferred, U8 previous): - LLHttpSDHandler(capabilityURL), + LLMaturityHttpHandler(LLAgent *agent, U8 preferred, U8 previous): + LLHttpSDHandler(), mAgent(agent), mPreferredMaturity(preferred), mPreviousMaturity(previous) @@ -2764,7 +2768,7 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity) return; } - LLMaturityHttpHandler * handler = new LLMaturityHttpHandler(url, this, pPreferredMaturity, mLastKnownResponseMaturity); + LLMaturityHttpHandler * handler = new LLMaturityHttpHandler(this, pPreferredMaturity, mLastKnownResponseMaturity); LLSD access_prefs = LLSD::emptyMap(); access_prefs["max"] = LLViewerRegion::accessToShortString(pPreferredMaturity); @@ -2779,14 +2783,14 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity) if (handle == LLCORE_HTTP_HANDLE_INVALID) { delete handler; - LL_WARNS("Avatar") << "Maturity request post failed." << LL_ENDL; + LL_WARNS("Agent") << "Maturity request post failed." << LL_ENDL; } } } LLCore::HttpHandle LLAgent::requestPostCapability(const std::string &cap, const std::string &url, LLSD &postData, LLHttpSDHandler *usrhndlr) { - LLHttpSDHandler * handler = (usrhndlr) ? usrhndlr : new LLHttpSDGenericHandler(url, cap); + LLHttpSDHandler * handler = (usrhndlr) ? usrhndlr : new LLHttpSDGenericHandler(cap); LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicy, mHttpPriority, url, postData, mHttpOptions, mHttpHeaders, handler); @@ -2799,16 +2803,31 @@ LLCore::HttpHandle LLAgent::requestPostCapability(const std::string &cap, const if (!usrhndlr) delete handler; LLCore::HttpStatus status = mHttpRequest->getStatus(); - LL_WARNS("Avatar") << "'" << cap << "' request POST failed. Reason " + LL_WARNS("Agent") << "'" << cap << "' request POST failed. Reason " << status.toTerseString() << " \"" << status.toString() << "\"" << LL_ENDL; } return handle; } -//LLCore::HttpHandle LLAgent::httpGetCapibility(const std::string &cap, const LLURI &uri, LLHttpSDHandler *usrhndlr) -//{ -//} +LLCore::HttpHandle LLAgent::requestGetCapability(const std::string &cap, const std::string &url, LLHttpSDHandler *usrhndlr) +{ + LLHttpSDHandler * handler = (usrhndlr) ? usrhndlr : new LLHttpSDGenericHandler(cap); + LLCore::HttpHandle handle = mHttpRequest->requestGet(mHttpPolicy, mHttpPriority, + url, mHttpOptions.get(), mHttpHeaders.get(), handler); + if (handle == LLCORE_HTTP_HANDLE_INVALID) + { + // If no handler was passed in we delete the handler default handler allocated + // at the start of this function. + // *TODO: Change this metaphore to use boost::shared_ptr<> for handlers. Requires change in LLCore::HTTP + if (!usrhndlr) + delete handler; + LLCore::HttpStatus status = mHttpRequest->getStatus(); + LL_WARNS("Agent") << "'" << cap << "' request GET failed. Reason " + << status.toTerseString() << " \"" << status.toString() << "\"" << LL_ENDL; + } + return handle; +} BOOL LLAgent::getAdminOverride() const { diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 26120b52f6..9ffc9b9a7a 100755 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -34,6 +34,7 @@ #include "llcoordframe.h" // for mFrameAgent #include "llavatarappearancedefines.h" #include "llpermissionsflags.h" +#include "llevents.h" #include "v3dmath.h" #include "httprequest.h" #include "httpheaders.h" @@ -117,9 +118,7 @@ public: void cleanup(); private: - bool onIdle(); - static bool mActive; //-------------------------------------------------------------------- // Login //-------------------------------------------------------------------- @@ -767,6 +766,7 @@ private: LLCore::HttpOptions::ptr_t mHttpOptions; LLCore::HttpRequest::policy_t mHttpPolicy; LLCore::HttpRequest::priority_t mHttpPriority; + LLTempBoundListener mBoundListener; bool isMaturityPreferenceSyncedWithServer() const; void sendMaturityPreferenceToServer(U8 pPreferredMaturity); @@ -781,6 +781,8 @@ private: void handleMaturity(const LLSD &pNewValue); bool validateMaturity(const LLSD& newvalue); + bool pollHttp(const LLSD &); + /** Access ** ** @@ -924,9 +926,9 @@ public: **/ public: /// Utilities for allowing the the agent sub managers to post and get via - /// HTTP using the agent's policy settings and headers. + /// HTTP using the agent's policy settings and headers. LLCore::HttpHandle requestPostCapability(const std::string &cap, const std::string &url, LLSD &postData, LLHttpSDHandler *usrhndlr = NULL); - //LLCore::HttpHandle httpGetCapability(const std::string &cap, const LLURI &uri, LLHttpSDHandler *usrhndlr = NULL); + LLCore::HttpHandle requestGetCapability(const std::string &cap, const std::string &url, LLHttpSDHandler *usrhndlr = NULL); /** Utility ** ** diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 709d9881e1..4fbcd90baa 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1249,8 +1249,8 @@ static void removeDuplicateItems(LLInventoryModel::item_array_t& items) class LLAppearanceMgrHttpHandler : public LLHttpSDHandler { public: - LLAppearanceMgrHttpHandler(const std::string& capabilityURL, LLAppearanceMgr *mgr) : - LLHttpSDHandler(capabilityURL), + LLAppearanceMgrHttpHandler(LLAppearanceMgr *mgr) : + LLHttpSDHandler(), mManager(mgr) { } @@ -1314,7 +1314,7 @@ void LLAppearanceMgrHttpHandler::onSuccess(LLCore::HttpResponse * response, cons void LLAppearanceMgrHttpHandler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status) { - LL_WARNS("Avatar") << "Appearance Mgr request failed to " << getUri() + LL_WARNS("Avatar") << "Appearance Mgr request failed to " << response->getRequestURL() << ". Reason code: (" << status.toTerseString() << ") " << status.toString() << LL_ENDL; } @@ -3434,7 +3434,7 @@ void LLAppearanceMgr::requestServerAppearanceUpdate() } LL_DEBUGS("Avatar") << "request url " << url << " my_cof_version " << cof_version << LL_ENDL; - LLAppearanceMgrHttpHandler * handler = new LLAppearanceMgrHttpHandler(url, this); + LLAppearanceMgrHttpHandler * handler = new LLAppearanceMgrHttpHandler(this); mInFlightCounter++; mInFlightTimer.setTimerExpirySec(60.0); diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp index 78fbe9af0a..8a726ec7c9 100755 --- a/indra/newview/llmaterialmgr.cpp +++ b/indra/newview/llmaterialmgr.cpp @@ -70,7 +70,7 @@ public: typedef boost::function<void(bool, const LLSD&)> CallbackFunction; typedef boost::shared_ptr<LLMaterialHttpHandler> ptr_t; - LLMaterialHttpHandler(const std::string& method, const std::string& capabilityURL, CallbackFunction cback); + LLMaterialHttpHandler(const std::string& method, CallbackFunction cback); virtual ~LLMaterialHttpHandler(); @@ -83,8 +83,8 @@ private: CallbackFunction mCallback; }; -LLMaterialHttpHandler::LLMaterialHttpHandler(const std::string& method, const std::string& capabilityURL, CallbackFunction cback): - LLHttpSDHandler(capabilityURL), +LLMaterialHttpHandler::LLMaterialHttpHandler(const std::string& method, CallbackFunction cback): + LLHttpSDHandler(), mMethod(method), mCallback(cback) { @@ -106,7 +106,7 @@ void LLMaterialHttpHandler::onFailure(LLCore::HttpResponse * response, LLCore::H LL_WARNS("Materials") << "\n--------------------------------------------------------------------------\n" << mMethod << " Error[" << status.toULong() << "] cannot access cap '" << MATERIALS_CAPABILITY_NAME - << "'\n with url '" << getUri() << "' because " << status.toString() + << "'\n with url '" << response->getRequestURL() << "' because " << status.toString() << "\n--------------------------------------------------------------------------" << LL_ENDL; @@ -653,7 +653,7 @@ void LLMaterialMgr::processGetQueue() postData[MATERIALS_CAP_ZIP_FIELD] = materialBinary; LLMaterialHttpHandler * handler = - new LLMaterialHttpHandler("POST", capURL, + new LLMaterialHttpHandler("POST", boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id) ); @@ -707,7 +707,7 @@ void LLMaterialMgr::processGetAllQueue() LL_DEBUGS("Materials") << "GET all for region " << region_id << "url " << capURL << LL_ENDL; LLMaterialHttpHandler *handler = - new LLMaterialHttpHandler("GET", capURL, + new LLMaterialHttpHandler("GET", boost::bind(&LLMaterialMgr::onGetAllResponse, this, _1, _2, *itRegion) ); @@ -810,7 +810,7 @@ void LLMaterialMgr::processPutQueue() LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL; LLMaterialHttpHandler * handler = - new LLMaterialHttpHandler("PUT", capURL, + new LLMaterialHttpHandler("PUT", boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2) ); |