diff options
Diffstat (limited to 'indra/llmessage')
-rw-r--r-- | indra/llmessage/CMakeLists.txt | 13 | ||||
-rw-r--r-- | indra/llmessage/llcachename.cpp | 4 | ||||
-rw-r--r-- | indra/llmessage/llhttpclient.cpp | 140 | ||||
-rw-r--r-- | indra/llmessage/llhttpclient.h | 8 | ||||
-rw-r--r-- | indra/llmessage/llinstantmessage.cpp | 2 | ||||
-rw-r--r-- | indra/llmessage/llmessageconfig.cpp | 7 | ||||
-rw-r--r-- | indra/llmessage/llurlrequest.cpp | 20 | ||||
-rw-r--r-- | indra/llmessage/llurlrequest.h | 5 | ||||
-rw-r--r-- | indra/llmessage/message.cpp | 3 | ||||
-rw-r--r-- | indra/llmessage/message.h | 16 | ||||
-rw-r--r-- | indra/llmessage/tests/llcurl_stub.cpp | 2 | ||||
-rw-r--r-- | indra/llmessage/tests/lltesthttpclientadapter.cpp | 2 | ||||
-rw-r--r-- | indra/llmessage/tests/lltesthttpclientadapter.h | 2 | ||||
-rw-r--r-- | indra/llmessage/tests/lltestmessagesender.cpp | 2 | ||||
-rw-r--r-- | indra/llmessage/tests/lltestmessagesender.h | 2 |
15 files changed, 181 insertions, 47 deletions
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index 99bd98dfc1..29e7aed898 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -219,10 +219,15 @@ IF (NOT LINUX AND VIEWER) # When building the viewer the tests links against the shared objects. # These can not be found when we try to run the tests, so we had to disable them, for the viewer build. # TODO: Can someone with viewer knowledge figure out how to make these find the correct so. - #ADD_BUILD_TEST(llhttpclientadapter llmessage) - ADD_BUILD_TEST(lltrustedmessageservice llmessage) - ADD_BUILD_TEST(lltemplatemessagedispatcher llmessage) + SET(llmessage_TEST_SOURCE_FILES + # llhttpclientadapter.cpp + lltrustedmessageservice.cpp + lltemplatemessagedispatcher.cpp + ) + LL_ADD_PROJECT_UNIT_TESTS(llmessage "${llmessage_TEST_SOURCE_FILES}") + + # Commented out - see rationale at bottom of newview's build file + poppy 2009-06-05 # Don't make llmessage depend on llsdmessage_test because ADD_COMM_BUILD_TEST depends on llmessage! - ADD_COMM_BUILD_TEST(llsdmessage "" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llsdmessage_peer.py") + # ADD_COMM_BUILD_TEST(llsdmessage "" "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llsdmessage_peer.py") ADD_BUILD_TEST(llareslistener llmessage) ENDIF (NOT LINUX AND VIEWER) diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp index 43abc2953d..a4304596de 100644 --- a/indra/llmessage/llcachename.cpp +++ b/indra/llmessage/llcachename.cpp @@ -42,6 +42,7 @@ #include "llsdserialize.h" #include "lluuid.h" #include "message.h" +#include "llmemtype.h" // llsd serialization constants static const std::string AGENTS("agents"); @@ -607,6 +608,7 @@ boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, ol void LLCacheName::processPending() { + LLMemType mt_pp(LLMemType::MTYPE_CACHE_PROCESS_PENDING); const F32 SECS_BETWEEN_PROCESS = 0.1f; if(!impl.mProcessTimer.checkExpirationAndReset(SECS_BETWEEN_PROCESS)) { @@ -700,6 +702,7 @@ std::string LLCacheName::getDefaultName() void LLCacheName::Impl::processPendingAsks() { + LLMemType mt_ppa(LLMemType::MTYPE_CACHE_PROCESS_PENDING_ASKS); sendRequest(_PREHASH_UUIDNameRequest, mAskNameQueue); sendRequest(_PREHASH_UUIDGroupNameRequest, mAskGroupQueue); mAskNameQueue.clear(); @@ -708,6 +711,7 @@ void LLCacheName::Impl::processPendingAsks() void LLCacheName::Impl::processPendingReplies() { + LLMemType mt_ppr(LLMemType::MTYPE_CACHE_PROCESS_PENDING_REPLIES); // First call all the callbacks, because they might send messages. for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); ++it) { diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index 307d9b92fa..8b90a4c5ca 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -224,6 +224,10 @@ static void request( LLURLRequest* req = new LLURLRequest(method, url); req->checkRootCertificate(true); + + lldebugs << LLURLRequest::actionAsVerb(method) << " " << url << " " + << headers << llendl; + // Insert custom headers is the caller sent any if (headers.isMap()) { @@ -375,72 +379,140 @@ private: std::string mBuffer; }; -// *TODO: Deprecate (only used by dataserver) -// This call is blocking! This is probably usually bad. :( -LLSD LLHTTPClient::blockingGet(const std::string& url) +// These calls are blocking! This is usually bad, unless you're a dataserver. Then it's awesome. + +/** + @brief does a blocking request on the url, returning the data or bad status. + + @param url URI to verb on. + @param method the verb to hit the URI with. + @param body the body of the call (if needed - for instance not used for GET and DELETE, but is for POST and PUT) + @param headers HTTP headers to use for the request. + @param timeout Curl timeout to use. Defaults to 5. Rationale: + Without this timeout, blockingGet() calls have been observed to take + up to 90 seconds to complete. Users of blockingGet() already must + check the HTTP return code for validity, so this will not introduce + new errors. A 5 second timeout will succeed > 95% of the time (and + probably > 99% of the time) based on my statistics. JC + + @returns an LLSD map: {status: integer, body: map} + */ +static LLSD blocking_request( + const std::string& url, + LLURLRequest::ERequestAction method, + const LLSD& body, + const LLSD& headers = LLSD(), + const F32 timeout = 5 +) { - llinfos << "blockingGet of " << url << llendl; - - // Returns an LLSD map: {status: integer, body: map} - char curl_error_buffer[CURL_ERROR_SIZE]; + lldebugs << "blockingRequest of " << url << llendl; + char curl_error_buffer[CURL_ERROR_SIZE] = "\0"; CURL* curlp = curl_easy_init(); - LLHTTPBuffer http_buffer; - - // Without this timeout, blockingGet() calls have been observed to take - // up to 90 seconds to complete. Users of blockingGet() already must - // check the HTTP return code for validity, so this will not introduce - // new errors. A 5 second timeout will succeed > 95% of the time (and - // probably > 99% of the time) based on my statistics. JC + std::string body_str; + + // other request method checks root cert first, we skip? + //req->checkRootCertificate(true); + + // * Set curl handle options curl_easy_setopt(curlp, CURLOPT_NOSIGNAL, 1); // don't use SIGALRM for timeouts - curl_easy_setopt(curlp, CURLOPT_TIMEOUT, 5); // seconds - + curl_easy_setopt(curlp, CURLOPT_TIMEOUT, timeout); // seconds, see warning at top of function. 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); - - struct curl_slist *header_list = NULL; - header_list = curl_slist_append(header_list, "Accept: application/llsd+xml"); - CURLcode curl_result = curl_easy_setopt(curlp, CURLOPT_HTTPHEADER, header_list); + + // * Setup headers (don't forget to free them after the call!) + curl_slist* headers_list = NULL; + if (headers.isMap()) + { + LLSD::map_const_iterator iter = headers.beginMap(); + LLSD::map_const_iterator end = headers.endMap(); + for (; iter != end; ++iter) + { + std::ostringstream header; + header << iter->first << ": " << iter->second.asString() ; + lldebugs << "header = " << header.str() << llendl; + headers_list = curl_slist_append(headers_list, header.str().c_str()); + } + } + + // * Setup specific method / "verb" for the URI (currently only GET and POST supported + poppy) + if (method == LLURLRequest::HTTP_GET) + { + curl_easy_setopt(curlp, CURLOPT_HTTPGET, 1); + } + else if (method == LLURLRequest::HTTP_POST) + { + curl_easy_setopt(curlp, CURLOPT_POST, 1); + //serialize to ostr then copy to str - need to because ostr ptr is unstable :( + std::ostringstream ostr; + LLSDSerialize::toXML(body, ostr); + body_str = ostr.str(); + curl_easy_setopt(curlp, CURLOPT_POSTFIELDS, body_str.c_str()); + //copied from PHP libs, correct? + headers_list = curl_slist_append(headers_list, "Content-Type: application/llsd+xml"); + + // copied from llurlrequest.cpp + // it appears that apache2.2.3 or django in etch is busted. If + // we do not clear the expect header, we get a 500. May be + // limited to django/mod_wsgi. + headers_list = curl_slist_append(headers_list, "Expect:"); + } + + // * Do the action using curl, handle results + lldebugs << "HTTP body: " << body_str << llendl; + headers_list = curl_slist_append(headers_list, "Accept: application/llsd+xml"); + CURLcode curl_result = curl_easy_setopt(curlp, CURLOPT_HTTPHEADER, headers_list); if ( curl_result != CURLE_OK ) { - llinfos << "Curl is hosed - can't add Accept header for llsd+xml" << llendl; + llinfos << "Curl is hosed - can't add headers" << llendl; } LLSD response = LLSD::emptyMap(); - S32 curl_success = curl_easy_perform(curlp); - S32 http_status = 499; - curl_easy_getinfo(curlp,CURLINFO_RESPONSE_CODE, &http_status); - + curl_easy_getinfo(curlp, CURLINFO_RESPONSE_CODE, &http_status); response["status"] = http_status; - - if (curl_success != 0 - && http_status != 404) // We expect 404s, don't spam for them. + // if we get a non-404 and it's not a 200 OR maybe it is but you have error bits, + if ( http_status != 404 && (http_status != 200 || curl_success != 0) ) { + // We expect 404s, don't spam for them. + llwarns << "CURL REQ URL: " << url << llendl; + llwarns << "CURL REQ METHOD TYPE: " << method << llendl; + llwarns << "CURL REQ HEADERS: " << headers.asString() << llendl; + llwarns << "CURL REQ BODY: " << body_str << llendl; + llwarns << "CURL HTTP_STATUS: " << http_status << llendl; llwarns << "CURL ERROR: " << curl_error_buffer << llendl; - + llwarns << "CURL ERROR BODY: " << http_buffer.asString() << llendl; response["body"] = http_buffer.asString(); } else { response["body"] = http_buffer.asLLSD(); + lldebugs << "CURL response: " << http_buffer.asString() << llendl; } - if(header_list) + if(headers_list) { // free the header list - curl_slist_free_all(header_list); - header_list = NULL; + curl_slist_free_all(headers_list); } + // * Cleanup curl_easy_cleanup(curlp); - return response; } +LLSD LLHTTPClient::blockingGet(const std::string& url) +{ + return blocking_request(url, LLURLRequest::HTTP_GET, LLSD()); +} + +LLSD LLHTTPClient::blockingPost(const std::string& url, const LLSD& body) +{ + return blocking_request(url, LLURLRequest::HTTP_POST, body); +} + void LLHTTPClient::put( const std::string& url, const LLSD& body, diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h index a0c9fac77f..3d0646e5fe 100644 --- a/indra/llmessage/llhttpclient.h +++ b/indra/llmessage/llhttpclient.h @@ -142,6 +142,14 @@ public: */ static LLSD blockingGet(const std::string& url); + /** + * @brief Blocking HTTP POST that returns an LLSD map of status and body. + * + * @param url the complete serialized (and escaped) url to get + * @param body the LLSD post body + * @return An LLSD of { 'status':status (an int), 'body':payload (an LLSD) } + */ + static LLSD blockingPost(const std::string& url, const LLSD& body); static void setPump(LLPumpIO& pump); diff --git a/indra/llmessage/llinstantmessage.cpp b/indra/llmessage/llinstantmessage.cpp index e41b332e7b..3da41939fa 100644 --- a/indra/llmessage/llinstantmessage.cpp +++ b/indra/llmessage/llinstantmessage.cpp @@ -357,7 +357,7 @@ LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd) param_message["message"].asString(), param_message["id"].asUUID(), (U32) param_message["parent_estate_id"].asInteger(), - im_info->mRegionID = param_message["region_id"].asUUID(), + param_message["region_id"].asUUID(), ll_vector3_from_sd(param_message["position"]), param_message["data"], (U8) param_message["offline"].asInteger(), diff --git a/indra/llmessage/llmessageconfig.cpp b/indra/llmessage/llmessageconfig.cpp index d4279354b6..dff0a3844c 100644 --- a/indra/llmessage/llmessageconfig.cpp +++ b/indra/llmessage/llmessageconfig.cpp @@ -66,7 +66,7 @@ public: static LLMessageConfigFile& instance(); // return the singleton configuration file - /* virtual */ void loadFile(); + /* virtual */ bool loadFile(); void loadServerDefaults(const LLSD& data); void loadMaxQueuedEvents(const LLSD& data); void loadMessages(const LLSD& data); @@ -98,7 +98,7 @@ LLMessageConfigFile& LLMessageConfigFile::instance() } // virtual -void LLMessageConfigFile::loadFile() +bool LLMessageConfigFile::loadFile() { LLSD data; { @@ -115,7 +115,7 @@ void LLMessageConfigFile::loadFile() LL_INFOS("AppInit") << "LLMessageConfigFile::loadFile: file missing," " ill-formed, or simply undefined; not changing the" " file" << LL_ENDL; - return; + return false; } } loadServerDefaults(data); @@ -123,6 +123,7 @@ void LLMessageConfigFile::loadFile() loadMessages(data); loadCapBans(data); loadMessageBans(data); + return true; } void LLMessageConfigFile::loadServerDefaults(const LLSD& data) diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 46e976fe35..3ab8057abb 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -98,6 +98,26 @@ LLURLRequestDetail::~LLURLRequestDetail() * class LLURLRequest */ +// static +std::string LLURLRequest::actionAsVerb(LLURLRequest::ERequestAction action) +{ + static const std::string VERBS[] = + { + "(invalid)", + "HEAD", + "GET", + "PUT", + "POST", + "DELETE", + "MOVE" + }; + if(((S32)action <=0) || ((S32)action >= REQUEST_ACTION_COUNT)) + { + return VERBS[0]; + } + return VERBS[action]; +} + LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action) : mAction(action) { diff --git a/indra/llmessage/llurlrequest.h b/indra/llmessage/llurlrequest.h index d1facbff0f..86ef71f085 100644 --- a/indra/llmessage/llurlrequest.h +++ b/indra/llmessage/llurlrequest.h @@ -81,6 +81,11 @@ public: REQUEST_ACTION_COUNT }; + /** + * @brief Turn the requst action into an http verb. + */ + static std::string actionAsVerb(ERequestAction action); + /** * @brief Constructor. * diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index 78af35bf65..e56d818d65 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -86,6 +86,7 @@ #include "v3math.h" #include "v4math.h" #include "lltransfertargetvfile.h" +#include "llmemtype.h" // Constants //const char* MESSAGE_LOG_FILENAME = "message.log"; @@ -794,6 +795,7 @@ S32 LLMessageSystem::getReceiveBytes() const void LLMessageSystem::processAcks() { + LLMemType mt_pa(LLMemType::MTYPE_MESSAGE_PROCESS_ACKS); F64 mt_sec = getMessageTimeSeconds(); { gTransferManager.updateTransfers(); @@ -4020,6 +4022,7 @@ void LLMessageSystem::setTimeDecodesSpamThreshold( F32 seconds ) // TODO: babbage: move gServicePump in to LLMessageSystem? bool LLMessageSystem::checkAllMessages(S64 frame_count, LLPumpIO* http_pump) { + LLMemType mt_cam(LLMemType::MTYPE_MESSAGE_CHECK_ALL); if(checkMessages(frame_count)) { return true; diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h index 3d7d8984ad..27482ca1af 100644 --- a/indra/llmessage/message.h +++ b/indra/llmessage/message.h @@ -509,6 +509,22 @@ private: public: // BOOL decodeData(const U8 *buffer, const LLHost &host); + /** + gets binary data from the current message. + + @param blockname the name of the block in the message (from the message template) + + @param varname + + @param datap + + @param size expected size - set to zero to get any amount of data up to max_size. + Make sure max_size is set in that case! + + @param blocknum + + @param max_size the max number of bytes to read + */ void getBinaryDataFast(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX); void getBinaryData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX); void getBOOLFast( const char *block, const char *var, BOOL &data, S32 blocknum = 0); diff --git a/indra/llmessage/tests/llcurl_stub.cpp b/indra/llmessage/tests/llcurl_stub.cpp index afd38b0655..d6be54336a 100644 --- a/indra/llmessage/tests/llcurl_stub.cpp +++ b/indra/llmessage/tests/llcurl_stub.cpp @@ -2,7 +2,7 @@ * @file llcurl_stub.cpp * @brief stub class to allow unit testing * - * $LicenseInfo:firstyear=2008&license=internal$ + * $LicenseInfo:firstyear=2008&license=viewergpl$ * * Copyright (c) 2008-2009, Linden Research, Inc. * diff --git a/indra/llmessage/tests/lltesthttpclientadapter.cpp b/indra/llmessage/tests/lltesthttpclientadapter.cpp index 9bb597feec..0cea4b57c2 100644 --- a/indra/llmessage/tests/lltesthttpclientadapter.cpp +++ b/indra/llmessage/tests/lltesthttpclientadapter.cpp @@ -2,7 +2,7 @@ * @file * @brief * - * $LicenseInfo:firstyear=2008&license=internal$ + * $LicenseInfo:firstyear=2008&license=viewergpl$ * * Copyright (c) 2008-2009, Linden Research, Inc. * diff --git a/indra/llmessage/tests/lltesthttpclientadapter.h b/indra/llmessage/tests/lltesthttpclientadapter.h index 8853fc44ec..6f252e8510 100644 --- a/indra/llmessage/tests/lltesthttpclientadapter.h +++ b/indra/llmessage/tests/lltesthttpclientadapter.h @@ -2,7 +2,7 @@ * @file * @brief * - * $LicenseInfo:firstyear=2008&license=internal$ + * $LicenseInfo:firstyear=2008&license=viewergpl$ * * Copyright (c) 2008-2009, Linden Research, Inc. * diff --git a/indra/llmessage/tests/lltestmessagesender.cpp b/indra/llmessage/tests/lltestmessagesender.cpp index 2c8456e0a8..3d1876ec36 100644 --- a/indra/llmessage/tests/lltestmessagesender.cpp +++ b/indra/llmessage/tests/lltestmessagesender.cpp @@ -2,7 +2,7 @@ * @file * @brief * - * $LicenseInfo:firstyear=2008&license=internal$ + * $LicenseInfo:firstyear=2008&license=viewergpl$ * * Copyright (c) 2008-2009, Linden Research, Inc. * diff --git a/indra/llmessage/tests/lltestmessagesender.h b/indra/llmessage/tests/lltestmessagesender.h index dfbef6be64..d3aaee8f69 100644 --- a/indra/llmessage/tests/lltestmessagesender.h +++ b/indra/llmessage/tests/lltestmessagesender.h @@ -2,7 +2,7 @@ * @file * @brief * - * $LicenseInfo:firstyear=2008&license=internal$ + * $LicenseInfo:firstyear=2008&license=viewergpl$ * * Copyright (c) 2008-2009, Linden Research, Inc. * |