diff options
| -rwxr-xr-x | indra/newview/llviewerinventory.cpp | 205 | 
1 files changed, 131 insertions, 74 deletions
| diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 18ea812471..31ff3bb5d6 100755 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -66,6 +66,7 @@  #include "lllogininstance.h"  #include "llfavoritesbar.h"  #include "llclipboard.h" +#include "llhttpretrypolicy.h"  // Two do-nothing ops for use in callbacks.  void no_op_inventory_func(const LLUUID&) {}  @@ -1138,44 +1139,156 @@ void move_inventory_item(  	gAgent.sendReliableMessage();  } -class RemoveObjectResponder: public LLHTTPClient::Responder +class AISCommand: public LLHTTPClient::Responder  {  public: -	RemoveObjectResponder(const LLUUID& item_id, LLPointer<LLInventoryCallback> callback): -		mItemUUID(item_id), +	typedef boost::function<void()> command_func_type; + +	AISCommand(LLPointer<LLInventoryCallback> callback):  		mCallback(callback)  	{ +		llinfos << "constructor" << llendl; +		mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 32.0, 2.0, 10); +	} + +	virtual ~AISCommand() +	{ +		llinfos << "destructor" << llendl; +	} + +	void run_command() +	{ +		mCommandFunc(); +	} + +	void setCommandFunc(command_func_type command_func) +	{ +		mCommandFunc = command_func; +	} +	 +	// Need to do command-specific parsing to get an id here.  May or +	// may not need to bother, since most LLInventoryCallbacks do +	// their work in the destructor. +	virtual bool getResponseUUID(const LLSD& content, LLUUID& id) +	{ +		return false;  	} +	  	/* virtual */ void httpSuccess()  	{ +		// Command func holds a reference to self, need to release it +		// after a success or final failure. +		setCommandFunc(no_op); +		  		const LLSD& content = getContent();  		if (!content.isMap())  		{  			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);  			return;  		} -		gInventory.onAISUpdateReceived("removeObjectResponder " + mItemUUID.asString(), content); +		mRetryPolicy->onSuccess(); +		 +		gInventory.onAISUpdateReceived("AISCommand", content);  		if (mCallback)  		{ -			mCallback->fire(mItemUUID); +			LLUUID item_id; // will default to null if parse fails. +			getResponseUUID(content,item_id); +			mCallback->fire(item_id);  		}  	} +  	/*virtual*/ void httpFailure()  	{  		const LLSD& content = getContent();  		S32 status = getStatus();  		const std::string& reason = getReason(); +		const LLSD& headers = getResponseHeaders();  		if (!content.isMap())  		{ -			llwarns << "Malformed response contents " << content << " id " << mItemUUID << " status " << status << " reason " << reason << llendl; -			return; +			llwarns << "Malformed response contents " << content +					<< " status " << status << " reason " << reason << llendl; +		} +		else +		{ +			llwarns << "failed with content: " << ll_pretty_print_sd(content) +					<< " status " << status << " reason " << reason << llendl; +		} +		mRetryPolicy->onFailure(status, headers); +		F32 seconds_to_wait; +		if (mRetryPolicy->shouldRetry(seconds_to_wait)) +		{ +			doAfterInterval(boost::bind(&AISCommand::run_command,this),seconds_to_wait); +		} +		else +		{ +			// Command func holds a reference to self, need to release it +			// after a success or final failure. +			setCommandFunc(no_op);  		} -		llwarns << "failed for " << mItemUUID << " content: " << ll_pretty_print_sd(content) << " status " << status << " reason " << reason << llendl;  	} + +	static bool getCap(std::string& cap) +	{ +		if (gAgent.getRegion()) +		{ +			cap = gAgent.getRegion()->getCapability("InventoryAPIv3"); +		} +		if (!cap.empty()) +		{ +			return true; +		} +		return false; +	} +  private: +	command_func_type mCommandFunc; +	LLPointer<LLHTTPRetryPolicy> mRetryPolicy;  	LLPointer<LLInventoryCallback> mCallback; -	const LLUUID mItemUUID; +}; + +class RemoveObjectCommand: public AISCommand +{ +public: +	RemoveObjectCommand(const LLUUID& item_id, +						LLPointer<LLInventoryCallback> callback): +		AISCommand(callback) +	{ +		std::string cap; +		if (!getCap(cap)) +		{ +			return; +		} +		const std::string url = cap + std::string("/item/") + item_id.asString(); +		llinfos << "url: " << url << llendl; +		LLHTTPClient::ResponderPtr responder = this; +		LLSD headers; +		F32 timeout = HTTP_REQUEST_EXPIRY_SECS; +		command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder, headers, timeout); +		setCommandFunc(cmd); +	} +}; + +class PurgeDescendentsCommand: public AISCommand +{ +public: +	PurgeDescendentsCommand(const LLUUID& item_id, +							LLPointer<LLInventoryCallback> callback): +		AISCommand(callback) +	{ +		std::string cap; +		if (!getCap(cap)) +		{ +			return; +		} +		std::string url = cap + std::string("/category/") + item_id.asString() + "/children"; +		llinfos << "url: " << url << llendl; +		LLCurl::ResponderPtr responder = this; +		LLSD headers; +		F32 timeout = HTTP_REQUEST_EXPIRY_SECS; +		command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder, headers, timeout); +		setCommandFunc(cmd); +	}  };  void remove_inventory_item( @@ -1187,16 +1300,10 @@ void remove_inventory_item(  	if(obj)  	{  		std::string cap; -		if (gAgent.getRegion()) -		{ -			cap = gAgent.getRegion()->getCapability("InventoryAPIv3"); -		} -		if (!cap.empty()) +		if (AISCommand::getCap(cap))  		{ -			std::string url = cap + std::string("/item/") + item_id.asString(); -			llinfos << "url: " << url << llendl; -			LLCurl::ResponderPtr responder_ptr = new RemoveObjectResponder(item_id,cb); -			LLHTTPClient::del(url,responder_ptr); +			LLPointer<AISCommand> cmd_ptr = new RemoveObjectCommand(item_id, cb); +			cmd_ptr->run_command();  		}  		else // no cap  		{ @@ -1264,16 +1371,12 @@ void remove_inventory_category(  			return;  		}  		std::string cap; -		if (gAgent.getRegion()) -		{ -			cap = gAgent.getRegion()->getCapability("InventoryAPIv3"); -		} -		if (!cap.empty()) +		if (AISCommand::getCap(cap))  		{  			std::string url = cap + std::string("/category/") + cat_id.asString();  			llinfos << "url: " << url << llendl; -			LLCurl::ResponderPtr responder_ptr = new RemoveObjectResponder(cat_id,cb); -			LLHTTPClient::del(url,responder_ptr); +			LLPointer<AISCommand> cmd_ptr = new RemoveObjectCommand(cat_id, cb); +			cmd_ptr->run_command();  		}  		else // no cap  		{ @@ -1326,46 +1429,6 @@ void remove_inventory_object(  	}  } -class PurgeDescendentsResponder: public LLHTTPClient::Responder -{ -public: -	PurgeDescendentsResponder(const LLUUID& item_id, LLPointer<LLInventoryCallback> callback): -		mItemUUID(item_id), -		mCallback(callback) -	{ -	} -	/* virtual */ void httpSuccess() -	{ -		const LLSD& content = getContent(); -		if (!content.isMap()) -		{ -			failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content); -			return; -		} -		gInventory.onAISUpdateReceived("purgeDescendentsResponder " + mItemUUID.asString(), content); - -		if (mCallback) -		{ -			mCallback->fire(mItemUUID); -		} -	} -	/*virtual*/ void httpFailure() -	{ -		const LLSD& content = getContent(); -		S32 status = getStatus(); -		const std::string& reason = getReason(); -		if (!content.isMap()) -		{ -			llwarns << "Malformed response contents " << content << " id " << mItemUUID << " status " << status << " reason " << reason << llendl; -			return; -		} -		llwarns << "failed for " << mItemUUID << " content: " << ll_pretty_print_sd(content) << " status " << status << " reason " << reason << llendl; -	} -private: -	LLPointer<LLInventoryCallback> mCallback; -	const LLUUID mItemUUID; -}; -  // This is a method which collects the descendents of the id  // provided. If the category is not found, no action is  // taken. This method goes through the long winded process of @@ -1414,16 +1477,10 @@ void purge_descendents_of(const LLUUID& id, LLPointer<LLInventoryCallback> cb)  		else  		{  			std::string cap; -			if (gAgent.getRegion()) -			{ -				cap = gAgent.getRegion()->getCapability("InventoryAPIv3"); -			} -			if (!cap.empty()) +			if (AISCommand::getCap(cap))  			{ -				std::string url = cap + std::string("/category/") + id.asString() + "/children"; -				llinfos << "url: " << url << llendl; -				LLCurl::ResponderPtr responder_ptr = new PurgeDescendentsResponder(id,cb); -				LLHTTPClient::del(url,responder_ptr); +				LLPointer<AISCommand> cmd_ptr = new PurgeDescendentsCommand(id, cb); +				cmd_ptr->run_command();  			}  			else // no cap  			{ | 
