Added AvatarNameCache as coroutine, with LLCore::HttpHandler to respond correctly to Event Pumps.

Added get/setRequestURL() to LLCore::HttpResponse
Removed URI from the HttpSDHandler.
meow-7.2.2
Rider Linden 2015-04-01 16:37:00 -07:00
parent 0b02b36b65
commit edc1439bd6
13 changed files with 404 additions and 141 deletions

View File

@ -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);

View File

@ -41,7 +41,8 @@ HttpResponse::HttpResponse()
mBufferArray(NULL),
mHeaders(NULL),
mRetries(0U),
m503Retries(0U)
m503Retries(0U),
mRequestUrl()
{}

View File

@ -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;
};

View File

@ -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;
LLEventStream replyPump("NameCacheReply", true);
LLCoreHttpUtil::HttpCoroHandler::ptr_t httpHandler =
LLCoreHttpUtil::HttpCoroHandler::ptr_t(new LLCoreHttpUtil::HttpCoroHandler(replyPump));
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();
LL_DEBUGS("AvNameCache") << "Entering coroutine " << LLCoros::instance().getName(self)
<< " with url '" << url << "', requesting " << agentIds.size() << " Agent Ids" << LL_ENDL;
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();
try
{
bool success = true;
LLAvatarName av_name;
av_name.fromLLSD(row);
LLAvatarNameCache::sHttpRequest->requestGet(
LLAvatarNameCache::sHttpPolicy, LLAvatarNameCache::sHttpPriority,
url, LLAvatarNameCache::sHttpOptions.get(),
LLAvatarNameCache::sHttpHeaders.get(), httpHandler.get());
// Use expiration time from header
av_name.mExpires = expires;
LLSD results = waitForEventOn(self, replyPump);
LLSD httpResults;
LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << LL_ENDL;
av_name.dump();
// cache it and fire signals
LLAvatarNameCache::processName(agent_id, av_name);
}
LL_DEBUGS() << results << LL_ENDL;
// 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_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;
}
}
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);
}
/*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;
// 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;
// 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);
}
}
};
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)
{

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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
{

View File

@ -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
** **

View File

@ -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);

View File

@ -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)
);