From c437a9c4ec865c38366c8057010d24311888ecb1 Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Wed, 20 May 2015 17:37:27 -0700 Subject: Webprofile converted to coroutine. Added JSON->LLSD converter Added corohandler for JSON data --- indra/llmessage/CMakeLists.txt | 4 ++ indra/llmessage/llcorehttputil.cpp | 82 ++++++++++++++++++++++++++++++++++++++ indra/llmessage/llcorehttputil.h | 12 ++++++ 3 files changed, 98 insertions(+) (limited to 'indra/llmessage') diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index f6ca6a3634..51b8ed6c62 100755 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -14,6 +14,7 @@ include(LLAddBuildTest) include(Python) include(Tut) include(Python) +include(JsonCpp) include_directories (${CMAKE_CURRENT_SOURCE_DIR}) @@ -23,6 +24,7 @@ include_directories( ${LLMATH_INCLUDE_DIRS} ${LLMESSAGE_INCLUDE_DIRS} ${LLVFS_INCLUDE_DIRS} + ${JSONCPP_INCLUDE_DIR} ) set(llmessage_SOURCE_FILES @@ -229,6 +231,7 @@ target_link_libraries( ${LLVFS_LIBRARIES} ${LLMATH_LIBRARIES} ${CARES_LIBRARIES} + ${JSONCPP_LIBRARIES} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} ${XMLRPCEPI_LIBRARIES} @@ -254,6 +257,7 @@ if (LL_TESTS) ${LLCOMMON_LIBRARIES} ${LLMESSAGE_LIBRARIES} ${LLCOREHTTP_LIBRARIES} + ${JSONCPP_LIBRARIES} ${BOOST_CONTEXT_LIBRARY} ${BOOST_COROUTINE_LIBRARY} ${GOOGLEMOCK_LIBRARIES} diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp index cf34029dfe..05d2e84f88 100644 --- a/indra/llmessage/llcorehttputil.cpp +++ b/indra/llmessage/llcorehttputil.cpp @@ -32,7 +32,10 @@ #include #include "llcorehttputil.h" #include "llhttpconstants.h" +#include "llsd.h" +#include "llsdjson.h" #include "llsdserialize.h" +#include "reader.h" using namespace LLCore; @@ -252,6 +255,23 @@ void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons } buildStatusEntry(response, status, result); + +#if 0 + // commenting out, but keeping since this can be useful for debugging + if (!status) + { + LLSD &httpStatus = result[HttpCoroutineAdapter::HTTP_RESULTS]; + + LLCore::BufferArray *body = response->getBody(); + LLCore::BufferArrayStream bas(body); + LLSD::Binary bodyData; + bodyData.reserve(response->getBodySize()); + bas >> std::noskipws; + bodyData.assign(std::istream_iterator(bas), std::istream_iterator()); + httpStatus["error_body"] = bodyData; + } +#endif + mReplyPump.post(result); } @@ -437,6 +457,58 @@ LLSD HttpCoroRawHandler::handleSuccess(LLCore::HttpResponse * response, LLCore:: return result; } +//======================================================================== +/// The HttpCoroJSONHandler is a specialization of the LLCore::HttpHandler for +/// interacting with coroutines. +/// +/// In addition to the normal "http_results" the returned LLSD will contain +/// JSON entries will be converted into an LLSD map. All results are considered +/// strings +/// +class HttpCoroJSONHandler : public HttpCoroHandler +{ +public: + HttpCoroJSONHandler(LLEventStream &reply); + + virtual LLSD handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status); +}; + +//------------------------------------------------------------------------- +HttpCoroJSONHandler::HttpCoroJSONHandler(LLEventStream &reply) : + HttpCoroHandler(reply) +{ +} + +LLSD HttpCoroJSONHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::HttpStatus &status) +{ + LLSD result = LLSD::emptyMap(); + + BufferArray * body(response->getBody()); + if (!body || !body->size()) + { + return result; + } + + LLCore::BufferArrayStream bas(body); + Json::Value jsonRoot; + + try + { + bas >> jsonRoot; + } + catch (std::runtime_error e) + { // deserialization failed. Record the reason and pass back an empty map for markup. + status = LLCore::HttpStatus(499, std::string(e.what())); + return result; + } + + // Convert the JSON structure to LLSD + result = LlsdFromJson(jsonRoot); + + return result; +} + + //======================================================================== HttpRequestPumper::HttpRequestPumper(const LLCore::HttpRequest::ptr_t &request) : mHttpRequest(request) @@ -614,6 +686,16 @@ LLSD HttpCoroutineAdapter::getRawAndYield(LLCoros::self & self, LLCore::HttpRequ return getAndYield_(self, request, url, options, headers, httpHandler); } +LLSD HttpCoroutineAdapter::getJsonAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t request, + const std::string & url, LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers) +{ + LLEventStream replyPump(mAdapterName + "Reply", true); + HttpCoroHandler::ptr_t httpHandler = HttpCoroHandler::ptr_t(new HttpCoroJSONHandler(replyPump)); + + return getAndYield_(self, request, url, options, headers, httpHandler); +} + + LLSD HttpCoroutineAdapter::getAndYield_(LLCoros::self & self, LLCore::HttpRequest::ptr_t &request, const std::string & url, LLCore::HttpOptions::ptr_t &options, LLCore::HttpHeaders::ptr_t &headers, diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h index 35e5b0aa2d..d6219318f9 100644 --- a/indra/llmessage/llcorehttputil.h +++ b/indra/llmessage/llcorehttputil.h @@ -373,6 +373,18 @@ public: headers); } + LLSD getJsonAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t request, + const std::string & url, + LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false), + LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false)); + LLSD getJsonndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t &request, + const std::string & url, LLCore::HttpHeaders::ptr_t &headers) + { + return getJsonAndYield(self, request, url, + LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false), + headers); + } + /// Execute a DELETE transaction on the supplied URL and yield execution of /// the coroutine until a result is available. -- cgit v1.2.3