diff options
| author | Monty Brandenberg <monty@lindenlab.com> | 2014-08-26 18:33:14 -0400 | 
|---|---|---|
| committer | Monty Brandenberg <monty@lindenlab.com> | 2014-08-26 18:33:14 -0400 | 
| commit | bbf9de9c6717f38a77a39d42d8493d275d558db9 (patch) | |
| tree | 64fd0b76e3ca4961e4b0b338b0f05d42a03c0882 /indra/llmessage | |
| parent | b64ef2ecd4af5265483527f2ef030554133ab137 (diff) | |
Bring better error handling to inventory item and folder fetching.
First, introduced some LLSD-based interfaces to the llcorehttp code
using utils classes (in llcorehttputil).  I've kept LLSD out of
the llcorehttp library up to now and will continue to do that.
Functions provide a requestPost based on LLSD body and conversion
utils for HttpResponse-to-LLSD and HttpResponse-to-string
conversions.  Inventory fetch operations now do more thorough
error checking including 200-with-error status checking.  Still
do retry forever on folders though I don't like that.
Diffstat (limited to 'indra/llmessage')
| -rwxr-xr-x | indra/llmessage/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | indra/llmessage/llcorehttputil.cpp | 137 | ||||
| -rw-r--r-- | indra/llmessage/llcorehttputil.h | 115 | 
3 files changed, 256 insertions, 0 deletions
| diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index 8bd134dc84..40eddcb0ab 100755 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -6,6 +6,7 @@ include(00-Common)  include(GoogleMock)  include(LLAddBuildTest)  include(LLCommon) +include(LLCoreHttp)  include(LLMath)  include(LLMessage)  include(LLVFS) @@ -18,6 +19,7 @@ include_directories (${CMAKE_CURRENT_SOURCE_DIR})  include_directories(      ${LLCOMMON_INCLUDE_DIRS} +    ${LLCOREHTTP_INCLUDE_DIRS}      ${LLMATH_INCLUDE_DIRS}      ${LLMESSAGE_INCLUDE_DIRS}      ${LLVFS_INCLUDE_DIRS} @@ -36,6 +38,7 @@ set(llmessage_SOURCE_FILES      llchainio.cpp      llcircuit.cpp      llclassifiedflags.cpp +    llcorehttputil.cpp      llcurl.cpp      lldatapacker.cpp      lldispatcher.cpp @@ -124,6 +127,7 @@ set(llmessage_HEADER_FILES      llcipher.h      llcircuit.h      llclassifiedflags.h +    llcorehttputil.h      llcurl.h      lldatapacker.h      lldbstrings.h diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp new file mode 100644 index 0000000000..8d09aac971 --- /dev/null +++ b/indra/llmessage/llcorehttputil.cpp @@ -0,0 +1,137 @@ +/**  + * @file llcorehttputil.cpp + * @date 2014-08-25 + * @brief Implementation of adapter and utility classes expanding the llcorehttp interfaces. + * + * $LicenseInfo:firstyear=2014&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2014, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include <sstream> + +#include "llcorehttputil.h" +#include "llsdserialize.h" + + +using namespace LLCore; + + +namespace LLCoreHttpUtil +{ + + +bool responseToLLSD(HttpResponse * response, bool log, LLSD & out_llsd) +{ +	// Convert response to LLSD +	BufferArray * body(response->getBody()); +	if (! body || ! body->size()) +	{ +		return false; +	} + +	LLCore::BufferArrayStream bas(body); +	LLSD body_llsd; +	S32 parse_status(LLSDSerialize::fromXML(body_llsd, bas, log)); +	if (LLSDParser::PARSE_FAILURE == parse_status){ +		return false; +	} +	out_llsd = body_llsd; +	return true; +} + + +HttpHandle requestPostWithLLSD(HttpRequest * request, +							   HttpRequest::policy_t policy_id, +							   HttpRequest::priority_t priority, +							   const std::string & url, +							   const LLSD & body, +							   HttpOptions * options, +							   HttpHeaders * headers, +							   HttpHandler * handler) +{ +	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID); + +	BufferArray * ba = new BufferArray(); +	BufferArrayStream bas(ba); +	LLSDSerialize::toXML(body, bas); + +	handle = request->requestPost(policy_id, +								  priority, +								  url, +								  ba, +								  options, +								  headers, +								  handler); +	ba->release(); +	return handle; +} + + +std::string responseToString(LLCore::HttpResponse * response) +{ +	static const std::string empty("[Empty]"); + +	if (! response) +	{ +		return empty; +	} + +	BufferArray * body(response->getBody()); +	if (! body || ! body->size()) +	{ +		return empty; +	} + +	// Attempt to parse as LLSD regardless of content-type +	LLSD body_llsd; +	if (responseToLLSD(response, false, body_llsd)) +	{ +		std::ostringstream tmp; + +		LLSDSerialize::toPrettyNotation(body_llsd, tmp); +		std::size_t temp_len(tmp.tellp()); +		 +		if (temp_len) +		{ +			return tmp.str().substr(0, std::min(temp_len, std::size_t(1024))); +		} +	} +	else +	{ +		// *TODO:  More elaborate forms based on Content-Type as needed. +		char content[1024]; + +		size_t len(body->read(0, content, sizeof(content))); +		if (len) +		{ +			return std::string(content, 0, len); +		} +	} + +	// Default +	return empty; +} + + +} // end namespace LLCoreHttpUtil + diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h new file mode 100644 index 0000000000..d40172bc7a --- /dev/null +++ b/indra/llmessage/llcorehttputil.h @@ -0,0 +1,115 @@ +/**  + * @file llcorehttputil.h + * @date 2014-08-25 + * @brief Adapter and utility classes expanding the llcorehttp interfaces. + * + * $LicenseInfo:firstyear=2014&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2014, Linden Research, Inc. + *  + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + *  + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLCOREHTTPUTIL_H +#define LL_LLCOREHTTPUTIL_H + +#include <string> + +#include "httpcommon.h" +#include "httprequest.h" +#include "httpresponse.h" +#include "httpheaders.h" +#include "httpoptions.h" +#include "httphandler.h" +#include "bufferarray.h" +#include "bufferstream.h" +#include "llsd.h" + +/// +/// The base llcorehttp library implements many HTTP idioms +/// used in the viewer but not all.  That library intentionally +/// avoids the use of LLSD and its conventions which aren't +/// universally applicable.  This module, using namespace +/// LLCoreHttpUtil, provides the additional helper functions +/// that support idiomatic LLSD transport via the newer +/// llcorehttp library. +/// +namespace LLCoreHttpUtil +{ + +/// Attempt to convert a response object's contents to LLSD. +/// It is expected that the response body will be of non-zero +/// length on input but basic checks will be performed and +/// and error (false status) returned if there is no data. +/// If there is data but it cannot be successfully parsed, +/// an error is also returned.  If successfully parsed, +/// the output LLSD object, out_llsd, is written with the +/// result and true is returned. +/// +/// @arg	response	Response object as returned in +///						in an HttpHandler onCompleted() callback. +/// @arg	log			If true, LLSD parser will emit errors +///						as LL_INFOS-level messages as it parses. +///						Otherwise, it *should* be a quiet parse. +/// @arg	out_llsd	Output LLSD object written only upon +///						successful parse of the response object. +/// +/// @return				Returns true (and writes to out_llsd) if +///						parse was successful.  False otherwise. +/// +bool responseToLLSD(LLCore::HttpResponse * response, +					bool log, +					LLSD & out_llsd); + +/// Create a std::string representation of a response object +/// suitable for logging.  Mainly intended for logging of +/// failures and debug information.  This won't be fast, +/// just adequate. +std::string responseToString(LLCore::HttpResponse * response); + + +/// Issue a standard HttpRequest::requestPost() call but using +/// and LLSD object as the request body.  Conventions are the +/// same as with that method.  Caller is expected to provide +/// an HttpHeaders object with a correct 'Content-Type:' header. +/// One will not be provided by this call.  You might look after +/// the 'Accept:' header as well. +/// +/// @return				If request is successfully issued, the +///						HttpHandle representing the request. +///						On error, LLCORE_HTTP_HANDLE_INVALID +///						is returned and caller can fetch detailed +///						status with the getStatus() method on the +///						request object.  In case of error, no +///						request is queued and caller may need to +///						perform additional cleanup such as freeing +///						a now-useless HttpHandler object. +/// +LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest * request, +									   LLCore::HttpRequest::policy_t policy_id, +									   LLCore::HttpRequest::priority_t priority, +									   const std::string & url, +									   const LLSD & body, +									   LLCore::HttpOptions * options, +									   LLCore::HttpHeaders * headers, +									   LLCore::HttpHandler * handler); + +} // end namespace LLCoreHttpUtil + + +#endif // LL_LLCOREHTTPUTIL_H | 
