summaryrefslogtreecommitdiff
path: root/indra/newview/llmediadataclient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llmediadataclient.cpp')
-rwxr-xr-xindra/newview/llmediadataclient.cpp563
1 files changed, 296 insertions, 267 deletions
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index 2fb9e60b29..bfd0700a2f 100755
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -33,6 +33,7 @@
#pragma warning (disable:4702)
#endif
+#include <algorithm>
#include <boost/lexical_cast.hpp>
#include "llhttpconstants.h"
@@ -40,6 +41,7 @@
#include "llmediaentry.h"
#include "lltextureentry.h"
#include "llviewerregion.h"
+#include "llcorehttputil.h"
//
// When making a request
@@ -91,52 +93,74 @@ const U32 LLMediaDataClient::MAX_ROUND_ROBIN_QUEUE_SIZE = 10000;
std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::request_queue_t &q);
std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::Request &q);
-template <typename T>
-typename T::iterator find_matching_request(T &c, const LLMediaDataClient::Request *request, LLMediaDataClient::Request::Type match_type)
+
+//=========================================================================
+/// Uniary Predicate for matching requests in collections by either the request
+/// or by UUID
+///
+class PredicateMatchRequest
{
- for(typename T::iterator iter = c.begin(); iter != c.end(); ++iter)
- {
- if(request->isMatch(*iter, match_type))
- {
- return iter;
- }
- }
-
- return c.end();
+public:
+ PredicateMatchRequest(const LLMediaDataClient::Request::ptr_t &request, LLMediaDataClient::Request::Type matchType = LLMediaDataClient::Request::ANY);
+ PredicateMatchRequest(const LLUUID &id, LLMediaDataClient::Request::Type matchType = LLMediaDataClient::Request::ANY);
+
+ PredicateMatchRequest(const PredicateMatchRequest &other);
+
+ bool operator()(const LLMediaDataClient::Request::ptr_t &test) const;
+
+private:
+ LLMediaDataClient::Request::ptr_t mRequest;
+ LLMediaDataClient::Request::Type mMatchType;
+ LLUUID mId;
+};
+
+
+PredicateMatchRequest::PredicateMatchRequest(const LLMediaDataClient::Request::ptr_t &request, LLMediaDataClient::Request::Type matchType) :
+ mRequest(request),
+ mMatchType(matchType),
+ mId()
+{}
+
+PredicateMatchRequest::PredicateMatchRequest(const LLUUID &id, LLMediaDataClient::Request::Type matchType) :
+ mRequest(),
+ mMatchType(matchType),
+ mId(id)
+{}
+
+PredicateMatchRequest::PredicateMatchRequest(const PredicateMatchRequest &other)
+{
+ mRequest = other.mRequest;
+ mMatchType = other.mMatchType;
+ mId = other.mId;
}
-template <typename T>
-typename T::iterator find_matching_request(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type)
+bool PredicateMatchRequest::operator()(const LLMediaDataClient::Request::ptr_t &test) const
{
- for(typename T::iterator iter = c.begin(); iter != c.end(); ++iter)
- {
- if(((*iter)->getID() == id) && ((match_type == LLMediaDataClient::Request::ANY) || (match_type == (*iter)->getType())))
- {
- return iter;
- }
- }
-
- return c.end();
+ if (mRequest)
+ return (mRequest->isMatch(test, mMatchType));
+ else if (!mId.isNull())
+ return ((test->getID() == mId) && ((mMatchType == LLMediaDataClient::Request::ANY) || (mMatchType == test->getType())));
+ return false;
}
-// NOTE: remove_matching_requests will not work correctly for containers where deleting an element may invalidate iterators
-// to other elements in the container (such as std::vector).
-// If the implementation is changed to use a container with this property, this will need to be revisited.
+//=========================================================================
+///
template <typename T>
-void remove_matching_requests(T &c, const LLUUID &id, LLMediaDataClient::Request::Type match_type)
+void mark_dead_and_remove_if(T &c, const PredicateMatchRequest &matchPred)
{
- for(typename T::iterator iter = c.begin(); iter != c.end();)
- {
- typename T::value_type i = *iter;
- typename T::iterator next = iter;
- next++;
- if((i->getID() == id) && ((match_type == LLMediaDataClient::Request::ANY) || (match_type == i->getType())))
- {
- i->markDead();
- c.erase(iter);
- }
- iter = next;
- }
+ for (typename T::iterator it = c.begin(); it != c.end();)
+ {
+ if (matchPred(*it))
+ {
+ (*it)->markDead();
+ // *TDOO: When C++11 is in change the following line to: it = c.erase(it);
+ c.erase(it++);
+ }
+ else
+ {
+ ++it;
+ }
+ }
}
//////////////////////////////////////////////////////////////////////////////////////
@@ -145,18 +169,20 @@ void remove_matching_requests(T &c, const LLUUID &id, LLMediaDataClient::Request
//
//////////////////////////////////////////////////////////////////////////////////////
-LLMediaDataClient::LLMediaDataClient(F32 queue_timer_delay,
- F32 retry_timer_delay,
- U32 max_retries,
- U32 max_sorted_queue_size,
- U32 max_round_robin_queue_size)
- : mQueueTimerDelay(queue_timer_delay),
- mRetryTimerDelay(retry_timer_delay),
- mMaxNumRetries(max_retries),
- mMaxSortedQueueSize(max_sorted_queue_size),
- mMaxRoundRobinQueueSize(max_round_robin_queue_size),
- mQueueTimerIsRunning(false)
+LLMediaDataClient::LLMediaDataClient(F32 queue_timer_delay, F32 retry_timer_delay,
+ U32 max_retries, U32 max_sorted_queue_size, U32 max_round_robin_queue_size):
+ mQueueTimerDelay(queue_timer_delay),
+ mRetryTimerDelay(retry_timer_delay),
+ mMaxNumRetries(max_retries),
+ mMaxSortedQueueSize(max_sorted_queue_size),
+ mMaxRoundRobinQueueSize(max_round_robin_queue_size),
+ mQueueTimerIsRunning(false),
+ mHttpRequest(new LLCore::HttpRequest()),
+ mHttpHeaders(new LLCore::HttpHeaders()),
+ mHttpOpts(new LLCore::HttpOptions()),
+ mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID)
{
+ // *TODO: Look up real Policy ID
}
LLMediaDataClient::~LLMediaDataClient()
@@ -171,20 +197,23 @@ bool LLMediaDataClient::isEmpty() const
bool LLMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &object)
{
- if(find_matching_request(mQueue, object->getID(), LLMediaDataClient::Request::ANY) != mQueue.end())
- return true;
-
- if(find_matching_request(mUnQueuedRequests, object->getID(), LLMediaDataClient::Request::ANY) != mUnQueuedRequests.end())
- return true;
-
+ PredicateMatchRequest upred(object->getID());
+
+ if (std::find_if(mQueue.begin(), mQueue.end(), upred) != mQueue.end())
+ return true;
+ if (std::find_if(mUnQueuedRequests.begin(), mUnQueuedRequests.end(), upred) != mUnQueuedRequests.end())
+ return true;
+
return false;
}
void LLMediaDataClient::removeFromQueue(const LLMediaDataClientObject::ptr_t &object)
{
LL_DEBUGS("LLMediaDataClient") << "removing requests matching ID " << object->getID() << LL_ENDL;
- remove_matching_requests(mQueue, object->getID(), LLMediaDataClient::Request::ANY);
- remove_matching_requests(mUnQueuedRequests, object->getID(), LLMediaDataClient::Request::ANY);
+ PredicateMatchRequest upred(object->getID());
+
+ mark_dead_and_remove_if(mQueue, upred);
+ mark_dead_and_remove_if(mUnQueuedRequests, upred);
}
void LLMediaDataClient::startQueueTimer()
@@ -207,23 +236,24 @@ void LLMediaDataClient::stopQueueTimer()
bool LLMediaDataClient::processQueueTimer()
{
- if(isEmpty())
+ if (isDoneProcessing())
return true;
LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() started, queue size is: " << mQueue.size() << LL_ENDL;
LL_DEBUGS("LLMediaDataClientQueue") << "QueueTimer::tick() started, SORTED queue is: " << mQueue << LL_ENDL;
serviceQueue();
-
+ serviceHttp();
+
LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() finished, queue size is: " << mQueue.size() << LL_ENDL;
LL_DEBUGS("LLMediaDataClientQueue") << "QueueTimer::tick() finished, SORTED queue is: " << mQueue << LL_ENDL;
- return isEmpty();
+ return isDoneProcessing();
}
-LLMediaDataClient::request_ptr_t LLMediaDataClient::dequeue()
+LLMediaDataClient::Request::ptr_t LLMediaDataClient::dequeue()
{
- request_ptr_t request;
+ Request::ptr_t request;
request_queue_t *queue_p = getQueue();
if (queue_p->empty())
@@ -242,20 +272,20 @@ LLMediaDataClient::request_ptr_t LLMediaDataClient::dequeue()
else
{
// Don't return this request -- it's not ready to be serviced.
- request = NULL;
+ request.reset();
}
}
return request;
}
-void LLMediaDataClient::pushBack(request_ptr_t request)
+void LLMediaDataClient::pushBack(Request::ptr_t request)
{
request_queue_t *queue_p = getQueue();
queue_p->push_front(request);
}
-void LLMediaDataClient::trackRequest(request_ptr_t request)
+void LLMediaDataClient::trackRequest(Request::ptr_t request)
{
request_set_t::iterator iter = mUnQueuedRequests.find(request);
@@ -269,7 +299,7 @@ void LLMediaDataClient::trackRequest(request_ptr_t request)
}
}
-void LLMediaDataClient::stopTrackingRequest(request_ptr_t request)
+void LLMediaDataClient::stopTrackingRequest(Request::ptr_t request)
{
request_set_t::iterator iter = mUnQueuedRequests.find(request);
@@ -283,16 +313,22 @@ void LLMediaDataClient::stopTrackingRequest(request_ptr_t request)
}
}
+bool LLMediaDataClient::isDoneProcessing() const
+{
+ return (isEmpty() && mUnQueuedRequests.empty());
+}
+
+
void LLMediaDataClient::serviceQueue()
{
// Peel one off of the items from the queue and execute it
- request_ptr_t request;
+ Request::ptr_t request;
do
{
request = dequeue();
- if(request.isNull())
+ if(!request)
{
// Queue is empty.
return;
@@ -317,7 +353,18 @@ void LLMediaDataClient::serviceQueue()
trackRequest(request);
// and make the post
- LLHTTPClient::post(url, sd_payload, request->createResponder());
+ LLHttpSDHandler *handler = request->createHandler();
+ LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicy, 0,
+ url, sd_payload, mHttpOpts, mHttpHeaders, handler);
+
+ if (handle == LLCORE_HTTP_HANDLE_INVALID)
+ {
+ // *TODO: Change this metaphore to use boost::shared_ptr<> for handlers. Requires change in LLCore::HTTP
+ delete handler;
+ LLCore::HttpStatus status = mHttpRequest->getStatus();
+ LL_WARNS("LLMediaDataClient") << "'" << url << "' request POST failed. Reason "
+ << status.toTerseString() << " \"" << status.toString() << "\"" << LL_ENDL;
+ }
}
else
{
@@ -332,13 +379,17 @@ void LLMediaDataClient::serviceQueue()
}
else
{
- // This request has exceeded its maxumim retry count. It will be dropped.
+ // This request has exceeded its maximum retry count. It will be dropped.
LL_WARNS("LLMediaDataClient") << "Could not send request " << *request << " for " << mMaxNumRetries << " tries, dropping request." << LL_ENDL;
}
}
}
+void LLMediaDataClient::serviceHttp()
+{
+ mHttpRequest->update(0);
+}
// dump the queue
std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::request_queue_t &q)
@@ -395,7 +446,7 @@ BOOL LLMediaDataClient::QueueTimer::tick()
//
//////////////////////////////////////////////////////////////////////////////////////
-LLMediaDataClient::RetryTimer::RetryTimer(F32 time, request_ptr_t request)
+LLMediaDataClient::RetryTimer::RetryTimer(F32 time, Request::ptr_t request)
: LLEventTimer(time), mRequest(request)
{
mRequest->startTracking();
@@ -417,7 +468,7 @@ BOOL LLMediaDataClient::RetryTimer::tick()
}
// Release the ref to the request.
- mRequest = NULL;
+ mRequest.reset();
// Don't fire again
return TRUE;
@@ -490,7 +541,7 @@ void LLMediaDataClient::Request::reEnqueue()
{
if(mMDC)
{
- mMDC->enqueue(this);
+ mMDC->enqueue(shared_from_this());
}
}
@@ -533,13 +584,13 @@ bool LLMediaDataClient::Request::isDead()
void LLMediaDataClient::Request::startTracking()
{
if(mMDC)
- mMDC->trackRequest(this);
+ mMDC->trackRequest(shared_from_this());
}
void LLMediaDataClient::Request::stopTracking()
{
if(mMDC)
- mMDC->stopTrackingRequest(this);
+ mMDC->stopTrackingRequest(shared_from_this());
}
std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::Request &r)
@@ -551,79 +602,61 @@ std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::Request &r)
<< " #retries=" << r.getRetryCount();
return s;
}
-
-//////////////////////////////////////////////////////////////////////////////////////
-//
-// LLMediaDataClient::Responder
-//
-//////////////////////////////////////////////////////////////////////////////////////
-LLMediaDataClient::Responder::Responder(const request_ptr_t &request)
-: mRequest(request)
+//========================================================================
+
+LLMediaDataClient::Handler::Handler(const Request::ptr_t &request):
+ mRequest(request)
{
}
-/*virtual*/
-void LLMediaDataClient::Responder::httpFailure()
+
+void LLMediaDataClient::Handler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
{
- mRequest->stopTracking();
+ mRequest->stopTracking();
- if(mRequest->isDead())
- {
- LL_WARNS("LLMediaDataClient") << "dead request " << *mRequest << LL_ENDL;
- return;
- }
-
- if (getStatus() == HTTP_SERVICE_UNAVAILABLE)
- {
- F32 retry_timeout;
-#if 0
- // *TODO: Honor server Retry-After header.
- if (!hasResponseHeader(HTTP_IN_HEADER_RETRY_AFTER)
- || !getSecondsUntilRetryAfter(getResponseHeader(HTTP_IN_HEADER_RETRY_AFTER), retry_timeout))
-#endif
- {
- retry_timeout = mRequest->getRetryTimerDelay();
- }
-
- mRequest->incRetryCount();
-
- if (mRequest->getRetryCount() < mRequest->getMaxNumRetries())
- {
- LL_INFOS("LLMediaDataClient") << *mRequest << " got SERVICE_UNAVAILABLE...retrying in " << retry_timeout << " seconds" << LL_ENDL;
-
- // Start timer (instances are automagically tracked by
- // InstanceTracker<> and LLEventTimer)
- new RetryTimer(F32(retry_timeout/*secs*/), mRequest);
- }
- else
- {
- LL_INFOS("LLMediaDataClient") << *mRequest << " got SERVICE_UNAVAILABLE...retry count "
- << mRequest->getRetryCount() << " exceeds " << mRequest->getMaxNumRetries() << ", not retrying" << LL_ENDL;
- }
- }
- // *TODO: Redirect on 3xx status codes.
- else
- {
- LL_WARNS("LLMediaDataClient") << *mRequest << " http failure "
- << dumpResponse() << LL_ENDL;
- }
+ if (mRequest->isDead())
+ {
+ LL_WARNS("LLMediaDataClient") << "dead request " << *mRequest << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("LLMediaDataClientResponse") << *mRequest << LL_ENDL;
}
-/*virtual*/
-void LLMediaDataClient::Responder::httpSuccess()
+void LLMediaDataClient::Handler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status)
{
- mRequest->stopTracking();
+ mRequest->stopTracking();
- if(mRequest->isDead())
- {
- LL_WARNS("LLMediaDataClient") << "dead request " << *mRequest << LL_ENDL;
- return;
- }
+ if (status == LLCore::HttpStatus(HTTP_SERVICE_UNAVAILABLE))
+ {
+ F32 retry_timeout;
+
+ retry_timeout = mRequest->getRetryTimerDelay();
+
+ mRequest->incRetryCount();
+
+ if (mRequest->getRetryCount() < mRequest->getMaxNumRetries())
+ {
+ LL_INFOS("LLMediaDataClient") << *mRequest << " got SERVICE_UNAVAILABLE...retrying in " << retry_timeout << " seconds" << LL_ENDL;
- LL_DEBUGS("LLMediaDataClientResponse") << *mRequest << " " << dumpResponse() << LL_ENDL;
+ // Start timer (instances are automagically tracked by
+ // InstanceTracker<> and LLEventTimer)
+ new RetryTimer(F32(retry_timeout/*secs*/), mRequest);
+ }
+ else
+ {
+ LL_INFOS("LLMediaDataClient") << *mRequest << " got SERVICE_UNAVAILABLE...retry count "
+ << mRequest->getRetryCount() << " exceeds " << mRequest->getMaxNumRetries() << ", not retrying" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("LLMediaDataClient") << *mRequest << " HTTP failure " << LL_ENDL;
+ }
}
+
//////////////////////////////////////////////////////////////////////////////////////
//
// LLObjectMediaDataClient
@@ -634,7 +667,7 @@ void LLMediaDataClient::Responder::httpSuccess()
void LLObjectMediaDataClient::fetchMedia(LLMediaDataClientObject *object)
{
// Create a get request and put it in the queue.
- enqueue(new RequestGet(object, this));
+ enqueue(Request::ptr_t(new RequestGet(object, this)));
}
const char *LLObjectMediaDataClient::getCapabilityName() const
@@ -678,14 +711,14 @@ void LLObjectMediaDataClient::sortQueue()
}
// static
-bool LLObjectMediaDataClient::compareRequestScores(const request_ptr_t &o1, const request_ptr_t &o2)
+bool LLObjectMediaDataClient::compareRequestScores(const Request::ptr_t &o1, const Request::ptr_t &o2)
{
- if (o2.isNull()) return true;
- if (o1.isNull()) return false;
+ if (!o2) return true;
+ if (!o1) return false;
return ( o1->getScore() > o2->getScore() );
}
-void LLObjectMediaDataClient::enqueue(Request *request)
+void LLObjectMediaDataClient::enqueue(Request::ptr_t request)
{
if(request->isDead())
{
@@ -703,9 +736,10 @@ void LLObjectMediaDataClient::enqueue(Request *request)
{
// For GET requests that are not new, if a matching request is already in the round robin queue,
// in flight, or being retried, leave it at its current position.
- request_queue_t::iterator iter = find_matching_request(mRoundRobinQueue, request->getID(), Request::GET);
- request_set_t::iterator iter2 = find_matching_request(mUnQueuedRequests, request->getID(), Request::GET);
-
+ PredicateMatchRequest upred(request->getID(), Request::GET);
+ request_queue_t::iterator iter = std::find_if(mRoundRobinQueue.begin(), mRoundRobinQueue.end(), upred);
+ request_set_t::iterator iter2 = std::find_if(mUnQueuedRequests.begin(), mUnQueuedRequests.end(), upred);
+
if( (iter != mRoundRobinQueue.end()) || (iter2 != mUnQueuedRequests.end()) )
{
LL_DEBUGS("LLMediaDataClient") << "ALREADY THERE: NOT Queuing request for " << *request << LL_ENDL;
@@ -718,9 +752,11 @@ void LLObjectMediaDataClient::enqueue(Request *request)
// IF the update will cause an object update message to be sent out at some point in the future, it probably should.
// Remove any existing requests of this type for this object
- remove_matching_requests(mQueue, request->getID(), request->getType());
- remove_matching_requests(mRoundRobinQueue, request->getID(), request->getType());
- remove_matching_requests(mUnQueuedRequests, request->getID(), request->getType());
+ PredicateMatchRequest upred(request->getID(), request->getType());
+
+ mark_dead_and_remove_if(mQueue, upred);
+ mark_dead_and_remove_if(mRoundRobinQueue, upred);
+ mark_dead_and_remove_if(mUnQueuedRequests, upred);
if (is_new)
{
@@ -749,7 +785,7 @@ void LLObjectMediaDataClient::enqueue(Request *request)
startQueueTimer();
}
-bool LLObjectMediaDataClient::canServiceRequest(request_ptr_t request)
+bool LLObjectMediaDataClient::canServiceRequest(Request::ptr_t request)
{
if(mCurrentQueueIsTheSortedQueue)
{
@@ -785,9 +821,9 @@ bool LLObjectMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &ob
if(LLMediaDataClient::isInQueue(object))
return true;
- if(find_matching_request(mRoundRobinQueue, object->getID(), LLMediaDataClient::Request::ANY) != mRoundRobinQueue.end())
- return true;
-
+ if (std::find_if(mRoundRobinQueue.begin(), mRoundRobinQueue.end(), PredicateMatchRequest(object->getID())) != mRoundRobinQueue.end())
+ return true;
+
return false;
}
@@ -796,12 +832,12 @@ void LLObjectMediaDataClient::removeFromQueue(const LLMediaDataClientObject::ptr
// First, call parent impl.
LLMediaDataClient::removeFromQueue(object);
- remove_matching_requests(mRoundRobinQueue, object->getID(), LLMediaDataClient::Request::ANY);
+ mark_dead_and_remove_if(mRoundRobinQueue, PredicateMatchRequest(object->getID()));
}
bool LLObjectMediaDataClient::processQueueTimer()
{
- if(isEmpty())
+ if (isDoneProcessing())
return true;
LL_DEBUGS("LLMediaDataClient") << "started, SORTED queue size is: " << mQueue.size()
@@ -816,6 +852,7 @@ bool LLObjectMediaDataClient::processQueueTimer()
LL_DEBUGS("LLMediaDataClientQueue") << "after sort, SORTED queue is: " << mQueue << LL_ENDL;
serviceQueue();
+ serviceHttp();
swapCurrentQueue();
@@ -824,7 +861,7 @@ bool LLObjectMediaDataClient::processQueueTimer()
LL_DEBUGS("LLMediaDataClientQueue") << " SORTED queue is: " << mQueue << LL_ENDL;
LL_DEBUGS("LLMediaDataClientQueue") << " RR queue is: " << mRoundRobinQueue << LL_ENDL;
- return isEmpty();
+ return isDoneProcessing();
}
LLObjectMediaDataClient::RequestGet::RequestGet(LLMediaDataClientObject *obj, LLMediaDataClient *mdc):
@@ -841,16 +878,16 @@ LLSD LLObjectMediaDataClient::RequestGet::getPayload() const
return result;
}
-LLMediaDataClient::Responder *LLObjectMediaDataClient::RequestGet::createResponder()
+LLHttpSDHandler *LLObjectMediaDataClient::RequestGet::createHandler()
{
- return new LLObjectMediaDataClient::Responder(this);
+ return new LLObjectMediaDataClient::Handler(shared_from_this());
}
void LLObjectMediaDataClient::updateMedia(LLMediaDataClientObject *object)
{
// Create an update request and put it in the queue.
- enqueue(new RequestUpdate(object, this));
+ enqueue(Request::ptr_t(new RequestUpdate(object, this)));
}
LLObjectMediaDataClient::RequestUpdate::RequestUpdate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc):
@@ -877,60 +914,58 @@ LLSD LLObjectMediaDataClient::RequestUpdate::getPayload() const
return result;
}
-LLMediaDataClient::Responder *LLObjectMediaDataClient::RequestUpdate::createResponder()
+LLHttpSDHandler *LLObjectMediaDataClient::RequestUpdate::createHandler()
{
// This just uses the base class's responder.
- return new LLMediaDataClient::Responder(this);
+ return new LLMediaDataClient::Handler(shared_from_this());
}
-
-/*virtual*/
-void LLObjectMediaDataClient::Responder::httpSuccess()
+void LLObjectMediaDataClient::Handler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
{
- getRequest()->stopTracking();
+ LLMediaDataClient::Handler::onSuccess(response, content);
+
+ if (getRequest()->isDead())
+ { // warning emitted from base method.
+ return;
+ }
+
+ if (!content.isMap())
+ {
+ onFailure(response, LLCore::HttpStatus(HTTP_INTERNAL_ERROR, "Malformed response contents"));
+ return;
+ }
+
+ // This responder is only used for GET requests, not UPDATE.
+ LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " " << LL_ENDL;
+
+ // Look for an error
+ if (content.has("error"))
+ {
+ const LLSD &error = content["error"];
+ LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error getting media data for object: code=" <<
+ error["code"].asString() << ": " << error["message"].asString() << LL_ENDL;
+
+ // XXX Warn user?
+ }
+ else
+ {
+ // Check the data
+ const LLUUID &object_id = content[LLTextureEntry::OBJECT_ID_KEY];
+ if (object_id != getRequest()->getObject()->getID())
+ {
+ // NOT good, wrong object id!!
+ LL_WARNS("LLMediaDataClient") << *(getRequest()) << " DROPPING response with wrong object id (" << object_id << ")" << LL_ENDL;
+ return;
+ }
+
+ // Otherwise, update with object media data
+ getRequest()->getObject()->updateObjectMediaData(content[LLTextureEntry::OBJECT_MEDIA_DATA_KEY],
+ content[LLTextureEntry::MEDIA_VERSION_KEY]);
+ }
- if(getRequest()->isDead())
- {
- LL_WARNS("LLMediaDataClient") << "dead request " << *(getRequest()) << LL_ENDL;
- return;
- }
-
- const LLSD& content = getContent();
- if (!content.isMap())
- {
- failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
- return;
- }
-
- // This responder is only used for GET requests, not UPDATE.
- LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " " << dumpResponse() << LL_ENDL;
-
- // Look for an error
- if (content.has("error"))
- {
- const LLSD &error = content["error"];
- LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error getting media data for object: code=" <<
- error["code"].asString() << ": " << error["message"].asString() << LL_ENDL;
-
- // XXX Warn user?
- }
- else
- {
- // Check the data
- const LLUUID &object_id = content[LLTextureEntry::OBJECT_ID_KEY];
- if (object_id != getRequest()->getObject()->getID())
- {
- // NOT good, wrong object id!!
- LL_WARNS("LLMediaDataClient") << *(getRequest()) << " DROPPING response with wrong object id (" << object_id << ")" << LL_ENDL;
- return;
- }
-
- // Otherwise, update with object media data
- getRequest()->getObject()->updateObjectMediaData(content[LLTextureEntry::OBJECT_MEDIA_DATA_KEY],
- content[LLTextureEntry::MEDIA_VERSION_KEY]);
- }
}
+
//////////////////////////////////////////////////////////////////////////////////////
//
// LLObjectMediaNavigateClient
@@ -943,16 +978,18 @@ const char *LLObjectMediaNavigateClient::getCapabilityName() const
return "ObjectMediaNavigate";
}
-void LLObjectMediaNavigateClient::enqueue(Request *request)
+void LLObjectMediaNavigateClient::enqueue(Request::ptr_t request)
{
if(request->isDead())
{
- LL_DEBUGS("LLMediaDataClient") << "not queueing dead request " << *request << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClient") << "not queuing dead request " << *request << LL_ENDL;
return;
}
+ PredicateMatchRequest upred(request);
+
// If there's already a matching request in the queue, remove it.
- request_queue_t::iterator iter = find_matching_request(mQueue, request, LLMediaDataClient::Request::ANY);
+ request_queue_t::iterator iter = std::find_if(mQueue.begin(), mQueue.end(), upred);
if(iter != mQueue.end())
{
LL_DEBUGS("LLMediaDataClient") << "removing matching queued request " << (**iter) << LL_ENDL;
@@ -960,7 +997,7 @@ void LLObjectMediaNavigateClient::enqueue(Request *request)
}
else
{
- request_set_t::iterator set_iter = find_matching_request(mUnQueuedRequests, request, LLMediaDataClient::Request::ANY);
+ request_set_t::iterator set_iter = std::find_if(mUnQueuedRequests.begin(), mUnQueuedRequests.end(), upred);
if(set_iter != mUnQueuedRequests.end())
{
LL_DEBUGS("LLMediaDataClient") << "removing matching unqueued request " << (**set_iter) << LL_ENDL;
@@ -979,7 +1016,7 @@ void LLObjectMediaNavigateClient::enqueue(Request *request)
else
#endif
{
- LL_DEBUGS("LLMediaDataClient") << "queueing new request " << (*request) << LL_ENDL;
+ LL_DEBUGS("LLMediaDataClient") << "queuing new request " << (*request) << LL_ENDL;
mQueue.push_back(request);
// Start the timer if not already running
@@ -993,7 +1030,7 @@ void LLObjectMediaNavigateClient::navigate(LLMediaDataClientObject *object, U8 t
// LL_INFOS("LLMediaDataClient") << "navigate() initiated: " << ll_print_sd(sd_payload) << LL_ENDL;
// Create a get request and put it in the queue.
- enqueue(new RequestNavigate(object, this, texture_index, url));
+ enqueue(Request::ptr_t(new RequestNavigate(object, this, texture_index, url)));
}
LLObjectMediaNavigateClient::RequestNavigate::RequestNavigate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc, U8 texture_index, const std::string &url):
@@ -1012,75 +1049,67 @@ LLSD LLObjectMediaNavigateClient::RequestNavigate::getPayload() const
return result;
}
-LLMediaDataClient::Responder *LLObjectMediaNavigateClient::RequestNavigate::createResponder()
+LLHttpSDHandler *LLObjectMediaNavigateClient::RequestNavigate::createHandler()
{
- return new LLObjectMediaNavigateClient::Responder(this);
+ return new LLObjectMediaNavigateClient::Handler(shared_from_this());
}
-/*virtual*/
-void LLObjectMediaNavigateClient::Responder::httpFailure()
+void LLObjectMediaNavigateClient::Handler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
{
- getRequest()->stopTracking();
+ LLMediaDataClient::Handler::onSuccess(response, content);
- if(getRequest()->isDead())
- {
- LL_WARNS("LLMediaDataClient") << "dead request " << *(getRequest()) << LL_ENDL;
- return;
- }
+ if (getRequest()->isDead())
+ { // already warned.
+ return;
+ }
+
+ LL_INFOS("LLMediaDataClient") << *(getRequest()) << " NAVIGATE returned" << LL_ENDL;
+
+ if (content.has("error"))
+ {
+ const LLSD &error = content["error"];
+ int error_code = error["code"];
+
+ if (ERROR_PERMISSION_DENIED_CODE == error_code)
+ {
+ mediaNavigateBounceBack();
+ }
+ else
+ {
+ LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating: code=" <<
+ error["code"].asString() << ": " << error["message"].asString() << LL_ENDL;
+ }
+
+ // XXX Warn user?
+ }
+ else
+ {
+ // No action required.
+ LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << LL_ENDL;
+ }
- // Bounce back (unless HTTP_SERVICE_UNAVAILABLE, in which case call base
- // class
- if (getStatus() == HTTP_SERVICE_UNAVAILABLE)
- {
- LLMediaDataClient::Responder::httpFailure();
- }
- else
- {
- // bounce the face back
- LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating: " << dumpResponse() << LL_ENDL;
- const LLSD &payload = getRequest()->getPayload();
- // bounce the face back
- getRequest()->getObject()->mediaNavigateBounceBack((LLSD::Integer)payload[LLTextureEntry::TEXTURE_INDEX_KEY]);
- }
}
-/*virtual*/
-void LLObjectMediaNavigateClient::Responder::httpSuccess()
+void LLObjectMediaNavigateClient::Handler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status)
{
- getRequest()->stopTracking();
+ LLMediaDataClient::Handler::onFailure(response, status);
- if(getRequest()->isDead())
- {
- LL_WARNS("LLMediaDataClient") << "dead request " << *(getRequest()) << LL_ENDL;
- return;
- }
+ if (getRequest()->isDead())
+ { // already warned.
+ return;
+ }
- LL_INFOS("LLMediaDataClient") << *(getRequest()) << " NAVIGATE returned " << dumpResponse() << LL_ENDL;
-
- const LLSD& content = getContent();
- if (content.has("error"))
- {
- const LLSD &error = content["error"];
- int error_code = error["code"];
-
- if (ERROR_PERMISSION_DENIED_CODE == error_code)
- {
- LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Navigation denied: bounce back" << LL_ENDL;
- const LLSD &payload = getRequest()->getPayload();
- // bounce the face back
- getRequest()->getObject()->mediaNavigateBounceBack((LLSD::Integer)payload[LLTextureEntry::TEXTURE_INDEX_KEY]);
- }
- else
- {
- LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating: code=" <<
- error["code"].asString() << ": " << error["message"].asString() << LL_ENDL;
- }
+ if (status != LLCore::HttpStatus(HTTP_SERVICE_UNAVAILABLE))
+ {
+ mediaNavigateBounceBack();
+ }
+}
- // XXX Warn user?
- }
- else
- {
- // No action required.
- LL_DEBUGS("LLMediaDataClientResponse") << *(getRequest()) << " " << dumpResponse() << LL_ENDL;
- }
+void LLObjectMediaNavigateClient::Handler::mediaNavigateBounceBack()
+{
+ LL_WARNS("LLMediaDataClient") << *(getRequest()) << " Error navigating or denied." << LL_ENDL;
+ const LLSD &payload = getRequest()->getPayload();
+
+ // bounce the face back
+ getRequest()->getObject()->mediaNavigateBounceBack((LLSD::Integer)payload[LLTextureEntry::TEXTURE_INDEX_KEY]);
}