From dfce4c451c0b12f5836db1af0c26bffc316837fa Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Thu, 2 Aug 2012 22:54:01 +0000 Subject: Added AppearanceData block to AvatarAppearance message --- indra/llmessage/message_prehash.cpp | 3 +++ indra/llmessage/message_prehash.h | 3 +++ 2 files changed, 6 insertions(+) (limited to 'indra/llmessage') diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index d7658862da..c3fa7ff048 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -1376,3 +1376,6 @@ char const* const _PREHASH_ProductSKU = LLMessageStringTable::getInstance()->get char const* const _PREHASH_SeeAVs = LLMessageStringTable::getInstance()->getString("SeeAVs"); char const* const _PREHASH_AnyAVSounds = LLMessageStringTable::getInstance()->getString("AnyAVSounds"); char const* const _PREHASH_GroupAVSounds = LLMessageStringTable::getInstance()->getString("GroupAVSounds"); +char const* const _PREHASH_AppearanceData = LLMessageStringTable::getInstance()->getString("AppearanceData"); +char const* const _PREHASH_AppearanceVersion = LLMessageStringTable::getInstance()->getString("AppearanceVersion"); +char const* const _PREHASH_CofVersion = LLMessageStringTable::getInstance()->getString("CofVersion"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index da2b613f53..9214682003 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -1376,4 +1376,7 @@ extern char const* const _PREHASH_ProductSKU; extern char const* const _PREHASH_SeeAVs; extern char const* const _PREHASH_AnyAVSounds; extern char const* const _PREHASH_GroupAVSounds; +extern char const* const _PREHASH_AppearanceData; +extern char const* const _PREHASH_AppearanceVersion; +extern char const* const _PREHASH_CofVersion; #endif -- cgit v1.2.3 From 64d9705ae21c42f4c7869a414e250c5de251b143 Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Fri, 17 Aug 2012 03:56:38 +0000 Subject: Expanding region flags to 64 bits. Adding region protocol flags --- indra/llmessage/llregionflags.h | 65 +++++++++++++++++++------------------ indra/llmessage/message_prehash.cpp | 4 +++ indra/llmessage/message_prehash.h | 4 +++ 3 files changed, 42 insertions(+), 31 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h index 7b796a0fa8..1cf940918b 100644 --- a/indra/llmessage/llregionflags.h +++ b/indra/llmessage/llregionflags.h @@ -28,95 +28,98 @@ #define LL_LLREGIONFLAGS_H // Can you be hurt here? Should health be on? -const U32 REGION_FLAGS_ALLOW_DAMAGE = (1 << 0); +const U64 REGION_FLAGS_ALLOW_DAMAGE = (1 << 0); // Can you make landmarks here? -const U32 REGION_FLAGS_ALLOW_LANDMARK = (1 << 1); +const U64 REGION_FLAGS_ALLOW_LANDMARK = (1 << 1); // Do we reset the home position when someone teleports away from here? -const U32 REGION_FLAGS_ALLOW_SET_HOME = (1 << 2); +const U64 REGION_FLAGS_ALLOW_SET_HOME = (1 << 2); // Do we reset the home position when someone teleports away from here? -const U32 REGION_FLAGS_RESET_HOME_ON_TELEPORT = (1 << 3); +const U64 REGION_FLAGS_RESET_HOME_ON_TELEPORT = (1 << 3); // Does the sun move? -const U32 REGION_FLAGS_SUN_FIXED = (1 << 4); +const U64 REGION_FLAGS_SUN_FIXED = (1 << 4); // Can't change the terrain heightfield, even on owned parcels, // but can plant trees and grass. -const U32 REGION_FLAGS_BLOCK_TERRAFORM = (1 << 6); +const U64 REGION_FLAGS_BLOCK_TERRAFORM = (1 << 6); // Can't release, sell, or buy land. -const U32 REGION_FLAGS_BLOCK_LAND_RESELL = (1 << 7); +const U64 REGION_FLAGS_BLOCK_LAND_RESELL = (1 << 7); // All content wiped once per night -const U32 REGION_FLAGS_SANDBOX = (1 << 8); -const U32 REGION_FLAGS_SKIP_COLLISIONS = (1 << 12); // Pin all non agent rigid bodies -const U32 REGION_FLAGS_SKIP_SCRIPTS = (1 << 13); -const U32 REGION_FLAGS_SKIP_PHYSICS = (1 << 14); // Skip all physics -const U32 REGION_FLAGS_EXTERNALLY_VISIBLE = (1 << 15); -const U32 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT = (1 << 16); -const U32 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT = (1 << 17); -const U32 REGION_FLAGS_BLOCK_DWELL = (1 << 18); +const U64 REGION_FLAGS_SANDBOX = (1 << 8); +const U64 REGION_FLAGS_SKIP_COLLISIONS = (1 << 12); // Pin all non agent rigid bodies +const U64 REGION_FLAGS_SKIP_SCRIPTS = (1 << 13); +const U64 REGION_FLAGS_SKIP_PHYSICS = (1 << 14); // Skip all physics +const U64 REGION_FLAGS_EXTERNALLY_VISIBLE = (1 << 15); +const U64 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT = (1 << 16); +const U64 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT = (1 << 17); +const U64 REGION_FLAGS_BLOCK_DWELL = (1 << 18); // Is flight allowed? -const U32 REGION_FLAGS_BLOCK_FLY = (1 << 19); +const U64 REGION_FLAGS_BLOCK_FLY = (1 << 19); // Is direct teleport (p2p) allowed? -const U32 REGION_FLAGS_ALLOW_DIRECT_TELEPORT = (1 << 20); +const U64 REGION_FLAGS_ALLOW_DIRECT_TELEPORT = (1 << 20); // Is there an administrative override on scripts in the region at the // moment. This is the similar skip scripts, except this flag is // presisted in the database on an estate level. -const U32 REGION_FLAGS_ESTATE_SKIP_SCRIPTS = (1 << 21); +const U64 REGION_FLAGS_ESTATE_SKIP_SCRIPTS = (1 << 21); -const U32 REGION_FLAGS_RESTRICT_PUSHOBJECT = (1 << 22); +const U64 REGION_FLAGS_RESTRICT_PUSHOBJECT = (1 << 22); -const U32 REGION_FLAGS_DENY_ANONYMOUS = (1 << 23); +const U64 REGION_FLAGS_DENY_ANONYMOUS = (1 << 23); -const U32 REGION_FLAGS_ALLOW_PARCEL_CHANGES = (1 << 26); +const U64 REGION_FLAGS_ALLOW_PARCEL_CHANGES = (1 << 26); -const U32 REGION_FLAGS_ALLOW_VOICE = (1 << 28); +const U64 REGION_FLAGS_ALLOW_VOICE = (1 << 28); -const U32 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29); -const U32 REGION_FLAGS_DENY_AGEUNVERIFIED = (1 << 30); +const U64 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29); +const U64 REGION_FLAGS_DENY_AGEUNVERIFIED = (1 << 30); -const U32 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK | +const U64 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK | REGION_FLAGS_ALLOW_SET_HOME | REGION_FLAGS_ALLOW_PARCEL_CHANGES | REGION_FLAGS_ALLOW_VOICE; -const U32 REGION_FLAGS_PRELUDE_SET = REGION_FLAGS_RESET_HOME_ON_TELEPORT; -const U32 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK +const U64 REGION_FLAGS_PRELUDE_SET = REGION_FLAGS_RESET_HOME_ON_TELEPORT; +const U64 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK | REGION_FLAGS_ALLOW_SET_HOME; -const U32 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE +const U64 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE | REGION_FLAGS_SUN_FIXED | REGION_FLAGS_DENY_ANONYMOUS | REGION_FLAGS_DENY_AGEUNVERIFIED; -inline BOOL is_prelude( U32 flags ) +inline BOOL is_prelude( U64 flags ) { // definition of prelude does not depend on fixed-sun return 0 == (flags & REGION_FLAGS_PRELUDE_UNSET) && 0 != (flags & REGION_FLAGS_PRELUDE_SET); } -inline U32 set_prelude_flags(U32 flags) +inline U64 set_prelude_flags(U64 flags) { // also set the sun-fixed flag return ((flags & ~REGION_FLAGS_PRELUDE_UNSET) | (REGION_FLAGS_PRELUDE_SET | REGION_FLAGS_SUN_FIXED)); } -inline U32 unset_prelude_flags(U32 flags) +inline U64 unset_prelude_flags(U64 flags) { // also unset the fixed-sun flag return ((flags | REGION_FLAGS_PRELUDE_UNSET) & ~(REGION_FLAGS_PRELUDE_SET | REGION_FLAGS_SUN_FIXED)); } +// Region protocols +const U64 REGION_PROTOCOLS_AGENT_APPEARANCE_SERVICE = (1 << 0); + // estate constants. Need to match first few etries in indra.estate table. const U32 ESTATE_ALL = 0; // will not match in db, reserved key for logic const U32 ESTATE_MAINLAND = 1; diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index c3fa7ff048..39cfb6019e 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -279,6 +279,8 @@ char const* const _PREHASH_GrabOffset = LLMessageStringTable::getInstance()->get char const* const _PREHASH_SimPort = LLMessageStringTable::getInstance()->getString("SimPort"); char const* const _PREHASH_PricePerMeter = LLMessageStringTable::getInstance()->getString("PricePerMeter"); char const* const _PREHASH_RegionFlags = LLMessageStringTable::getInstance()->getString("RegionFlags"); +char const* const _PREHASH_RegionFlagsExtended = LLMessageStringTable::getInstance()->getString("RegionFlagsExtended"); +char const* const _PREHASH_RegionProtocols = LLMessageStringTable::getInstance()->getString("RegionProtocols"); char const* const _PREHASH_VoteResult = LLMessageStringTable::getInstance()->getString("VoteResult"); char const* const _PREHASH_ParcelDirFeeEstimate = LLMessageStringTable::getInstance()->getString("ParcelDirFeeEstimate"); char const* const _PREHASH_ModifyBlock = LLMessageStringTable::getInstance()->getString("ModifyBlock"); @@ -305,6 +307,8 @@ char const* const _PREHASH_ViewerStartAuction = LLMessageStringTable::getInstanc char const* const _PREHASH_StartAuction = LLMessageStringTable::getInstance()->getString("StartAuction"); char const* const _PREHASH_DuplicateFlags = LLMessageStringTable::getInstance()->getString("DuplicateFlags"); char const* const _PREHASH_RegionInfo2 = LLMessageStringTable::getInstance()->getString("RegionInfo2"); +char const* const _PREHASH_RegionInfo3 = LLMessageStringTable::getInstance()->getString("RegionInfo3"); +char const* const _PREHASH_RegionInfo4 = LLMessageStringTable::getInstance()->getString("RegionInfo4"); char const* const _PREHASH_TextColor = LLMessageStringTable::getInstance()->getString("TextColor"); char const* const _PREHASH_SlaveID = LLMessageStringTable::getInstance()->getString("SlaveID"); char const* const _PREHASH_Charter = LLMessageStringTable::getInstance()->getString("Charter"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index 9214682003..573e10dc0b 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -279,6 +279,8 @@ extern char const* const _PREHASH_GrabOffset; extern char const* const _PREHASH_SimPort; extern char const* const _PREHASH_PricePerMeter; extern char const* const _PREHASH_RegionFlags; +extern char const* const _PREHASH_RegionFlagsExtended; +extern char const* const _PREHASH_RegionProtocols; extern char const* const _PREHASH_VoteResult; extern char const* const _PREHASH_ParcelDirFeeEstimate; extern char const* const _PREHASH_ModifyBlock; @@ -305,6 +307,8 @@ extern char const* const _PREHASH_ViewerStartAuction; extern char const* const _PREHASH_StartAuction; extern char const* const _PREHASH_DuplicateFlags; extern char const* const _PREHASH_RegionInfo2; +extern char const* const _PREHASH_RegionInfo3; +extern char const* const _PREHASH_RegionInfo4; extern char const* const _PREHASH_TextColor; extern char const* const _PREHASH_SlaveID; extern char const* const _PREHASH_Charter; -- cgit v1.2.3 From 8ba2b388769e245ec1b49b7d6d4b0372d684ff86 Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Thu, 13 Sep 2012 10:25:48 +0000 Subject: Fleshed out target_link_libraries dependencies between libraries. Appearance utility now reads avatar_lad.xml during stubbed out params processing. --- indra/llmessage/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index d98781e9e6..1a90c32fe4 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -218,6 +218,9 @@ add_library (llmessage ${llmessage_SOURCE_FILES}) target_link_libraries( llmessage ${CURL_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${LLVFS_LIBRARES} + ${LLMATH_LIBRARIES} ${CARES_LIBRARIES} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} @@ -243,7 +246,7 @@ if (LL_TESTS) ${LLVFS_LIBRARIES} ${LLMATH_LIBRARIES} ${LLCOMMON_LIBRARIES} - ${GOOGLEMOCK_LIBRARIES} + ${GOOGLEMOCK_LIBRARIES} ) LL_ADD_INTEGRATION_TEST( -- cgit v1.2.3 From 3d5e24d135bd5d2636f075f9ef12ffba2129c61f Mon Sep 17 00:00:00 2001 From: William Todd Stinson Date: Fri, 21 Sep 2012 17:32:28 -0700 Subject: Adding the CXX to each CMake project definition. --- indra/llmessage/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index d98781e9e6..3f324ae005 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -1,6 +1,6 @@ # -*- cmake -*- -project(llmessage) +project(llmessage CXX) include(00-Common) include(GoogleMock) -- cgit v1.2.3 From 95f3fb45ae2f4fe199e34f35be1e46b3a598ca1a Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Mon, 24 Sep 2012 19:42:58 +0000 Subject: Cherry-picked windows build fixes from sunshine-experimental --- indra/llmessage/tests/llhttpclient_test.cpp | 84 +------ indra/llmessage/tests/test_llsdmessage_peer.py | 326 +++++++++++++------------ 2 files changed, 183 insertions(+), 227 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp index e338d4ec71..4a9db7cd98 100644 --- a/indra/llmessage/tests/llhttpclient_test.cpp +++ b/indra/llmessage/tests/llhttpclient_test.cpp @@ -47,37 +47,6 @@ namespace tut { - LLSD storage; - - class LLSDStorageNode : public LLHTTPNode - { - public: - LLSD simpleGet() const { return storage; } - LLSD simplePut(const LLSD& value) const { storage = value; return LLSD(); } - }; - - class ErrorNode : public LLHTTPNode - { - public: - void get(ResponsePtr r, const LLSD& context) const - { r->status(599, "Intentional error"); } - void post(ResponsePtr r, const LLSD& context, const LLSD& input) const - { r->status(input["status"], input["reason"]); } - }; - - class TimeOutNode : public LLHTTPNode - { - public: - void get(ResponsePtr r, const LLSD& context) const - { - /* do nothing, the request will eventually time out */ - } - }; - - LLHTTPRegistration gStorageNode("/test/storage"); - LLHTTPRegistration gErrorNode("/test/error"); - LLHTTPRegistration gTimeOutNode("/test/timeout"); - struct HTTPClientTestData { public: @@ -86,7 +55,6 @@ namespace tut { apr_pool_create(&mPool, NULL); LLCurl::initClass(false); - mServerPump = new LLPumpIO(mPool); mClientPump = new LLPumpIO(mPool); LLHTTPClient::setPump(*mClientPump); @@ -94,20 +62,11 @@ namespace tut ~HTTPClientTestData() { - delete mServerPump; delete mClientPump; LLProxy::cleanupClass(); apr_pool_destroy(mPool); } - void setupTheServer() - { - LLHTTPNode& root = LLIOHTTPServer::create(mPool, *mServerPump, 8888); - - LLHTTPStandardServices::useServices(); - LLHTTPRegistrar::buildAllServices(root); - } - void runThePump(float timeout = 100.0f) { LLTimer timer; @@ -115,11 +74,7 @@ namespace tut while(!mSawCompleted && !mSawCompletedHeader && !timer.hasExpired()) { - if (mServerPump) - { - mServerPump->pump(); - mServerPump->callback(); - } + LLFrameTimer::updateFrameTime(); if (mClientPump) { mClientPump->pump(); @@ -128,17 +83,10 @@ namespace tut } } - void killServer() - { - delete mServerPump; - mServerPump = NULL; - } - const std::string local_server; private: apr_pool_t* mPool; - LLPumpIO* mServerPump; LLPumpIO* mClientPump; protected: @@ -283,14 +231,12 @@ namespace tut sd["list"][1]["three"] = 3; sd["list"][1]["four"] = 4; - setupTheServer(); - - LLHTTPClient::post("http://localhost:8888/web/echo", sd, newResult()); + LLHTTPClient::post(local_server + "web/echo", sd, newResult()); runThePump(); ensureStatusOK(); ensure_equals("echoed result matches", getResult(), sd); } - + template<> template<> void HTTPClientTestObject::test<4>() { @@ -298,12 +244,11 @@ namespace tut sd["message"] = "This is my test message."; - setupTheServer(); - LLHTTPClient::put("http://localhost:8888/test/storage", sd, newResult()); + LLHTTPClient::put(local_server + "test/storage", sd, newResult()); runThePump(); ensureStatusOK(); - LLHTTPClient::get("http://localhost:8888/test/storage", newResult()); + LLHTTPClient::get(local_server + "test/storage", newResult()); runThePump(); ensureStatusOK(); ensure_equals("echoed result matches", getResult(), sd); @@ -317,9 +262,7 @@ namespace tut sd["status"] = 543; sd["reason"] = "error for testing"; - setupTheServer(); - - LLHTTPClient::post("http://localhost:8888/test/error", sd, newResult()); + LLHTTPClient::post(local_server + "test/error", sd, newResult()); runThePump(); ensureStatusError(); ensure_contains("reason", mReason, sd["reason"]); @@ -328,23 +271,16 @@ namespace tut template<> template<> void HTTPClientTestObject::test<6>() { - setupTheServer(); - - LLHTTPClient::get("http://localhost:8888/test/timeout", newResult()); - runThePump(1.0f); - killServer(); - runThePump(); + const F32 timeout = 1.0f; + LLHTTPClient::get(local_server + "test/timeout", newResult(), LLSD(), timeout); + runThePump(timeout * 5.0f); ensureStatusError(); - ensure_equals("reason", mReason, "STATUS_ERROR"); + ensure_equals("reason", mReason, "STATUS_EXPIRED"); } 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. LLHTTPClient::get(local_server, newResult()); runThePump(); ensureStatusOK(); diff --git a/indra/llmessage/tests/test_llsdmessage_peer.py b/indra/llmessage/tests/test_llsdmessage_peer.py index fe4f3a8c01..b59c5a06cd 100644 --- a/indra/llmessage/tests/test_llsdmessage_peer.py +++ b/indra/llmessage/tests/test_llsdmessage_peer.py @@ -1,153 +1,173 @@ -#!/usr/bin/env python -"""\ -@file test_llsdmessage_peer.py -@author Nat Goodspeed -@date 2008-10-09 -@brief This script asynchronously runs the executable (with args) specified on - the command line, returning its result code. While that executable is - running, we provide dummy local services for use by C++ tests. - -$LicenseInfo:firstyear=2008&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2010, 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$ -""" - -import os -import sys -from threading import Thread -from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler - -mydir = os.path.dirname(__file__) # expected to be .../indra/llmessage/tests/ -sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python")) -from indra.util.fastest_elementtree import parse as xml_parse -from indra.base import llsd -from testrunner import freeport, run, debug, VERBOSE - -class TestHTTPRequestHandler(BaseHTTPRequestHandler): - """This subclass of BaseHTTPRequestHandler is to receive and echo - LLSD-flavored messages sent by the C++ LLHTTPClient. - """ - def read(self): - # The following logic is adapted from the library module - # SimpleXMLRPCServer.py. - # Get arguments by reading body of request. - # We read this in chunks to avoid straining - # socket.read(); around the 10 or 15Mb mark, some platforms - # begin to have problems (bug #792570). - try: - size_remaining = int(self.headers["content-length"]) - except (KeyError, ValueError): - return "" - max_chunk_size = 10*1024*1024 - L = [] - while size_remaining: - chunk_size = min(size_remaining, max_chunk_size) - chunk = self.rfile.read(chunk_size) - L.append(chunk) - size_remaining -= len(chunk) - return ''.join(L) - # end of swiped read() logic - - def read_xml(self): - # This approach reads the entire POST data into memory first - return llsd.parse(self.read()) -## # This approach attempts to stream in the LLSD XML from self.rfile, -## # assuming that the underlying XML parser reads its input file -## # incrementally. Unfortunately I haven't been able to make it work. -## tree = xml_parse(self.rfile) -## debug("Finished raw parse") -## debug("parsed XML tree %s", tree) -## debug("parsed root node %s", tree.getroot()) -## debug("root node tag %s", tree.getroot().tag) -## return llsd.to_python(tree.getroot()) - - def do_HEAD(self): - self.do_GET(withdata=False) - - def do_GET(self, withdata=True): - # Of course, don't attempt to read data. - data = dict(reply="success", body="avatar", random=17) - self.answer(data, withdata=withdata) - - def do_POST(self): - # Read the provided POST data. - self.answer(self.read_xml()) - - def answer(self, data, withdata=True): - debug("%s.answer(%s): self.path = %r", self.__class__.__name__, data, self.path) - if "fail" not in self.path: - data = data.copy() # we're going to modify - # Ensure there's a "reply" key in data, even if there wasn't before - data["reply"] = data.get("reply", llsd.LLSD("success")) - response = llsd.format_xml(data) - debug("success: %s", response) - self.send_response(200) - self.send_header("Content-type", "application/llsd+xml") - self.send_header("Content-Length", str(len(response))) - self.end_headers() - if withdata: - self.wfile.write(response) - else: # fail requested - status = data.get("status", 500) - # self.responses maps an int status to a (short, long) pair of - # strings. We want the longer string. That's why we pass a string - # pair to get(): the [1] will select the second string, whether it - # came from self.responses or from our default pair. - reason = data.get("reason", - self.responses.get(status, - ("fail requested", - "Your request specified failure status %s " - "without providing a reason" % status))[1]) - debug("fail requested: %s: %r", status, reason) - self.send_error(status, reason) - - if not VERBOSE: - # When VERBOSE is set, skip both these overrides because they exist to - # suppress output. - - def log_request(self, code, size=None): - # For present purposes, we don't want the request splattered onto - # stderr, as it would upset devs watching the test run - pass - - def log_error(self, format, *args): - # Suppress error output as well - pass - -class Server(HTTPServer): - # This pernicious flag is on by default in HTTPServer. But proper - # operation of freeport() absolutely depends on it being off. - allow_reuse_address = False - -if __name__ == "__main__": - # Instantiate a Server(TestHTTPRequestHandler) on the first free port - # in the specified port range. Doing this inline is better than in a - # daemon thread: if it blows up here, we'll get a traceback. If it blew up - # in some other thread, the traceback would get eaten and we'd run the - # subject test program anyway. - httpd, port = freeport(xrange(8000, 8020), - lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler)) - # Pass the selected port number to the subject test program via the - # environment. We don't want to impose requirements on the test program's - # command-line parsing -- and anyway, for C++ integration tests, that's - # performed in TUT code rather than our own. - os.environ["PORT"] = str(port) - debug("$PORT = %s", port) - sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), *sys.argv[1:])) +#!/usr/bin/env python +"""\ +@file test_llsdmessage_peer.py +@author Nat Goodspeed +@date 2008-10-09 +@brief This script asynchronously runs the executable (with args) specified on + the command line, returning its result code. While that executable is + running, we provide dummy local services for use by C++ tests. + +$LicenseInfo:firstyear=2008&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2010, 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$ +""" + +import os +import sys +from threading import Thread +from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler + +mydir = os.path.dirname(__file__) # expected to be .../indra/llmessage/tests/ +sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python")) +from indra.util.fastest_elementtree import parse as xml_parse +from indra.base import llsd +from testrunner import freeport, run, debug, VERBOSE +import time + +_storage=None + +class TestHTTPRequestHandler(BaseHTTPRequestHandler): + """This subclass of BaseHTTPRequestHandler is to receive and echo + LLSD-flavored messages sent by the C++ LLHTTPClient. + """ + def read(self): + # The following logic is adapted from the library module + # SimpleXMLRPCServer.py. + # Get arguments by reading body of request. + # We read this in chunks to avoid straining + # socket.read(); around the 10 or 15Mb mark, some platforms + # begin to have problems (bug #792570). + try: + size_remaining = int(self.headers["content-length"]) + except (KeyError, ValueError): + return "" + max_chunk_size = 10*1024*1024 + L = [] + while size_remaining: + chunk_size = min(size_remaining, max_chunk_size) + chunk = self.rfile.read(chunk_size) + L.append(chunk) + size_remaining -= len(chunk) + return ''.join(L) + # end of swiped read() logic + + def read_xml(self): + # This approach reads the entire POST data into memory first + return llsd.parse(self.read()) +## # This approach attempts to stream in the LLSD XML from self.rfile, +## # assuming that the underlying XML parser reads its input file +## # incrementally. Unfortunately I haven't been able to make it work. +## tree = xml_parse(self.rfile) +## debug("Finished raw parse") +## debug("parsed XML tree %s", tree) +## debug("parsed root node %s", tree.getroot()) +## debug("root node tag %s", tree.getroot().tag) +## return llsd.to_python(tree.getroot()) + + def do_HEAD(self): + self.do_GET(withdata=False) + + def do_GET(self, withdata=True): + # Of course, don't attempt to read data. + data = dict(reply="success", body="avatar", random=17) + self.answer(data, withdata=withdata) + + def do_POST(self): + # Read the provided POST data. + self.answer(self.read_xml()) + + def do_PUT(self): + # Read the provided PUT data. + self.answer(self.read_xml()) + + def answer(self, data, withdata=True): + global _storage + debug("%s.answer(%s): self.path = %r", self.__class__.__name__, data, self.path) + if "fail" in self.path or "test/error" in self.path: # fail requested + status = data.get("status", 500) + # self.responses maps an int status to a (short, long) pair of + # strings. We want the longer string. That's why we pass a string + # pair to get(): the [1] will select the second string, whether it + # came from self.responses or from our default pair. + reason = data.get("reason", + self.responses.get(status, + ("fail requested", + "Your request specified failure status %s " + "without providing a reason" % status))[1]) + debug("fail requested: %s: %r", status, reason) + self.send_error(status, reason) + else: + if "web/echo" in self.path: + pass + elif "test/timeout" in self.path: + time.sleep(5.0) + return + elif "test/storage" in self.path: + if "GET" == self.command: + data = _storage + else: + _storage = data + data = "ok" + else: + data = data.copy() # we're going to modify + # Ensure there's a "reply" key in data, even if there wasn't before + data["reply"] = data.get("reply", llsd.LLSD("success")) + response = llsd.format_xml(data) + debug("success: %s", response) + self.send_response(200) + self.send_header("Content-type", "application/llsd+xml") + self.send_header("Content-Length", str(len(response))) + self.end_headers() + if withdata: + self.wfile.write(response) + + if not VERBOSE: + # When VERBOSE is set, skip both these overrides because they exist to + # suppress output. + + def log_request(self, code, size=None): + # For present purposes, we don't want the request splattered onto + # stderr, as it would upset devs watching the test run + pass + + def log_error(self, format, *args): + # Suppress error output as well + pass + +class Server(HTTPServer): + # This pernicious flag is on by default in HTTPServer. But proper + # operation of freeport() absolutely depends on it being off. + allow_reuse_address = False + +if __name__ == "__main__": + # Instantiate a Server(TestHTTPRequestHandler) on the first free port + # in the specified port range. Doing this inline is better than in a + # daemon thread: if it blows up here, we'll get a traceback. If it blew up + # in some other thread, the traceback would get eaten and we'd run the + # subject test program anyway. + httpd, port = freeport(xrange(8000, 8020), + lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler)) + # Pass the selected port number to the subject test program via the + # environment. We don't want to impose requirements on the test program's + # command-line parsing -- and anyway, for C++ integration tests, that's + # performed in TUT code rather than our own. + os.environ["PORT"] = str(port) + debug("$PORT = %s", port) + sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), *sys.argv[1:])) -- cgit v1.2.3 From 0ca59987843cfcaedb12592b9466567ef421c4e8 Mon Sep 17 00:00:00 2001 From: William Todd Stinson Date: Wed, 3 Oct 2012 17:53:28 -0700 Subject: Backed out changeset: eb957fafe167 --- indra/llmessage/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index 3f324ae005..d98781e9e6 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -1,6 +1,6 @@ # -*- cmake -*- -project(llmessage CXX) +project(llmessage) include(00-Common) include(GoogleMock) -- cgit v1.2.3 From c06c35609c6683731eaea283468f6b32af18fea2 Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Thu, 11 Oct 2012 00:09:04 +0000 Subject: Updating linux build to gcc4.6 --- indra/llmessage/llhttpassetstorage.cpp | 2 +- indra/llmessage/lliosocket.cpp | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp index 612d765969..7dcf160c9b 100644 --- a/indra/llmessage/llhttpassetstorage.cpp +++ b/indra/llmessage/llhttpassetstorage.cpp @@ -747,7 +747,7 @@ LLAssetRequest* LLHTTPAssetStorage::findNextRequest(LLAssetStorage::request_list request_list_t::iterator running_end = running.end(); request_list_t::iterator pending_iter = pending.begin(); - request_list_t::iterator pending_end = pending.end(); + // Loop over all pending requests until we miss finding it in the running list. for (; pending_iter != pending.end(); ++pending_iter) { diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp index d5b4d45821..46430994d9 100644 --- a/indra/llmessage/lliosocket.cpp +++ b/indra/llmessage/lliosocket.cpp @@ -608,6 +608,15 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl( PUMP_DEBUG; apr_pool_t* new_pool = NULL; apr_status_t status = apr_pool_create(&new_pool, mPool); + if(ll_apr_warn_status(status)) + { + if(new_pool) + { + apr_pool_destroy(new_pool); + } + return STATUS_ERROR; + } + apr_socket_t* socket = NULL; status = apr_socket_accept( &socket, -- cgit v1.2.3 From d4dc41dbd5b54501fcb3c94e07e4753ed4196eac Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 1 Nov 2012 14:19:00 -0400 Subject: misc error detection, debug coloration for avatar meshes --- indra/llmessage/llurlrequest.cpp | 4 ++++ 1 file changed, 4 insertions(+) mode change 100644 => 100755 indra/llmessage/llurlrequest.cpp (limited to 'indra/llmessage') diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp old mode 100644 new mode 100755 index f3f0007205..8c0ad35204 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -181,6 +181,10 @@ void LLURLRequest::setURL(const std::string& url) { LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); mDetail->mURL = url; + if (url.empty()) + { + llwarns << "empty URL specified" << llendl; + } } std::string LLURLRequest::getURL() const -- cgit v1.2.3 From fa85e16d63b09326b9facb4850d50cd163f87bc7 Mon Sep 17 00:00:00 2001 From: William Todd Stinson Date: Wed, 7 Nov 2012 17:47:35 -0800 Subject: Removing unused code. --- indra/llmessage/lldbstrings.h | 12 --------- indra/llmessage/llinstantmessage.cpp | 17 +----------- indra/llmessage/llinstantmessage.h | 51 ------------------------------------ 3 files changed, 1 insertion(+), 79 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/lldbstrings.h b/indra/llmessage/lldbstrings.h index 9bf1b3eda4..e23d17d5b6 100644 --- a/indra/llmessage/lldbstrings.h +++ b/indra/llmessage/lldbstrings.h @@ -156,18 +156,6 @@ const S32 DB_USER_SKILLS_BUF_SIZE = 255; const S32 DB_NV_NAME_STR_LEN = 128; const S32 DB_NV_NAME_BUF_SIZE = 129; -// votes.vote_text varchar(254) -const S32 DB_VOTE_TEXT_STR_LEN = 254; -const S32 DB_VOTE_TEXT_BUF_SIZE = 255; - -// vpte type text varchar(9) -const S32 DB_VOTE_TYPE_STR_LEN = 9; -const S32 DB_VOTE_TYPE_BUF_SIZE = 10; - -// vote result text -const S32 DB_VOTE_RESULT_BUF_LEN = 8; -const S32 DB_VOTE_RESULT_BUF_SIZE = 9; - // user_start_location.location_name varchar(254) const S32 DB_START_LOCATION_STR_LEN = 254; const S32 DB_START_LOCATION_BUF_SIZE = 255; diff --git a/indra/llmessage/llinstantmessage.cpp b/indra/llmessage/llinstantmessage.cpp index d68e0c423e..b0275c161b 100644 --- a/indra/llmessage/llinstantmessage.cpp +++ b/indra/llmessage/llinstantmessage.cpp @@ -43,14 +43,6 @@ const U8 IM_ONLINE = 0; const U8 IM_OFFLINE = 1; -const S32 VOTE_YES = 1; -const S32 VOTE_NO = 0; -const S32 VOTE_ABSTAIN = -1; - -const S32 VOTE_MAJORITY = 0; -const S32 VOTE_SUPER_MAJORITY = 1; -const S32 VOTE_UNANIMOUS = 2; - const char EMPTY_BINARY_BUCKET[] = ""; const S32 EMPTY_BINARY_BUCKET_SIZE = 1; const U32 NO_TIMESTAMP = 0; @@ -69,7 +61,6 @@ LLIMInfo::LLIMInfo() : mViewerThinksToIsOnline(false), mIMType(IM_NOTHING_SPECIAL), mTimeStamp(0), - mSource(IM_FROM_SIM), mTTL(IM_TTL) { } @@ -88,7 +79,6 @@ LLIMInfo::LLIMInfo( LLSD data, U8 offline, U32 timestamp, - EIMSource source, S32 ttl) : mFromID(from_id), mFromGroup(from_group), @@ -104,14 +94,12 @@ LLIMInfo::LLIMInfo( mName(name), mMessage(message), mData(data), - mSource(source), mTTL(ttl) { } -LLIMInfo::LLIMInfo(LLMessageSystem* msg, EIMSource source, S32 ttl) : +LLIMInfo::LLIMInfo(LLMessageSystem* msg, S32 ttl) : mViewerThinksToIsOnline(false), - mSource(source), mTTL(ttl) { unpackMessageBlock(msg); @@ -326,7 +314,6 @@ LLSD im_info_to_llsd(LLPointer im_info) param_message["region_id"] = im_info->mRegionID; param_message["position"] = ll_sd_from_vector3(im_info->mPosition); param_message["data"] = im_info->mData; - param_message["source"]= im_info->mSource; param_message["ttl"] = im_info->mTTL; LLSD param_agent; @@ -359,7 +346,6 @@ LLPointer llsd_to_im_info(const LLSD& im_info_sd) param_message["data"], (U8) param_message["offline"].asInteger(), (U32) param_message["timestamp"].asInteger(), - (EIMSource)param_message["source"].asInteger(), param_message["ttl"].asInteger()); return im_info; @@ -381,7 +367,6 @@ LLPointer LLIMInfo::clone() mData, mOffline, mTimeStamp, - mSource, mTTL); } diff --git a/indra/llmessage/llinstantmessage.h b/indra/llmessage/llinstantmessage.h index e0dae376b4..12e4e79475 100644 --- a/indra/llmessage/llinstantmessage.h +++ b/indra/llmessage/llinstantmessage.h @@ -164,57 +164,9 @@ enum EInstantMessage }; -// Hooks for quickly hacking in experimental admin debug messages -// without needing to recompile the viewer -// *NOTE: This functionality has been moved to be a string based -// operation so that we don't even have to do a full recompile. This -// enumeration will be phased out soon. -enum EGodlikeRequest -{ - GOD_WANTS_NOTHING, - - // for requesting physics information about an object - GOD_WANTS_PHYSICS_INFO, - - // two unused requests that can be appropriated for debug - // purposes (no viewer recompile necessary) - GOD_WANTS_FOO, - GOD_WANTS_BAR, - - // to dump simulator terrain data to terrain.raw file - GOD_WANTS_TERRAIN_SAVE, - // to load simulator terrain data from terrain.raw file - GOD_WANTS_TERRAIN_LOAD, - - GOD_WANTS_TOGGLE_AVATAR_GEOMETRY, // HACK for testing new avatar geom - - // real-time telehub operations - GOD_WANTS_TELEHUB_INFO, - GOD_WANTS_CONNECT_TELEHUB, - GOD_WANTS_DELETE_TELEHUB, - GOD_WANTS_ADD_TELEHUB_SPAWNPOINT, - GOD_WANTS_REMOVE_TELEHUB_SPAWNPOINT, - -}; - -enum EIMSource -{ - IM_FROM_VIEWER, - IM_FROM_DATASERVER, - IM_FROM_SIM -}; - extern const U8 IM_ONLINE; extern const U8 IM_OFFLINE; -extern const S32 VOTE_YES; -extern const S32 VOTE_NO; -extern const S32 VOTE_ABSTAIN; - -extern const S32 VOTE_MAJORITY; -extern const S32 VOTE_SUPER_MAJORITY; -extern const S32 VOTE_UNANIMOUS; - extern const char EMPTY_BINARY_BUCKET[]; extern const S32 EMPTY_BINARY_BUCKET_SIZE; @@ -234,7 +186,6 @@ protected: public: LLIMInfo(LLMessageSystem* msg, - EIMSource source = IM_FROM_SIM, S32 ttl = IM_TTL); LLIMInfo( @@ -251,7 +202,6 @@ public: LLSD data, U8 offline, U32 timestamp, - EIMSource source, S32 ttl = IM_TTL); void packInstantMessage(LLMessageSystem* msg) const; @@ -274,7 +224,6 @@ public: std::string mMessage; LLSD mData; - EIMSource mSource; S32 mTTL; }; -- cgit v1.2.3 From c4eaaa3d6a08330863119d550d365315ba7526bb Mon Sep 17 00:00:00 2001 From: William Todd Stinson Date: Thu, 8 Nov 2012 12:35:15 -0800 Subject: CHUI-484: Updating the code to rather than refer to it as Busy Mode, it now refers to it as Do Not Disturb mode. --- indra/llmessage/llinstantmessage.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/llinstantmessage.h b/indra/llmessage/llinstantmessage.h index 12e4e79475..db4a38ea9e 100644 --- a/indra/llmessage/llinstantmessage.h +++ b/indra/llmessage/llinstantmessage.h @@ -115,8 +115,8 @@ enum EInstantMessage // viewer, since you can't IM an object yet. IM_FROM_TASK = 19, - // sent an IM to a busy user, this is the auto response - IM_BUSY_AUTO_RESPONSE = 20, + // sent an IM to a do not disturb user, this is the auto response + IM_DO_NOT_DISTURB_AUTO_RESPONSE = 20, // Shows the message in the console and chat history IM_CONSOLE_AND_CHAT_HISTORY = 21, -- cgit v1.2.3 From 3a49beed0e96a797a6d663bcae5e932437ca3661 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Wed, 5 Dec 2012 20:25:46 -0800 Subject: CHUI-580 : WIP : Change the display name cache system, deprecating the old protocol and using the cap (People API) whenever available. Still has occurence of Resident as last name to clean up. --- indra/llmessage/llavatarnamecache.cpp | 56 +++++++++++------------------------ indra/llmessage/llavatarnamecache.h | 2 ++ indra/llmessage/llcachename.cpp | 6 ++-- 3 files changed, 23 insertions(+), 41 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 700525e1fa..329871d8eb 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -43,10 +43,6 @@ namespace LLAvatarNameCache { use_display_name_signal_t mUseDisplayNamesSignal; - // Manual override for display names - can disable even if the region - // supports it. - bool sUseDisplayNames = true; - // Cache starts in a paused state until we can determine if the // current region supports display names. bool sRunning = false; @@ -209,17 +205,8 @@ public: // Use expiration time from header av_name.mExpires = expires; - // Some avatars don't have explicit display names set - if (av_name.mDisplayName.empty()) - { - av_name.mDisplayName = av_name.mUsername; - } - - LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << " " - << "user '" << av_name.mUsername << "' " - << "display '" << av_name.mDisplayName << "' " - << "expires in " << expires - now << " seconds" - << LL_ENDL; + LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << LL_ENDL; + av_name.dump(); // cache it and fire signals LLAvatarNameCache::processName(agent_id, av_name, true); @@ -291,12 +278,9 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id) LLAvatarNameCache::sPendingQueue.erase(agent_id); LLAvatarName& av_name = existing->second; - LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " - << agent_id - << "user '" << av_name.mUsername << "' " - << "display '" << av_name.mDisplayName << "' " - << "expires in " << av_name.mExpires - LLFrameTimer::getTotalSeconds() << " seconds" - << LL_ENDL; + LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " << agent_id << LL_ENDL; + av_name.dump(); + av_name.mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; // reset expiry time so we don't constantly rerequest. } } @@ -476,7 +460,7 @@ void LLAvatarNameCache::exportFile(std::ostream& ostr) const LLUUID& agent_id = it->first; const LLAvatarName& av_name = it->second; // Do not write temporary or expired entries to the stored cache - if (!av_name.mIsTemporaryName && av_name.mExpires >= max_unrefreshed) + if (av_name.isValidName(max_unrefreshed)) { // key must be a string agents[agent_id.asString()] = av_name.asLLSD(); @@ -513,7 +497,7 @@ void LLAvatarNameCache::idle() if (!sAskQueue.empty()) { - if (useDisplayNames()) + if (hasNameLookupURL()) { requestNamesViaCapability(); } @@ -565,7 +549,7 @@ void LLAvatarNameCache::eraseUnrefreshed() { const LLUUID& agent_id = it->first; LL_DEBUGS("AvNameCache") << agent_id - << " user '" << av_name.mUsername << "' " + << " user '" << av_name.getUserName() << "' " << "expired " << now - av_name.mExpires << " secs ago" << LL_ENDL; sCache.erase(it++); @@ -583,14 +567,12 @@ void LLAvatarNameCache::buildLegacyName(const std::string& full_name, LLAvatarName* av_name) { llassert(av_name); - av_name->mUsername = ""; - av_name->mDisplayName = full_name; - av_name->mIsDisplayNameDefault = true; - av_name->mIsTemporaryName = true; - av_name->mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; + av_name->fromString(full_name,TEMP_CACHE_ENTRY_LIFETIME); LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName " << full_name << LL_ENDL; + // DEBUG ONLY!!! DO NOT COMMIT!!! + av_name->dump(); } // fills in av_name if it has it in the cache, even if expired (can check expiry time) @@ -600,7 +582,7 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) if (sRunning) { // ...only do immediate lookups when cache is running - if (useDisplayNames()) + if (hasNameLookupURL()) { // ...use display names cache std::map::iterator it = sCache.find(agent_id); @@ -662,7 +644,7 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag if (sRunning) { // ...only do immediate lookups when cache is running - if (useDisplayNames()) + if (hasNameLookupURL()) { // ...use new cache std::map::iterator it = sCache.find(agent_id); @@ -720,20 +702,16 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag void LLAvatarNameCache::setUseDisplayNames(bool use) { - if (use != sUseDisplayNames) + if (use != LLAvatarName::useDisplayNames()) { - sUseDisplayNames = use; - // flush our cache - sCache.clear(); - + LLAvatarName::setUseDisplayNames(use); mUseDisplayNamesSignal(); } } -bool LLAvatarNameCache::useDisplayNames() +void LLAvatarNameCache::flushCache() { - // Must be both manually set on and able to look up names. - return sUseDisplayNames && !sNameLookupURL.empty(); + sCache.clear(); } void LLAvatarNameCache::erase(const LLUUID& agent_id) diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index 79f170f7c8..e172601432 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -81,6 +81,8 @@ namespace LLAvatarNameCache void setUseDisplayNames(bool use); bool useDisplayNames(); + void flushCache(); + void erase(const LLUUID& agent_id); /// Provide some fallback for agents that return errors diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp index 479efabb5f..da07c9ae42 100644 --- a/indra/llmessage/llcachename.cpp +++ b/indra/llmessage/llcachename.cpp @@ -524,6 +524,7 @@ std::string LLCacheName::cleanFullName(const std::string& full_name) } //static +// Transform hard-coded name provided by server to a more legible username std::string LLCacheName::buildUsername(const std::string& full_name) { // rare, but handle hard-coded error names returned from server @@ -549,8 +550,9 @@ std::string LLCacheName::buildUsername(const std::string& full_name) return username; } - // if the input wasn't a correctly formatted legacy name just return it unchanged - return full_name; + // if the input wasn't a correctly formatted legacy name, just return it + // cleaned up from a potential terminal "Resident" + return cleanFullName(full_name); } //static -- cgit v1.2.3 From bb322a1cccd3fab28951ad4e11b5edcfc4e48140 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 7 Dec 2012 00:10:50 -0800 Subject: CHUI-580 : Fixed : Clean up the use of display name. Allow the use of the legacy protocol in settings.xml --- indra/llmessage/llavatarnamecache.cpp | 170 ++++++++++++---------------------- indra/llmessage/llavatarnamecache.h | 32 +++---- indra/llmessage/llcachename.h | 2 +- 3 files changed, 75 insertions(+), 129 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 329871d8eb..15c4f2a207 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -47,18 +47,22 @@ namespace LLAvatarNameCache // current region supports display names. bool sRunning = false; + // Use the People API (modern) for fetching name if true. Use the old legacy protocol if false. + // For testing, there's a UsePeopleAPI setting that can be flipped (must restart viewer). + bool sUsePeopleAPI = true; + // Base lookup URL for name service. // On simulator, loaded from indra.xml // On viewer, usually a simulator capability (at People API team's request) // Includes the trailing slash, like "http://pdp60.lindenlab.com:8000/agents/" std::string sNameLookupURL; - // accumulated agent IDs for next query against service + // Accumulated agent IDs for next query against service typedef std::set ask_queue_t; ask_queue_t sAskQueue; - // agent IDs that have been requested, but with no reply - // maps agent ID to frame time request was made + // Agent IDs that have been requested, but with no reply. + // Maps agent ID to frame time request was made. typedef std::map pending_queue_t; pending_queue_t sPendingQueue; @@ -69,21 +73,21 @@ namespace LLAvatarNameCache typedef std::map signal_map_t; signal_map_t sSignalMap; - // names we know about + // The cache at last, i.e. avatar names we know about. typedef std::map cache_t; cache_t sCache; - // Send bulk lookup requests a few times a second at most - // only need per-frame timing resolution + // Send bulk lookup requests a few times a second at most. + // Only need per-frame timing resolution. LLFrameTimer sRequestTimer; - /// Maximum time an unrefreshed cache entry is allowed + // Maximum time an unrefreshed cache entry is allowed. const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0; - /// Time when unrefreshed cached names were checked last + // Time when unrefreshed cached names were checked last. static F64 sLastExpireCheck; - /// Time-to-live for a temp cache entry. + // Time-to-live for a temp cache entry. const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0; //----------------------------------------------------------------------- @@ -91,26 +95,18 @@ namespace LLAvatarNameCache //----------------------------------------------------------------------- // Handle name response off network. - // Optionally skip adding to cache, used when this is a fallback to the - // legacy name system. void processName(const LLUUID& agent_id, - const LLAvatarName& av_name, - bool add_to_cache); + const LLAvatarName& av_name); void requestNamesViaCapability(); // Legacy name system callback void legacyNameCallback(const LLUUID& agent_id, const std::string& full_name, - bool is_group - ); + bool is_group); void requestNamesViaLegacy(); - // Fill in an LLAvatarName with the legacy name data - void buildLegacyName(const std::string& full_name, - LLAvatarName* av_name); - // Do a single callback to a given slot void fireSignal(const LLUUID& agent_id, const callback_slot_t& slot, @@ -209,7 +205,7 @@ public: av_name.dump(); // cache it and fire signals - LLAvatarNameCache::processName(agent_id, av_name, true); + LLAvatarNameCache::processName(agent_id, av_name); } // Same logic as error response case @@ -271,7 +267,7 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id) } else { - // we have a chached (but probably expired) entry - since that would have + // we have a cached (but probably expired) entry - since that would have // been returned by the get method, there is no need to signal anyone // Clear this agent from the pending list @@ -281,22 +277,20 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id) LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " << agent_id << LL_ENDL; av_name.dump(); - av_name.mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; // reset expiry time so we don't constantly rerequest. + // Reset expiry time so we don't constantly rerequest. + av_name.setExpires(TEMP_CACHE_ENTRY_LIFETIME); } } -void LLAvatarNameCache::processName(const LLUUID& agent_id, - const LLAvatarName& av_name, - bool add_to_cache) +void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName& av_name) { - if (add_to_cache) - { - sCache[agent_id] = av_name; - } + // Add to the cache + sCache[agent_id] = av_name; + // Suppress request from the queue sPendingQueue.erase(agent_id); - // signal everyone waiting on this name + // Signal everyone waiting on this name signal_map_t::iterator sig_it = sSignalMap.find(agent_id); if (sig_it != sSignalMap.end()) { @@ -373,22 +367,20 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id, const std::string& full_name, bool is_group) { - // Construct a dummy record for this name. By convention, SLID is blank - // Never expires, but not written to disk, so lasts until end of session. - LLAvatarName av_name; LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::legacyNameCallback " << "agent " << agent_id << " " << "full name '" << full_name << "'" << ( is_group ? " [group]" : "" ) << LL_ENDL; - buildLegacyName(full_name, &av_name); + + // Construct an av_name record from this name. + LLAvatarName av_name; + av_name.fromString(full_name); + av_name.dump(); // Add to cache, because if we don't we'll keep rerequesting the - // same record forever. buildLegacyName should always guarantee - // that these records expire reasonably soon - // (in TEMP_CACHE_ENTRY_LIFETIME seconds), so if the failure was due - // to something temporary we will eventually request and get the right data. - processName(agent_id, av_name, true); + // same record forever. + processName(agent_id, av_name); } void LLAvatarNameCache::requestNamesViaLegacy() @@ -410,18 +402,19 @@ void LLAvatarNameCache::requestNamesViaLegacy() LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaLegacy agent " << agent_id << LL_ENDL; gCacheName->get(agent_id, false, // legacy compatibility - boost::bind(&LLAvatarNameCache::legacyNameCallback, - _1, _2, _3)); + boost::bind(&LLAvatarNameCache::legacyNameCallback, _1, _2, _3)); } } -void LLAvatarNameCache::initClass(bool running) +void LLAvatarNameCache::initClass(bool running, bool usePeopleAPI) { sRunning = running; + sUsePeopleAPI = usePeopleAPI; } void LLAvatarNameCache::cleanupClass() { + sCache.clear(); } void LLAvatarNameCache::importFile(std::istream& istr) @@ -481,6 +474,11 @@ bool LLAvatarNameCache::hasNameLookupURL() return !sNameLookupURL.empty(); } +bool LLAvatarNameCache::usePeopleAPI() +{ + return hasNameLookupURL() && sUsePeopleAPI; +} + void LLAvatarNameCache::idle() { // By convention, start running at first idle() call @@ -497,13 +495,12 @@ void LLAvatarNameCache::idle() if (!sAskQueue.empty()) { - if (hasNameLookupURL()) + if (usePeopleAPI()) { requestNamesViaCapability(); } else { - // ...fall back to legacy name cache system requestNamesViaLegacy(); } } @@ -563,18 +560,6 @@ void LLAvatarNameCache::eraseUnrefreshed() } } -void LLAvatarNameCache::buildLegacyName(const std::string& full_name, - LLAvatarName* av_name) -{ - llassert(av_name); - av_name->fromString(full_name,TEMP_CACHE_ENTRY_LIFETIME); - LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName " - << full_name - << LL_ENDL; - // DEBUG ONLY!!! DO NOT COMMIT!!! - av_name->dump(); -} - // fills in av_name if it has it in the cache, even if expired (can check expiry time) // returns bool specifying if av_name was filled, false otherwise bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) @@ -582,38 +567,24 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) if (sRunning) { // ...only do immediate lookups when cache is running - if (hasNameLookupURL()) + std::map::iterator it = sCache.find(agent_id); + if (it != sCache.end()) { - // ...use display names cache - std::map::iterator it = sCache.find(agent_id); - if (it != sCache.end()) - { - *av_name = it->second; + *av_name = it->second; - // re-request name if entry is expired - if (av_name->mExpires < LLFrameTimer::getTotalSeconds()) + // re-request name if entry is expired + if (av_name->mExpires < LLFrameTimer::getTotalSeconds()) + { + if (!isRequestPending(agent_id)) { - if (!isRequestPending(agent_id)) - { - LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get " - << "refresh agent " << agent_id - << LL_ENDL; - sAskQueue.insert(agent_id); - } + LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get " + << "refresh agent " << agent_id + << LL_ENDL; + sAskQueue.insert(agent_id); } - - return true; - } - } - else - { - // ...use legacy names cache - std::string full_name; - if (gCacheName->getFullName(agent_id, full_name)) - { - buildLegacyName(full_name, av_name); - return true; } + + return true; } } @@ -644,30 +615,14 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag if (sRunning) { // ...only do immediate lookups when cache is running - if (hasNameLookupURL()) - { - // ...use new cache - std::map::iterator it = sCache.find(agent_id); - if (it != sCache.end()) - { - const LLAvatarName& av_name = it->second; - - if (av_name.mExpires > LLFrameTimer::getTotalSeconds()) - { - // ...name already exists in cache, fire callback now - fireSignal(agent_id, slot, av_name); - return connection; - } - } - } - else + std::map::iterator it = sCache.find(agent_id); + if (it != sCache.end()) { - // ...use old name system - std::string full_name; - if (gCacheName->getFullName(agent_id, full_name)) + const LLAvatarName& av_name = it->second; + + if (av_name.mExpires > LLFrameTimer::getTotalSeconds()) { - LLAvatarName av_name; - buildLegacyName(full_name, &av_name); + // ...name already exists in cache, fire callback now fireSignal(agent_id, slot, av_name); return connection; } @@ -709,11 +664,6 @@ void LLAvatarNameCache::setUseDisplayNames(bool use) } } -void LLAvatarNameCache::flushCache() -{ - sCache.clear(); -} - void LLAvatarNameCache::erase(const LLUUID& agent_id) { sCache.erase(agent_id); diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index e172601432..2a8eb46187 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -37,33 +37,33 @@ class LLUUID; namespace LLAvatarNameCache { - typedef boost::signals2::signal use_display_name_signal_t; // Until the cache is set running, immediate lookups will fail and // async lookups will be queued. This allows us to block requests // until we know if the first region supports display names. - void initClass(bool running); + void initClass(bool running, bool usePeopleAPI); void cleanupClass(); + // Import/export the name cache to file. void importFile(std::istream& istr); void exportFile(std::ostream& ostr); - // On the viewer, usually a simulator capabilitity - // If empty, name cache will fall back to using legacy name - // lookup system + // On the viewer, usually a simulator capabilitity. + // If empty, name cache will fall back to using legacy name lookup system. void setNameLookupURL(const std::string& name_lookup_url); - // Do we have a valid lookup URL, hence are we trying to use the - // new display name lookup system? + // Do we have a valid lookup URL, i.e. are we trying to use the + // more recent display name lookup system? bool hasNameLookupURL(); + bool usePeopleAPI(); // Periodically makes a batch request for display names not already in - // cache. Call once per frame. + // cache. Called once per frame. void idle(); // If name is in cache, returns true and fills in provided LLAvatarName - // otherwise returns false + // otherwise returns false. bool get(const LLUUID& agent_id, LLAvatarName *av_name); // Callback types for get() below @@ -73,23 +73,19 @@ namespace LLAvatarNameCache typedef callback_signal_t::slot_type callback_slot_t; typedef boost::signals2::connection callback_connection_t; - // Fetches name information and calls callback. - // If name information is in cache, callback will be called immediately. + // Fetches name information and calls callbacks. + // If name information is in cache, callbacks will be called immediately. callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot); - // Allow display names to be explicitly disabled for testing. + // Set display name: flips the switch and triggers the callbacks. void setUseDisplayNames(bool use); - bool useDisplayNames(); - - void flushCache(); + void insert(const LLUUID& agent_id, const LLAvatarName& av_name); void erase(const LLUUID& agent_id); - /// Provide some fallback for agents that return errors + /// Provide some fallback for agents that return errors. void handleAgentError(const LLUUID& agent_id); - void insert(const LLUUID& agent_id, const LLAvatarName& av_name); - // Compute name expiration time from HTTP Cache-Control header, // or return default value, in seconds from epoch. F64 nameExpirationFromHeaders(LLSD headers); diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h index b108e37157..d238c3a247 100644 --- a/indra/llmessage/llcachename.h +++ b/indra/llmessage/llcachename.h @@ -40,7 +40,7 @@ typedef boost::signals2::signal LLCacheNameSignal; typedef LLCacheNameSignal::slot_type LLCacheNameCallback; -// Old callback with user data for compatability +// Old callback with user data for compatibility typedef void (*old_callback_t)(const LLUUID&, const std::string&, bool, void*); // Here's the theory: -- cgit v1.2.3 From a6f1690128b510977cfe86071f80f81967b9d0c7 Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 7 Dec 2012 18:58:52 -0800 Subject: CHUI-580, CHUI-406 : Fixed : Finished avatar name caching, also fixed the display of (waiting) when names don't come (mostly in legacy mode). --- indra/llmessage/llavatarnamecache.cpp | 39 ++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 12 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 15c4f2a207..9d6aa15ed1 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -100,11 +100,14 @@ namespace LLAvatarNameCache void requestNamesViaCapability(); - // Legacy name system callback + // Legacy name system callbacks void legacyNameCallback(const LLUUID& agent_id, const std::string& full_name, bool is_group); - + void legacyNameFetch(const LLUUID& agent_id, + const std::string& full_name, + bool is_group); + void requestNamesViaLegacy(); // Do a single callback to a given slot @@ -262,8 +265,7 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id) LL_WARNS("AvNameCache") << "LLAvatarNameCache get legacy for agent " << agent_id << LL_ENDL; gCacheName->get(agent_id, false, // legacy compatibility - boost::bind(&LLAvatarNameCache::legacyNameCallback, - _1, _2, _3)); + boost::bind(&LLAvatarNameCache::legacyNameFetch, _1, _2, _3)); } else { @@ -367,19 +369,32 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id, const std::string& full_name, bool is_group) { - LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::legacyNameCallback " - << "agent " << agent_id << " " + // Put the received data in the cache + legacyNameFetch(agent_id, full_name, is_group); + + // Retrieve the name and set it to never (or almost never...) expire: when we are using the legacy + // protocol, we do not get an expiration date for each name and there's no reason to ask the + // data again and again so we set the expiration time to the largest value admissible. + std::map::iterator av_record = sCache.find(agent_id); + LLAvatarName& av_name = av_record->second; + av_name.setExpires(MAX_UNREFRESHED_TIME); +} + +void LLAvatarNameCache::legacyNameFetch(const LLUUID& agent_id, + const std::string& full_name, + bool is_group) +{ + LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::legacyNameFetch " + << "agent " << agent_id << " " << "full name '" << full_name << "'" - << ( is_group ? " [group]" : "" ) - << LL_ENDL; + << ( is_group ? " [group]" : "" ) + << LL_ENDL; // Construct an av_name record from this name. LLAvatarName av_name; av_name.fromString(full_name); - av_name.dump(); - - // Add to cache, because if we don't we'll keep rerequesting the - // same record forever. + + // Add to cache: we're still using the new cache even if we're using the old (legacy) protocol. processName(agent_id, av_name); } -- cgit v1.2.3 From 9b556fb3fea0a97f5773d8fd435a428b0fafacbf Mon Sep 17 00:00:00 2001 From: Merov Linden Date: Fri, 14 Dec 2012 14:19:17 -0800 Subject: CHUI-599 : Use the account name in all places that are not UI related but use avatar names to index, search and other code only uses. --- indra/llmessage/llavatarnamecache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 9d6aa15ed1..9163262cc0 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -561,7 +561,7 @@ void LLAvatarNameCache::eraseUnrefreshed() { const LLUUID& agent_id = it->first; LL_DEBUGS("AvNameCache") << agent_id - << " user '" << av_name.getUserName() << "' " + << " user '" << av_name.getAccountName() << "' " << "expired " << now - av_name.mExpires << " secs ago" << LL_ENDL; sCache.erase(it++); -- cgit v1.2.3 From 54cdc322b8f2bd35b289cacf3493622e7cc51194 Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Tue, 5 Mar 2013 22:05:22 -0800 Subject: Fixing issues with not detecting when LLSD XML parsing fails. Changing most http error handlers to understand LLSD error responses. Fleshing out most http error handler message spam. --- indra/llmessage/llavatarnamecache.cpp | 6 ++++-- indra/llmessage/llcachename.cpp | 4 +++- indra/llmessage/llcurl.cpp | 4 +++- 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index a6e2c89ba4..f9e3ad26f7 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -443,8 +443,10 @@ void LLAvatarNameCache::cleanupClass() void LLAvatarNameCache::importFile(std::istream& istr) { LLSD data; - S32 parse_count = LLSDSerialize::fromXMLDocument(data, istr); - if (parse_count < 1) return; + if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(data, istr)) + { + return; + } // by convention LLSD storage is a map // we only store one entry in the map diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp index 8f4af1984c..d9eb65ff59 100644 --- a/indra/llmessage/llcachename.cpp +++ b/indra/llmessage/llcachename.cpp @@ -308,8 +308,10 @@ boost::signals2::connection LLCacheName::addObserver(const LLCacheNameCallback& bool LLCacheName::importFile(std::istream& istr) { LLSD data; - if(LLSDSerialize::fromXMLDocument(data, istr) < 1) + if(LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(data, istr)) + { return false; + } // We'll expire entries more than a week old U32 now = (U32)time(NULL); diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 8ffa8e4271..47041a2880 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -175,9 +175,11 @@ void LLCurl::Responder::completedRaw( { LLSD content; LLBufferStream istr(channels, buffer.get()); - if (!LLSDSerialize::fromXML(content, istr)) + const bool emit_errors = false; + if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(content, istr, emit_errors)) { llinfos << "Failed to deserialize LLSD. " << mURL << " [" << status << "]: " << reason << llendl; + content["reason"] = reason; } completed(status, reason, content); -- cgit v1.2.3 From 74055542902b590cd4d7868aa1c14bf4da7c6399 Mon Sep 17 00:00:00 2001 From: Don Kjer Date: Wed, 13 Mar 2013 08:49:26 +0000 Subject: Fixed potential memory leak in LLHTTPClient. Fixed potential hanging http requests in LLHTTPClient. Fixed munging of "Pragma" headers in LLHTTPClientAdapter --- indra/llmessage/llhttpclient.cpp | 15 ++++++++++++--- indra/llmessage/llhttpclientadapter.cpp | 7 +++++-- 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index 0c325a68aa..46b0311cce 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -222,7 +222,11 @@ static void request( { if (!LLHTTPClient::hasPump()) { - responder->completed(U32_MAX, "No pump", LLSD()); + if (responder) + { + responder->completed(U32_MAX, "No pump", LLSD()); + } + delete body_injector; return; } LLPumpIO::chain_t chain; @@ -230,8 +234,13 @@ static void request( LLURLRequest* req = new LLURLRequest(method, url); if(!req->isValid())//failed { - delete req ; - return ; + if (responder) + { + responder->completed(498, "Internal Error - curl failure"); + } + delete req; + delete body_injector; + return; } req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req); diff --git a/indra/llmessage/llhttpclientadapter.cpp b/indra/llmessage/llhttpclientadapter.cpp index f5d7a9abb6..0b59209af1 100644 --- a/indra/llmessage/llhttpclientadapter.cpp +++ b/indra/llmessage/llhttpclientadapter.cpp @@ -43,8 +43,11 @@ void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr respo void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers) { LLSD empty_pragma_header = headers; - // as above - empty_pragma_header["Pragma"] = " "; + if (!empty_pragma_header.has("Pragma")) + { + // as above + empty_pragma_header["Pragma"] = " "; + } LLHTTPClient::get(url, responder, empty_pragma_header); } -- cgit v1.2.3 From 45838b8b07a61af9b85ab9bc3013f1ac867e70d8 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 13 Mar 2013 11:19:21 -0400 Subject: fix for build failure --- indra/llmessage/llhttpclient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 indra/llmessage/llhttpclient.cpp (limited to 'indra/llmessage') diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp old mode 100644 new mode 100755 index 46b0311cce..3561459bb4 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -236,7 +236,7 @@ static void request( { if (responder) { - responder->completed(498, "Internal Error - curl failure"); + responder->completed(498, "Internal Error - curl failure", LLSD()); } delete req; delete body_injector; -- cgit v1.2.3 From 7ea7b236d88ec599c5bae561689b9d079256e551 Mon Sep 17 00:00:00 2001 From: Nyx Linden Date: Tue, 2 Apr 2013 18:32:57 -0400 Subject: BUILDFIX commit policy fixes --- indra/llmessage/tests/test_llsdmessage_peer.py | 346 ++++++++++++------------- 1 file changed, 173 insertions(+), 173 deletions(-) (limited to 'indra/llmessage') diff --git a/indra/llmessage/tests/test_llsdmessage_peer.py b/indra/llmessage/tests/test_llsdmessage_peer.py index b59c5a06cd..e45249b1cb 100644 --- a/indra/llmessage/tests/test_llsdmessage_peer.py +++ b/indra/llmessage/tests/test_llsdmessage_peer.py @@ -1,173 +1,173 @@ -#!/usr/bin/env python -"""\ -@file test_llsdmessage_peer.py -@author Nat Goodspeed -@date 2008-10-09 -@brief This script asynchronously runs the executable (with args) specified on - the command line, returning its result code. While that executable is - running, we provide dummy local services for use by C++ tests. - -$LicenseInfo:firstyear=2008&license=viewerlgpl$ -Second Life Viewer Source Code -Copyright (C) 2010, 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$ -""" - -import os -import sys -from threading import Thread -from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler - -mydir = os.path.dirname(__file__) # expected to be .../indra/llmessage/tests/ -sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python")) -from indra.util.fastest_elementtree import parse as xml_parse -from indra.base import llsd -from testrunner import freeport, run, debug, VERBOSE -import time - -_storage=None - -class TestHTTPRequestHandler(BaseHTTPRequestHandler): - """This subclass of BaseHTTPRequestHandler is to receive and echo - LLSD-flavored messages sent by the C++ LLHTTPClient. - """ - def read(self): - # The following logic is adapted from the library module - # SimpleXMLRPCServer.py. - # Get arguments by reading body of request. - # We read this in chunks to avoid straining - # socket.read(); around the 10 or 15Mb mark, some platforms - # begin to have problems (bug #792570). - try: - size_remaining = int(self.headers["content-length"]) - except (KeyError, ValueError): - return "" - max_chunk_size = 10*1024*1024 - L = [] - while size_remaining: - chunk_size = min(size_remaining, max_chunk_size) - chunk = self.rfile.read(chunk_size) - L.append(chunk) - size_remaining -= len(chunk) - return ''.join(L) - # end of swiped read() logic - - def read_xml(self): - # This approach reads the entire POST data into memory first - return llsd.parse(self.read()) -## # This approach attempts to stream in the LLSD XML from self.rfile, -## # assuming that the underlying XML parser reads its input file -## # incrementally. Unfortunately I haven't been able to make it work. -## tree = xml_parse(self.rfile) -## debug("Finished raw parse") -## debug("parsed XML tree %s", tree) -## debug("parsed root node %s", tree.getroot()) -## debug("root node tag %s", tree.getroot().tag) -## return llsd.to_python(tree.getroot()) - - def do_HEAD(self): - self.do_GET(withdata=False) - - def do_GET(self, withdata=True): - # Of course, don't attempt to read data. - data = dict(reply="success", body="avatar", random=17) - self.answer(data, withdata=withdata) - - def do_POST(self): - # Read the provided POST data. - self.answer(self.read_xml()) - - def do_PUT(self): - # Read the provided PUT data. - self.answer(self.read_xml()) - - def answer(self, data, withdata=True): - global _storage - debug("%s.answer(%s): self.path = %r", self.__class__.__name__, data, self.path) - if "fail" in self.path or "test/error" in self.path: # fail requested - status = data.get("status", 500) - # self.responses maps an int status to a (short, long) pair of - # strings. We want the longer string. That's why we pass a string - # pair to get(): the [1] will select the second string, whether it - # came from self.responses or from our default pair. - reason = data.get("reason", - self.responses.get(status, - ("fail requested", - "Your request specified failure status %s " - "without providing a reason" % status))[1]) - debug("fail requested: %s: %r", status, reason) - self.send_error(status, reason) - else: - if "web/echo" in self.path: - pass - elif "test/timeout" in self.path: - time.sleep(5.0) - return - elif "test/storage" in self.path: - if "GET" == self.command: - data = _storage - else: - _storage = data - data = "ok" - else: - data = data.copy() # we're going to modify - # Ensure there's a "reply" key in data, even if there wasn't before - data["reply"] = data.get("reply", llsd.LLSD("success")) - response = llsd.format_xml(data) - debug("success: %s", response) - self.send_response(200) - self.send_header("Content-type", "application/llsd+xml") - self.send_header("Content-Length", str(len(response))) - self.end_headers() - if withdata: - self.wfile.write(response) - - if not VERBOSE: - # When VERBOSE is set, skip both these overrides because they exist to - # suppress output. - - def log_request(self, code, size=None): - # For present purposes, we don't want the request splattered onto - # stderr, as it would upset devs watching the test run - pass - - def log_error(self, format, *args): - # Suppress error output as well - pass - -class Server(HTTPServer): - # This pernicious flag is on by default in HTTPServer. But proper - # operation of freeport() absolutely depends on it being off. - allow_reuse_address = False - -if __name__ == "__main__": - # Instantiate a Server(TestHTTPRequestHandler) on the first free port - # in the specified port range. Doing this inline is better than in a - # daemon thread: if it blows up here, we'll get a traceback. If it blew up - # in some other thread, the traceback would get eaten and we'd run the - # subject test program anyway. - httpd, port = freeport(xrange(8000, 8020), - lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler)) - # Pass the selected port number to the subject test program via the - # environment. We don't want to impose requirements on the test program's - # command-line parsing -- and anyway, for C++ integration tests, that's - # performed in TUT code rather than our own. - os.environ["PORT"] = str(port) - debug("$PORT = %s", port) - sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), *sys.argv[1:])) +#!/usr/bin/env python +"""\ +@file test_llsdmessage_peer.py +@author Nat Goodspeed +@date 2008-10-09 +@brief This script asynchronously runs the executable (with args) specified on + the command line, returning its result code. While that executable is + running, we provide dummy local services for use by C++ tests. + +$LicenseInfo:firstyear=2008&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2010, 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$ +""" + +import os +import sys +from threading import Thread +from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler + +mydir = os.path.dirname(__file__) # expected to be .../indra/llmessage/tests/ +sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python")) +from indra.util.fastest_elementtree import parse as xml_parse +from indra.base import llsd +from testrunner import freeport, run, debug, VERBOSE +import time + +_storage=None + +class TestHTTPRequestHandler(BaseHTTPRequestHandler): + """This subclass of BaseHTTPRequestHandler is to receive and echo + LLSD-flavored messages sent by the C++ LLHTTPClient. + """ + def read(self): + # The following logic is adapted from the library module + # SimpleXMLRPCServer.py. + # Get arguments by reading body of request. + # We read this in chunks to avoid straining + # socket.read(); around the 10 or 15Mb mark, some platforms + # begin to have problems (bug #792570). + try: + size_remaining = int(self.headers["content-length"]) + except (KeyError, ValueError): + return "" + max_chunk_size = 10*1024*1024 + L = [] + while size_remaining: + chunk_size = min(size_remaining, max_chunk_size) + chunk = self.rfile.read(chunk_size) + L.append(chunk) + size_remaining -= len(chunk) + return ''.join(L) + # end of swiped read() logic + + def read_xml(self): + # This approach reads the entire POST data into memory first + return llsd.parse(self.read()) +## # This approach attempts to stream in the LLSD XML from self.rfile, +## # assuming that the underlying XML parser reads its input file +## # incrementally. Unfortunately I haven't been able to make it work. +## tree = xml_parse(self.rfile) +## debug("Finished raw parse") +## debug("parsed XML tree %s", tree) +## debug("parsed root node %s", tree.getroot()) +## debug("root node tag %s", tree.getroot().tag) +## return llsd.to_python(tree.getroot()) + + def do_HEAD(self): + self.do_GET(withdata=False) + + def do_GET(self, withdata=True): + # Of course, don't attempt to read data. + data = dict(reply="success", body="avatar", random=17) + self.answer(data, withdata=withdata) + + def do_POST(self): + # Read the provided POST data. + self.answer(self.read_xml()) + + def do_PUT(self): + # Read the provided PUT data. + self.answer(self.read_xml()) + + def answer(self, data, withdata=True): + global _storage + debug("%s.answer(%s): self.path = %r", self.__class__.__name__, data, self.path) + if "fail" in self.path or "test/error" in self.path: # fail requested + status = data.get("status", 500) + # self.responses maps an int status to a (short, long) pair of + # strings. We want the longer string. That's why we pass a string + # pair to get(): the [1] will select the second string, whether it + # came from self.responses or from our default pair. + reason = data.get("reason", + self.responses.get(status, + ("fail requested", + "Your request specified failure status %s " + "without providing a reason" % status))[1]) + debug("fail requested: %s: %r", status, reason) + self.send_error(status, reason) + else: + if "web/echo" in self.path: + pass + elif "test/timeout" in self.path: + time.sleep(5.0) + return + elif "test/storage" in self.path: + if "GET" == self.command: + data = _storage + else: + _storage = data + data = "ok" + else: + data = data.copy() # we're going to modify + # Ensure there's a "reply" key in data, even if there wasn't before + data["reply"] = data.get("reply", llsd.LLSD("success")) + response = llsd.format_xml(data) + debug("success: %s", response) + self.send_response(200) + self.send_header("Content-type", "application/llsd+xml") + self.send_header("Content-Length", str(len(response))) + self.end_headers() + if withdata: + self.wfile.write(response) + + if not VERBOSE: + # When VERBOSE is set, skip both these overrides because they exist to + # suppress output. + + def log_request(self, code, size=None): + # For present purposes, we don't want the request splattered onto + # stderr, as it would upset devs watching the test run + pass + + def log_error(self, format, *args): + # Suppress error output as well + pass + +class Server(HTTPServer): + # This pernicious flag is on by default in HTTPServer. But proper + # operation of freeport() absolutely depends on it being off. + allow_reuse_address = False + +if __name__ == "__main__": + # Instantiate a Server(TestHTTPRequestHandler) on the first free port + # in the specified port range. Doing this inline is better than in a + # daemon thread: if it blows up here, we'll get a traceback. If it blew up + # in some other thread, the traceback would get eaten and we'd run the + # subject test program anyway. + httpd, port = freeport(xrange(8000, 8020), + lambda port: Server(('127.0.0.1', port), TestHTTPRequestHandler)) + # Pass the selected port number to the subject test program via the + # environment. We don't want to impose requirements on the test program's + # command-line parsing -- and anyway, for C++ integration tests, that's + # performed in TUT code rather than our own. + os.environ["PORT"] = str(port) + debug("$PORT = %s", port) + sys.exit(run(server=Thread(name="httpd", target=httpd.serve_forever), *sys.argv[1:])) -- cgit v1.2.3