diff options
| -rw-r--r-- | indra/llcommon/lluri.cpp | 19 | ||||
| -rw-r--r-- | indra/llcommon/lluri.h | 2 | ||||
| -rw-r--r-- | indra/llmessage/llhttpclient.cpp | 67 | ||||
| -rw-r--r-- | indra/llmessage/llhttpclient.h | 3 | ||||
| -rw-r--r-- | indra/test/llhttpclient_tut.cpp | 19 | 
5 files changed, 110 insertions, 0 deletions
| diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp index 5ecba4420d..cf06fe3f40 100644 --- a/indra/llcommon/lluri.cpp +++ b/indra/llcommon/lluri.cpp @@ -467,6 +467,25 @@ LLURI LLURI::buildAgentSessionURI(const LLUUID& agent_id, LLApp* app)  }  // static +LLURI LLURI::buildInventoryHostURI(const LLUUID& agent_id, LLApp* app) +{ +	std::string host = "localhost:12040"; + +	if (app) +	{ +		host = app->getOption("backbone-host-port").asString(); +	} + +	LLSD path = LLSD::emptyArray(); +	path.append("agent"); +	path.append(agent_id); +	path.append("inventory"); +	path.append("host"); + +	return buildHTTP(host, path); +} + +// static  LLURI LLURI::buildAgentLoginInfoURI(const LLUUID& agent_id, const std::string& dataserver)  {  	LLSD path = LLSD::emptyArray(); diff --git a/indra/llcommon/lluri.h b/indra/llcommon/lluri.h index b1ac0bca2b..514628237d 100644 --- a/indra/llcommon/lluri.h +++ b/indra/llcommon/lluri.h @@ -68,6 +68,8 @@ public:  	static LLURI buildBulkAgentPresenceURI(LLApp* app);  	static LLURI buildAgentSessionURI(const LLUUID& agent_id, LLApp* app);  	static LLURI buildAgentLoginInfoURI(const LLUUID& agent_id, const std::string& dataserver); +	static LLURI buildInventoryHostURI(const LLUUID& agent_id, LLApp* app); +	  private:  	std::string mScheme;  	std::string mEscapedOpaque; diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index 7d51b6c722..d83308d082 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -18,6 +18,8 @@  #include "llvfile.h"  #include "llvfs.h" +#include <curl/curl.h> +  static const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;  static std::string gCABundle; @@ -224,6 +226,71 @@ void LLHTTPClient::get(const std::string& url, ResponderPtr responder)  	request(url, LLURLRequest::HTTP_GET, NULL, responder);  } +// A simple class for managing data returned from a curl http request. +class LLHTTPBuffer +{ +public: +	LLHTTPBuffer() { } + +	static size_t curl_write( void *ptr, size_t size, size_t nmemb, void *user_data) +	{ +		LLHTTPBuffer* self = (LLHTTPBuffer*)user_data; +		 +		size_t bytes = (size * nmemb); +		self->mBuffer.append((char*)ptr,bytes); +		return nmemb; +	} + +	LLSD asLLSD() +	{ +		LLSD content; +		std::istringstream istr(mBuffer); +		LLSDSerialize::fromXML(content, istr); +		return content; +	} + +private: +	std::string mBuffer; +}; + +// This call is blocking! This is probably usually bad. :( +LLSD LLHTTPClient::blockingGet(const std::string& url) +{ +	llinfos << "blockingGet of " << url << llendl; + +	// Returns an LLSD map: {status: integer, body: map} +	char curl_error_buffer[CURL_ERROR_SIZE]; +	CURL* curlp = curl_easy_init(); + +	LLHTTPBuffer http_buffer; + +	curl_easy_setopt(curlp, CURLOPT_WRITEFUNCTION, LLHTTPBuffer::curl_write); +	curl_easy_setopt(curlp, CURLOPT_WRITEDATA, &http_buffer); +	curl_easy_setopt(curlp, CURLOPT_URL, url.c_str()); +	curl_easy_setopt(curlp, CURLOPT_ERRORBUFFER, curl_error_buffer); +	curl_easy_setopt(curlp, CURLOPT_FAILONERROR, 1); + +	LLSD response = LLSD::emptyMap(); + +	S32 curl_success = curl_easy_perform(curlp); + +	S32 http_status = 499; +	curl_easy_getinfo(curlp,CURLINFO_RESPONSE_CODE, &http_status); + +	if (curl_success != 0  +		&& http_status != 404)  // We expect 404s, don't spam for them. +	{ +		llwarns << "CURL ERROR: " << curl_error_buffer << llendl; +	} +	 +	response["status"] = http_status; +	response["body"] = http_buffer.asLLSD(); + +	curl_easy_cleanup(curlp); + +	return response; +} +  void LLHTTPClient::put(const std::string& url, const LLSD& body, ResponderPtr responder)  {  	request(url, LLURLRequest::HTTP_PUT, new LLSDInjector(body), responder); diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h index 41ccb1fad9..d64662e41d 100644 --- a/indra/llmessage/llhttpclient.h +++ b/indra/llmessage/llhttpclient.h @@ -58,6 +58,9 @@ public:  	static void postFile(const std::string& url, const LLUUID& uuid,  		LLAssetType::EType asset_type, ResponderPtr responder); +	// Blocking HTTP get that returns an LLSD map of status and body. +	static LLSD blockingGet(const std::string& url); +  	static void del(const std::string& url, ResponderPtr);  		///< sends a DELETE method, but we can't call it delete in c++ diff --git a/indra/test/llhttpclient_tut.cpp b/indra/test/llhttpclient_tut.cpp index 43ef6f4438..865af98761 100644 --- a/indra/test/llhttpclient_tut.cpp +++ b/indra/test/llhttpclient_tut.cpp @@ -294,4 +294,23 @@ namespace tut  		ensureStatusError();  		ensure_equals("reason", mReason, "STATUS_ERROR");  	} + +	template<> template<> +		void HTTPClientTestObject::test<7>() +	{ +		// Can not use the little mini server.  The blocking request won't ever let it run. +		// Instead get from a known LLSD source and compare results with the non-blocking get +		// which is tested against the mini server earlier. +		LLSD expected; + +		LLHTTPClient::get("http://secondlife.com/xmlhttp/homepage.php", newResult()); +		runThePump(); +		ensureStatusOK(); +		expected = getResult(); + +		LLSD result; +		result = LLHTTPClient::blockingGet("http://secondlife.com/xmlhttp/homepage.php"); +		LLSD body = result["body"]; +		ensure_equals("echoed result matches", body.size(), expected.size()); +	}  } | 
