Removed dead code, llsdmessage, llcapabilitylistener and the associated tests.
parent
aba8d5e488
commit
be1fa962df
|
|
@ -75,7 +75,6 @@ set(llmessage_SOURCE_FILES
|
|||
llpumpio.cpp
|
||||
llsdappservices.cpp
|
||||
llsdhttpserver.cpp
|
||||
llsdmessage.cpp
|
||||
llsdmessagebuilder.cpp
|
||||
llsdmessagereader.cpp
|
||||
llsdrpcclient.cpp
|
||||
|
|
@ -176,7 +175,6 @@ set(llmessage_HEADER_FILES
|
|||
llregionhandle.h
|
||||
llsdappservices.h
|
||||
llsdhttpserver.h
|
||||
llsdmessage.h
|
||||
llsdmessagebuilder.h
|
||||
llsdmessagereader.h
|
||||
llsdrpcclient.h
|
||||
|
|
@ -261,22 +259,6 @@ if (LL_TESTS)
|
|||
${GOOGLEMOCK_LIBRARIES}
|
||||
)
|
||||
|
||||
LL_ADD_INTEGRATION_TEST(
|
||||
llsdmessage
|
||||
"llsdmessage.cpp"
|
||||
"${test_libs}"
|
||||
${PYTHON_EXECUTABLE}
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llsdmessage_peer.py"
|
||||
)
|
||||
|
||||
LL_ADD_INTEGRATION_TEST(
|
||||
llhttpclient
|
||||
"llhttpclient.cpp"
|
||||
"${test_libs}"
|
||||
${PYTHON_EXECUTABLE}
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llsdmessage_peer.py"
|
||||
)
|
||||
|
||||
LL_ADD_INTEGRATION_TEST(llavatarnamecache "" "${test_libs}")
|
||||
LL_ADD_INTEGRATION_TEST(llhost "" "${test_libs}")
|
||||
LL_ADD_INTEGRATION_TEST(llpartdata "" "${test_libs}")
|
||||
|
|
|
|||
|
|
@ -1,168 +0,0 @@
|
|||
/**
|
||||
* @file llsdmessage.cpp
|
||||
* @author Nat Goodspeed
|
||||
* @date 2008-10-31
|
||||
* @brief Implementation for llsdmessage.
|
||||
*
|
||||
* $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$
|
||||
*/
|
||||
|
||||
#if LL_WINDOWS
|
||||
#pragma warning (disable : 4675) // "resolved by ADL" -- just as I want!
|
||||
#endif
|
||||
|
||||
// Precompiled header
|
||||
#include "linden_common.h"
|
||||
// associated header
|
||||
#include "llsdmessage.h"
|
||||
// STL headers
|
||||
// std headers
|
||||
// external library headers
|
||||
// other Linden headers
|
||||
#include "llevents.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llhttpclient.h"
|
||||
#include "llmessageconfig.h"
|
||||
#include "llhost.h"
|
||||
#include "message.h"
|
||||
#include "llsdutil.h"
|
||||
|
||||
// Declare a static LLSDMessage instance to ensure that we have a listener as
|
||||
// soon as someone tries to post on our canonical LLEventPump name.
|
||||
static LLSDMessage httpListener;
|
||||
|
||||
LLSDMessage::LLSDMessage():
|
||||
// Instantiating our own local LLEventPump with a string name the
|
||||
// constructor is NOT allowed to tweak is a way of ensuring Singleton
|
||||
// semantics: attempting to instantiate a second LLSDMessage object would
|
||||
// throw LLEventPump::DupPumpName.
|
||||
mEventPump("LLHTTPClient")
|
||||
{
|
||||
mEventPump.listen("self", boost::bind(&LLSDMessage::httpListener, this, _1));
|
||||
}
|
||||
|
||||
bool LLSDMessage::httpListener(const LLSD& request)
|
||||
{
|
||||
// Extract what we want from the request object. We do it all up front
|
||||
// partly to document what we expect.
|
||||
LLSD::String url(request["url"]);
|
||||
LLSD payload(request["payload"]);
|
||||
LLSD::String reply(request["reply"]);
|
||||
LLSD::String error(request["error"]);
|
||||
LLSD::Real timeout(request["timeout"]);
|
||||
// If the LLSD doesn't even have a "url" key, we doubt it was intended for
|
||||
// this listener.
|
||||
if (url.empty())
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "request event without 'url' key to '" << mEventPump.getName() << "'";
|
||||
throw ArgError(out.str());
|
||||
}
|
||||
// Establish default timeout. This test relies on LLSD::asReal() returning
|
||||
// exactly 0.0 for an undef value.
|
||||
if (! timeout)
|
||||
{
|
||||
timeout = HTTP_REQUEST_EXPIRY_SECS;
|
||||
}
|
||||
LLHTTPClient::post(url, payload,
|
||||
new LLSDMessage::EventResponder(LLEventPumps::instance(),
|
||||
request,
|
||||
url, "POST", reply, error),
|
||||
LLSD(), // headers
|
||||
(F32)timeout);
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLSDMessage::EventResponder::httpSuccess()
|
||||
{
|
||||
// If our caller passed an empty replyPump name, they're not
|
||||
// listening: this is a fire-and-forget message. Don't bother posting
|
||||
// to the pump whose name is "".
|
||||
if (! mReplyPump.empty())
|
||||
{
|
||||
LLSD response(getContent());
|
||||
mReqID.stamp(response);
|
||||
mPumps.obtain(mReplyPump).post(response);
|
||||
}
|
||||
else // default success handling
|
||||
{
|
||||
LL_INFOS("LLSDMessage::EventResponder")
|
||||
<< "'" << mMessage << "' to '" << mTarget << "' succeeded"
|
||||
<< LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
void LLSDMessage::EventResponder::httpFailure()
|
||||
{
|
||||
// If our caller passed an empty errorPump name, they're not
|
||||
// listening: "default error handling is acceptable." Only post to an
|
||||
// explicit pump name.
|
||||
if (! mErrorPump.empty())
|
||||
{
|
||||
LLSD info(mReqID.makeResponse());
|
||||
info["target"] = mTarget;
|
||||
info["message"] = mMessage;
|
||||
info["status"] = getStatus();
|
||||
info["reason"] = getReason();
|
||||
info["content"] = getContent();
|
||||
mPumps.obtain(mErrorPump).post(info);
|
||||
}
|
||||
else // default error handling
|
||||
{
|
||||
// convention seems to be to use LL_INFOS(), but that seems a bit casual?
|
||||
LL_WARNS("LLSDMessage::EventResponder")
|
||||
<< "'" << mMessage << "' to '" << mTarget
|
||||
<< "' failed " << dumpResponse() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
LLSDMessage::ResponderAdapter::ResponderAdapter(LLHTTPClient::ResponderPtr responder,
|
||||
const std::string& name):
|
||||
mResponder(responder),
|
||||
mReplyPump(name + ".reply", true), // tweak name for uniqueness
|
||||
mErrorPump(name + ".error", true)
|
||||
{
|
||||
mReplyPump.listen("self", boost::bind(&ResponderAdapter::listener, this, _1, true));
|
||||
mErrorPump.listen("self", boost::bind(&ResponderAdapter::listener, this, _1, false));
|
||||
}
|
||||
|
||||
bool LLSDMessage::ResponderAdapter::listener(const LLSD& payload, bool success)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
mResponder->successResult(payload);
|
||||
}
|
||||
else
|
||||
{
|
||||
mResponder->failureResult(payload["status"].asInteger(), payload["reason"], payload["content"]);
|
||||
}
|
||||
|
||||
/*---------------- MUST BE LAST STATEMENT BEFORE RETURN ----------------*/
|
||||
delete this;
|
||||
// Destruction of mResponder will usually implicitly free its referent as well
|
||||
/*------------------------- NOTHING AFTER THIS -------------------------*/
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLSDMessage::link()
|
||||
{
|
||||
}
|
||||
|
|
@ -1,168 +0,0 @@
|
|||
/**
|
||||
* @file llsdmessage.h
|
||||
* @author Nat Goodspeed
|
||||
* @date 2008-10-30
|
||||
* @brief API intended to unify sending capability, UDP and TCP messages:
|
||||
* https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes
|
||||
*
|
||||
* $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$
|
||||
*/
|
||||
|
||||
#if ! defined(LL_LLSDMESSAGE_H)
|
||||
#define LL_LLSDMESSAGE_H
|
||||
|
||||
#include "llerror.h" // LOG_CLASS()
|
||||
#include "llevents.h" // LLEventPumps
|
||||
#include "llhttpclient.h"
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
class LLSD;
|
||||
|
||||
/**
|
||||
* Class managing the messaging API described in
|
||||
* https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes
|
||||
*/
|
||||
class LLSDMessage
|
||||
{
|
||||
LOG_CLASS(LLSDMessage);
|
||||
|
||||
public:
|
||||
LLSDMessage();
|
||||
|
||||
/// Exception if you specify arguments badly
|
||||
struct ArgError: public std::runtime_error
|
||||
{
|
||||
ArgError(const std::string& what):
|
||||
std::runtime_error(std::string("ArgError: ") + what) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* The response idiom used by LLSDMessage -- LLEventPump names on which to
|
||||
* post reply or error -- is designed for the case in which your
|
||||
* reply/error handlers are methods on the same class as the method
|
||||
* sending the message. Any state available to the sending method that
|
||||
* must be visible to the reply/error methods can conveniently be stored
|
||||
* on that class itself, if it's not already.
|
||||
*
|
||||
* The LLHTTPClient::Responder idiom requires a separate instance of a
|
||||
* separate class so that it can dispatch to the code of interest by
|
||||
* calling canonical virtual methods. Interesting state must be copied
|
||||
* into that new object.
|
||||
*
|
||||
* With some trepidation, because existing response code is packaged in
|
||||
* LLHTTPClient::Responder subclasses, we provide this adapter class
|
||||
* <i>for transitional purposes only.</i> Instantiate a new heap
|
||||
* ResponderAdapter with your new LLHTTPClient::ResponderPtr. Pass
|
||||
* ResponderAdapter::getReplyName() and/or getErrorName() in your
|
||||
* LLSDMessage (or LLViewerRegion::getCapAPI()) request event. The
|
||||
* ResponderAdapter will call the appropriate Responder method, then
|
||||
* @c delete itself.
|
||||
*/
|
||||
class ResponderAdapter
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Bind the new LLHTTPClient::Responder subclass instance.
|
||||
*
|
||||
* Passing the constructor a name other than the default is only
|
||||
* interesting if you suspect some usage will lead to an exception or
|
||||
* log message.
|
||||
*/
|
||||
ResponderAdapter(LLHTTPClient::ResponderPtr responder,
|
||||
const std::string& name="ResponderAdapter");
|
||||
|
||||
/// EventPump name on which LLSDMessage should post reply event
|
||||
std::string getReplyName() const { return mReplyPump.getName(); }
|
||||
/// EventPump name on which LLSDMessage should post error event
|
||||
std::string getErrorName() const { return mErrorPump.getName(); }
|
||||
|
||||
private:
|
||||
// We have two different LLEventStreams, though we route them both to
|
||||
// the same listener, so that we can bind an extra flag identifying
|
||||
// which case (reply or error) reached that listener.
|
||||
bool listener(const LLSD&, bool success);
|
||||
|
||||
LLHTTPClient::ResponderPtr mResponder;
|
||||
LLEventStream mReplyPump, mErrorPump;
|
||||
};
|
||||
|
||||
/**
|
||||
* Force our implementation file to be linked with caller. The .cpp file
|
||||
* contains a static instance of this class, which must be linked into the
|
||||
* executable to support the canonical listener. But since the primary
|
||||
* interface to that static instance is via a named LLEventPump rather
|
||||
* than by direct reference, the linker doesn't necessarily perceive the
|
||||
* necessity to bring in the translation unit. Referencing this dummy
|
||||
* method forces the issue.
|
||||
*/
|
||||
static void link();
|
||||
|
||||
private:
|
||||
friend class LLCapabilityListener;
|
||||
/// Responder used for internal purposes by LLSDMessage and
|
||||
/// LLCapabilityListener. Others should use higher-level APIs.
|
||||
class EventResponder: public LLHTTPClient::Responder
|
||||
{
|
||||
LOG_CLASS(EventResponder);
|
||||
public:
|
||||
/**
|
||||
* LLHTTPClient::Responder that dispatches via named LLEventPump instances.
|
||||
* We bind LLEventPumps, even though it's an LLSingleton, for testability.
|
||||
* We bind the string names of the desired LLEventPump instances rather
|
||||
* than actually obtain()ing them so we only obtain() the one we're going
|
||||
* to use. If the caller doesn't bother to listen() on it, the other pump
|
||||
* may never materialize at all.
|
||||
* @a target and @a message are only to clarify error processing.
|
||||
* For a capability message, @a target should be the region description,
|
||||
* @a message should be the capability name.
|
||||
* For a service with a visible URL, pass the URL as @a target and the HTTP verb
|
||||
* (e.g. "POST") as @a message.
|
||||
*/
|
||||
EventResponder(LLEventPumps& pumps,
|
||||
const LLSD& request,
|
||||
const std::string& target, const std::string& message,
|
||||
const std::string& replyPump, const std::string& errorPump):
|
||||
mPumps(pumps),
|
||||
mReqID(request),
|
||||
mTarget(target),
|
||||
mMessage(message),
|
||||
mReplyPump(replyPump),
|
||||
mErrorPump(errorPump)
|
||||
{}
|
||||
|
||||
protected:
|
||||
virtual void httpSuccess();
|
||||
virtual void httpFailure();
|
||||
|
||||
private:
|
||||
LLEventPumps& mPumps;
|
||||
LLReqID mReqID;
|
||||
const std::string mTarget, mMessage, mReplyPump, mErrorPump;
|
||||
};
|
||||
|
||||
private:
|
||||
bool httpListener(const LLSD&);
|
||||
LLEventStream mEventPump;
|
||||
};
|
||||
|
||||
#endif /* ! defined(LL_LLSDMESSAGE_H) */
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
/**
|
||||
* @file llsdmessage_test.cpp
|
||||
* @author Nat Goodspeed
|
||||
* @date 2008-12-22
|
||||
* @brief Test of llsdmessage.h
|
||||
*
|
||||
* $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$
|
||||
*/
|
||||
|
||||
#if LL_WINDOWS
|
||||
#pragma warning (disable : 4675) // "resolved by ADL" -- just as I want!
|
||||
#endif
|
||||
|
||||
// Precompiled header
|
||||
#include "linden_common.h"
|
||||
// associated header
|
||||
#include "llsdmessage.h"
|
||||
// STL headers
|
||||
#include <iostream>
|
||||
// std headers
|
||||
#include <stdexcept>
|
||||
#include <typeinfo>
|
||||
// external library headers
|
||||
// other Linden headers
|
||||
#include "../test/lltut.h"
|
||||
#include "../test/catch_and_store_what_in.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llevents.h"
|
||||
#include "stringize.h"
|
||||
#include "llhost.h"
|
||||
#include "tests/networkio.h"
|
||||
#include "tests/commtest.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* TUT
|
||||
*****************************************************************************/
|
||||
namespace tut
|
||||
{
|
||||
struct llsdmessage_data: public commtest_data
|
||||
{
|
||||
LLEventPump& httpPump;
|
||||
|
||||
llsdmessage_data():
|
||||
httpPump(pumps.obtain("LLHTTPClient"))
|
||||
{
|
||||
LLCurl::initClass();
|
||||
LLSDMessage::link();
|
||||
}
|
||||
};
|
||||
typedef test_group<llsdmessage_data> llsdmessage_group;
|
||||
typedef llsdmessage_group::object llsdmessage_object;
|
||||
llsdmessage_group llsdmgr("llsdmessage");
|
||||
|
||||
template<> template<>
|
||||
void llsdmessage_object::test<1>()
|
||||
{
|
||||
std::string threw;
|
||||
// This should fail...
|
||||
try
|
||||
{
|
||||
LLSDMessage localListener;
|
||||
}
|
||||
CATCH_AND_STORE_WHAT_IN(threw, LLEventPump::DupPumpName)
|
||||
ensure("second LLSDMessage should throw", ! threw.empty());
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void llsdmessage_object::test<2>()
|
||||
{
|
||||
LLSD request, body;
|
||||
body["data"] = "yes";
|
||||
request["payload"] = body;
|
||||
request["reply"] = replyPump.getName();
|
||||
request["error"] = errorPump.getName();
|
||||
bool threw = false;
|
||||
try
|
||||
{
|
||||
httpPump.post(request);
|
||||
}
|
||||
catch (const LLSDMessage::ArgError&)
|
||||
{
|
||||
threw = true;
|
||||
}
|
||||
ensure("missing URL", threw);
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void llsdmessage_object::test<3>()
|
||||
{
|
||||
LLSD request, body;
|
||||
body["data"] = "yes";
|
||||
request["url"] = server + "got-message";
|
||||
request["payload"] = body;
|
||||
request["reply"] = replyPump.getName();
|
||||
request["error"] = errorPump.getName();
|
||||
httpPump.post(request);
|
||||
ensure("got response", netio.pump());
|
||||
ensure("success response", success);
|
||||
ensure_equals(result["reply"].asString(), "success");
|
||||
|
||||
body["status"] = 499;
|
||||
body["reason"] = "custom error message";
|
||||
request["url"] = server + "fail";
|
||||
request["payload"] = body;
|
||||
httpPump.post(request);
|
||||
ensure("got response", netio.pump());
|
||||
ensure("failure response", ! success);
|
||||
ensure_equals(result["status"].asInteger(), body["status"].asInteger());
|
||||
ensure_equals(result["reason"].asString(), body["reason"].asString());
|
||||
}
|
||||
} // namespace tut
|
||||
|
|
@ -142,7 +142,6 @@ set(viewer_SOURCE_FILES
|
|||
llbuycurrencyhtml.cpp
|
||||
llcallbacklist.cpp
|
||||
llcallingcard.cpp
|
||||
llcapabilitylistener.cpp
|
||||
llcaphttpsender.cpp
|
||||
llchannelmanager.cpp
|
||||
llchatbar.cpp
|
||||
|
|
@ -742,7 +741,6 @@ set(viewer_HEADER_FILES
|
|||
llbuycurrencyhtml.h
|
||||
llcallbacklist.h
|
||||
llcallingcard.h
|
||||
llcapabilitylistener.h
|
||||
llcapabilityprovider.h
|
||||
llcaphttpsender.h
|
||||
llchannelmanager.h
|
||||
|
|
@ -2298,7 +2296,6 @@ if (LL_TESTS)
|
|||
LL_ADD_PROJECT_UNIT_TESTS(${VIEWER_BINARY_NAME} "${viewer_TEST_SOURCE_FILES}")
|
||||
|
||||
#set(TEST_DEBUG on)
|
||||
set(test_sources llcapabilitylistener.cpp)
|
||||
##################################################
|
||||
# DISABLING PRECOMPILED HEADERS USAGE FOR TESTS
|
||||
##################################################
|
||||
|
|
@ -2314,13 +2311,6 @@ if (LL_TESTS)
|
|||
${GOOGLEMOCK_LIBRARIES}
|
||||
)
|
||||
|
||||
LL_ADD_INTEGRATION_TEST(llcapabilitylistener
|
||||
"${test_sources}"
|
||||
"${test_libs}"
|
||||
${PYTHON_EXECUTABLE}
|
||||
"${CMAKE_SOURCE_DIR}/llmessage/tests/test_llsdmessage_peer.py"
|
||||
)
|
||||
|
||||
if (LINUX)
|
||||
# llcommon uses `clock_gettime' which is provided by librt on linux.
|
||||
set(LIBRT_LIBRARY
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@
|
|||
#include "llappearancemgr.h"
|
||||
#include "llanimationstates.h"
|
||||
#include "llcallingcard.h"
|
||||
#include "llcapabilitylistener.h"
|
||||
#include "llchannelmanager.h"
|
||||
#include "llchicletbar.h"
|
||||
#include "llconsole.h"
|
||||
|
|
@ -62,7 +61,6 @@
|
|||
#include "llpaneltopinfobar.h"
|
||||
#include "llparcel.h"
|
||||
#include "llrendersphere.h"
|
||||
#include "llsdmessage.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llsky.h"
|
||||
#include "llslurl.h"
|
||||
|
|
@ -2388,35 +2386,6 @@ void LLAgent::setStartPositionSuccess(const LLSD &result)
|
|||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
struct HomeLocationMapper: public LLCapabilityListener::CapabilityMapper
|
||||
{
|
||||
// No reply message expected
|
||||
HomeLocationMapper(): LLCapabilityListener::CapabilityMapper("HomeLocation") {}
|
||||
virtual void buildMessage(LLMessageSystem* msg,
|
||||
const LLUUID& agentID,
|
||||
const LLUUID& sessionID,
|
||||
const std::string& capabilityName,
|
||||
const LLSD& payload) const
|
||||
{
|
||||
msg->newMessageFast(_PREHASH_SetStartLocationRequest);
|
||||
msg->nextBlockFast( _PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, agentID);
|
||||
msg->addUUIDFast(_PREHASH_SessionID, sessionID);
|
||||
msg->nextBlockFast( _PREHASH_StartLocationData);
|
||||
// corrected by sim
|
||||
msg->addStringFast(_PREHASH_SimName, "");
|
||||
msg->addU32Fast(_PREHASH_LocationID, payload["HomeLocation"]["LocationId"].asInteger());
|
||||
msg->addVector3Fast(_PREHASH_LocationPos,
|
||||
ll_vector3_from_sdmap(payload["HomeLocation"]["LocationPos"]));
|
||||
msg->addVector3Fast(_PREHASH_LocationLookAt,
|
||||
ll_vector3_from_sdmap(payload["HomeLocation"]["LocationLookAt"]));
|
||||
}
|
||||
};
|
||||
// Need an instance of this class so it will self-register
|
||||
static HomeLocationMapper homeLocationMapper;
|
||||
#endif
|
||||
|
||||
void LLAgent::requestStopMotion( LLMotion* motion )
|
||||
{
|
||||
// Notify all avatars that a motion has stopped.
|
||||
|
|
|
|||
|
|
@ -1,202 +0,0 @@
|
|||
/**
|
||||
* @file llcapabilitylistener.cpp
|
||||
* @author Nat Goodspeed
|
||||
* @date 2009-01-07
|
||||
* @brief Implementation for llcapabilitylistener.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&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$
|
||||
*/
|
||||
|
||||
// Precompiled header
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
// associated header
|
||||
#include "llcapabilitylistener.h"
|
||||
// STL headers
|
||||
#include <map>
|
||||
// std headers
|
||||
// external library headers
|
||||
#include <boost/bind.hpp>
|
||||
// other Linden headers
|
||||
#include "stringize.h"
|
||||
#include "llcapabilityprovider.h"
|
||||
#include "message.h"
|
||||
|
||||
class LLCapabilityListener::CapabilityMappers: public LLSingleton<LLCapabilityListener::CapabilityMappers>
|
||||
{
|
||||
public:
|
||||
void registerMapper(const LLCapabilityListener::CapabilityMapper*);
|
||||
void unregisterMapper(const LLCapabilityListener::CapabilityMapper*);
|
||||
const LLCapabilityListener::CapabilityMapper* find(const std::string& cap) const;
|
||||
|
||||
struct DupCapMapper: public std::runtime_error
|
||||
{
|
||||
DupCapMapper(const std::string& what):
|
||||
std::runtime_error(std::string("DupCapMapper: ") + what)
|
||||
{}
|
||||
};
|
||||
|
||||
private:
|
||||
friend class LLSingleton<LLCapabilityListener::CapabilityMappers>;
|
||||
CapabilityMappers();
|
||||
|
||||
typedef std::map<std::string, const LLCapabilityListener::CapabilityMapper*> CapabilityMap;
|
||||
CapabilityMap mMap;
|
||||
};
|
||||
|
||||
LLCapabilityListener::LLCapabilityListener(const std::string& name,
|
||||
LLMessageSystem* messageSystem,
|
||||
const LLCapabilityProvider& provider,
|
||||
const LLUUID& agentID,
|
||||
const LLUUID& sessionID):
|
||||
mEventPump(name),
|
||||
mMessageSystem(messageSystem),
|
||||
mProvider(provider),
|
||||
mAgentID(agentID),
|
||||
mSessionID(sessionID)
|
||||
{
|
||||
mEventPump.listen("self", boost::bind(&LLCapabilityListener::capListener, this, _1));
|
||||
}
|
||||
|
||||
bool LLCapabilityListener::capListener(const LLSD& request)
|
||||
{
|
||||
// Extract what we want from the request object. We do it all up front
|
||||
// partly to document what we expect.
|
||||
LLSD::String cap(request["message"]);
|
||||
LLSD payload(request["payload"]);
|
||||
LLSD::String reply(request["reply"]);
|
||||
LLSD::String error(request["error"]);
|
||||
LLSD::Real timeout(request["timeout"]);
|
||||
// If the LLSD doesn't even have a "message" key, we doubt it was intended
|
||||
// for this listener.
|
||||
if (cap.empty())
|
||||
{
|
||||
LL_ERRS("capListener") << "capability request event without 'message' key to '"
|
||||
<< getCapAPI().getName()
|
||||
<< "' on region\n" << mProvider.getDescription()
|
||||
<< LL_ENDL;
|
||||
return false; // in case fatal-error function isn't
|
||||
}
|
||||
// Establish default timeout. This test relies on LLSD::asReal() returning
|
||||
// exactly 0.0 for an undef value.
|
||||
if (! timeout)
|
||||
{
|
||||
timeout = HTTP_REQUEST_EXPIRY_SECS;
|
||||
}
|
||||
// Look up the url for the requested capability name.
|
||||
std::string url = mProvider.getCapability(cap);
|
||||
if (! url.empty())
|
||||
{
|
||||
// This capability is supported by the region to which we're talking.
|
||||
LLHTTPClient::post(url, payload,
|
||||
new LLSDMessage::EventResponder(LLEventPumps::instance(),
|
||||
request,
|
||||
mProvider.getDescription(),
|
||||
cap, reply, error),
|
||||
LLSD(), // headers
|
||||
timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Capability not supported -- do we have a registered mapper?
|
||||
const CapabilityMapper* mapper = CapabilityMappers::instance().find(cap);
|
||||
if (! mapper) // capability neither supported nor mapped
|
||||
{
|
||||
LL_ERRS("capListener") << "unsupported capability '" << cap << "' request to '"
|
||||
<< getCapAPI().getName() << "' on region\n"
|
||||
<< mProvider.getDescription()
|
||||
<< LL_ENDL;
|
||||
}
|
||||
else if (! mapper->getReplyName().empty()) // mapper expects reply support
|
||||
{
|
||||
LL_ERRS("capListener") << "Mapper for capability '" << cap
|
||||
<< "' requires unimplemented support for reply message '"
|
||||
<< mapper->getReplyName()
|
||||
<< "' on '" << getCapAPI().getName() << "' on region\n"
|
||||
<< mProvider.getDescription()
|
||||
<< LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS("capListener") << "fallback invoked for capability '" << cap
|
||||
<< "' request to '" << getCapAPI().getName()
|
||||
<< "' on region\n" << mProvider.getDescription()
|
||||
<< LL_ENDL;
|
||||
mapper->buildMessage(mMessageSystem, mAgentID, mSessionID, cap, payload);
|
||||
mMessageSystem->sendReliable(mProvider.getHost());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
LLCapabilityListener::CapabilityMapper::CapabilityMapper(const std::string& cap, const std::string& reply):
|
||||
mCapName(cap),
|
||||
mReplyName(reply)
|
||||
{
|
||||
LLCapabilityListener::CapabilityMappers::instance().registerMapper(this);
|
||||
}
|
||||
|
||||
LLCapabilityListener::CapabilityMapper::~CapabilityMapper()
|
||||
{
|
||||
LLCapabilityListener::CapabilityMappers::instance().unregisterMapper(this);
|
||||
}
|
||||
|
||||
LLSD LLCapabilityListener::CapabilityMapper::readResponse(LLMessageSystem* messageSystem) const
|
||||
{
|
||||
return LLSD();
|
||||
}
|
||||
|
||||
LLCapabilityListener::CapabilityMappers::CapabilityMappers() {}
|
||||
|
||||
void LLCapabilityListener::CapabilityMappers::registerMapper(const LLCapabilityListener::CapabilityMapper* mapper)
|
||||
{
|
||||
// Try to insert a new map entry by which we can look up the passed mapper
|
||||
// instance.
|
||||
std::pair<CapabilityMap::iterator, bool> inserted =
|
||||
mMap.insert(CapabilityMap::value_type(mapper->getCapName(), mapper));
|
||||
// If we already have a mapper for that name, insert() merely located the
|
||||
// existing iterator and returned false. It is a coding error to try to
|
||||
// register more than one mapper for the same capability name.
|
||||
if (! inserted.second)
|
||||
{
|
||||
throw DupCapMapper(std::string("Duplicate capability name ") + mapper->getCapName());
|
||||
}
|
||||
}
|
||||
|
||||
void LLCapabilityListener::CapabilityMappers::unregisterMapper(const LLCapabilityListener::CapabilityMapper* mapper)
|
||||
{
|
||||
CapabilityMap::iterator found = mMap.find(mapper->getCapName());
|
||||
if (found != mMap.end())
|
||||
{
|
||||
mMap.erase(found);
|
||||
}
|
||||
}
|
||||
|
||||
const LLCapabilityListener::CapabilityMapper*
|
||||
LLCapabilityListener::CapabilityMappers::find(const std::string& cap) const
|
||||
{
|
||||
CapabilityMap::const_iterator found = mMap.find(cap);
|
||||
if (found != mMap.end())
|
||||
{
|
||||
return found->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
/**
|
||||
* @file llcapabilitylistener.h
|
||||
* @author Nat Goodspeed
|
||||
* @date 2009-01-07
|
||||
* @brief Provide an event-based API for capability requests
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&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$
|
||||
*/
|
||||
|
||||
#if ! defined(LL_LLCAPABILITYLISTENER_H)
|
||||
#define LL_LLCAPABILITYLISTENER_H
|
||||
|
||||
#include "llevents.h" // LLEventPump
|
||||
#include "llsdmessage.h" // LLSDMessage::ArgError
|
||||
#include "llerror.h" // LOG_CLASS()
|
||||
|
||||
class LLCapabilityProvider;
|
||||
class LLMessageSystem;
|
||||
class LLSD;
|
||||
|
||||
class LLCapabilityListener
|
||||
{
|
||||
LOG_CLASS(LLCapabilityListener);
|
||||
public:
|
||||
LLCapabilityListener(const std::string& name, LLMessageSystem* messageSystem,
|
||||
const LLCapabilityProvider& provider,
|
||||
const LLUUID& agentID, const LLUUID& sessionID);
|
||||
|
||||
/// Capability-request exception
|
||||
typedef LLSDMessage::ArgError ArgError;
|
||||
/// Get LLEventPump on which we listen for capability requests
|
||||
/// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities)
|
||||
LLEventPump& getCapAPI() { return mEventPump; }
|
||||
|
||||
/**
|
||||
* Base class for mapping an as-yet-undeployed capability name to a (pair
|
||||
* of) LLMessageSystem message(s). To map a capability name to such
|
||||
* messages, derive a subclass of CapabilityMapper and declare a static
|
||||
* instance in a translation unit known to be loaded. The mapping is not
|
||||
* region-specific. If an LLViewerRegion's capListener() receives a
|
||||
* request for a supported capability, it will use the capability's URL.
|
||||
* If not, it will look for an applicable CapabilityMapper subclass
|
||||
* instance.
|
||||
*/
|
||||
class CapabilityMapper
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Base-class constructor. Typically your subclass constructor will
|
||||
* pass these parameters as literals.
|
||||
* @param cap the capability name handled by this (subclass) instance
|
||||
* @param reply the name of the response LLMessageSystem message. Omit
|
||||
* if the LLMessageSystem message you intend to send doesn't prompt a
|
||||
* reply message, or if you already handle that message in some other
|
||||
* way.
|
||||
*/
|
||||
CapabilityMapper(const std::string& cap, const std::string& reply = "");
|
||||
virtual ~CapabilityMapper();
|
||||
/// query the capability name
|
||||
std::string getCapName() const { return mCapName; }
|
||||
/// query the reply message name
|
||||
std::string getReplyName() const { return mReplyName; }
|
||||
/**
|
||||
* Override this method to build the LLMessageSystem message we should
|
||||
* send instead of the requested capability message. DO NOT send that
|
||||
* message: that will be handled by the caller.
|
||||
*/
|
||||
virtual void buildMessage(LLMessageSystem* messageSystem,
|
||||
const LLUUID& agentID,
|
||||
const LLUUID& sessionID,
|
||||
const std::string& capabilityName,
|
||||
const LLSD& payload) const = 0;
|
||||
/**
|
||||
* Override this method if you pass a non-empty @a reply
|
||||
* LLMessageSystem message name to the constructor: that is, if you
|
||||
* expect to receive an LLMessageSystem message in response to the
|
||||
* message you constructed in buildMessage(). If you don't pass a @a
|
||||
* reply message name, you need not override this method as it won't
|
||||
* be called.
|
||||
*
|
||||
* Using LLMessageSystem message-reading operations, your
|
||||
* readResponse() override should construct and return an LLSD object
|
||||
* of the form you expect to receive from the real implementation of
|
||||
* the capability you intend to invoke, when it finally goes live.
|
||||
*/
|
||||
virtual LLSD readResponse(LLMessageSystem* messageSystem) const;
|
||||
|
||||
private:
|
||||
const std::string mCapName;
|
||||
const std::string mReplyName;
|
||||
};
|
||||
|
||||
private:
|
||||
/// Bind the LLCapabilityProvider passed to our ctor
|
||||
const LLCapabilityProvider& mProvider;
|
||||
|
||||
/// Post an event to this LLEventPump to invoke a capability message on
|
||||
/// the bound LLCapabilityProvider's server
|
||||
/// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities)
|
||||
LLEventStream mEventPump;
|
||||
|
||||
LLMessageSystem* mMessageSystem;
|
||||
LLUUID mAgentID, mSessionID;
|
||||
|
||||
/// listener to process capability requests
|
||||
bool capListener(const LLSD&);
|
||||
|
||||
/// helper class for capListener()
|
||||
class CapabilityMappers;
|
||||
};
|
||||
|
||||
#endif /* ! defined(LL_LLCAPABILITYLISTENER_H) */
|
||||
|
|
@ -1750,27 +1750,20 @@ void copy_inventory_from_notecard(const LLUUID& destination_id,
|
|||
return;
|
||||
}
|
||||
|
||||
// check capability to prevent a crash while LL_ERRS in LLCapabilityListener::capListener. See EXT-8459.
|
||||
std::string url = viewer_region->getCapability("CopyInventoryFromNotecard");
|
||||
if (url.empty())
|
||||
{
|
||||
LL_WARNS(LOG_NOTECARD) << "There is no 'CopyInventoryFromNotecard' capability"
|
||||
<< " for region: " << viewer_region->getName()
|
||||
<< LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LLSD request, body;
|
||||
LLSD body;
|
||||
body["notecard-id"] = notecard_inv_id;
|
||||
body["object-id"] = object_id;
|
||||
body["item-id"] = src->getUUID();
|
||||
body["folder-id"] = destination_id;
|
||||
body["callback-id"] = (LLSD::Integer)callback_id;
|
||||
|
||||
request["message"] = "CopyInventoryFromNotecard";
|
||||
request["payload"] = body;
|
||||
|
||||
viewer_region->getCapAPI().post(request);
|
||||
/// *TODO: RIDER: This posts the request under the agents policy.
|
||||
/// When I convert the inventory over this call should be moved under that
|
||||
/// policy as well.
|
||||
if (!gAgent.requestPostCapability("CopyInventoryFromNotecard", body))
|
||||
{
|
||||
LL_WARNS() << "SIM does not have the capability to copy from notecard." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
void create_new_item(const std::string& name,
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@
|
|||
#include "llavatarrenderinfoaccountant.h"
|
||||
#include "llcallingcard.h"
|
||||
#include "llcaphttpsender.h"
|
||||
#include "llcapabilitylistener.h"
|
||||
#include "llcommandhandler.h"
|
||||
#include "lldir.h"
|
||||
#include "lleventpoll.h"
|
||||
|
|
@ -151,29 +150,18 @@ LLRegionHandler gRegionHandler;
|
|||
class LLViewerRegionImpl
|
||||
{
|
||||
public:
|
||||
LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host)
|
||||
: mHost(host),
|
||||
mCompositionp(NULL),
|
||||
mEventPoll(NULL),
|
||||
mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS),
|
||||
mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),
|
||||
mSeedCapAttempts(0),
|
||||
mHttpResponderID(0),
|
||||
mLastCameraUpdate(0),
|
||||
mLastCameraOrigin(),
|
||||
mVOCachePartition(NULL),
|
||||
mLandp(NULL),
|
||||
// I'd prefer to set the LLCapabilityListener name to match the region
|
||||
// name -- it's disappointing that's not available at construction time.
|
||||
// We could instead store an LLCapabilityListener*, making
|
||||
// setRegionNameAndZone() replace the instance. Would that pose
|
||||
// consistency problems? Can we even request a capability before calling
|
||||
// setRegionNameAndZone()?
|
||||
// For testability -- the new Michael Feathers paradigm --
|
||||
// LLCapabilityListener binds all the globals it expects to need at
|
||||
// construction time.
|
||||
mCapabilityListener(host.getString(), gMessageSystem, *region,
|
||||
gAgent.getID(), gAgent.getSessionID())
|
||||
LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host):
|
||||
mHost(host),
|
||||
mCompositionp(NULL),
|
||||
mEventPoll(NULL),
|
||||
mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS),
|
||||
mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),
|
||||
mSeedCapAttempts(0),
|
||||
mHttpResponderID(0),
|
||||
mLastCameraUpdate(0),
|
||||
mLastCameraOrigin(),
|
||||
mVOCachePartition(NULL),
|
||||
mLandp(NULL)
|
||||
{}
|
||||
|
||||
void buildCapabilityNames(LLSD& capabilityNames);
|
||||
|
|
@ -225,11 +213,6 @@ public:
|
|||
|
||||
S32 mHttpResponderID;
|
||||
|
||||
/// Post an event to this LLCapabilityListener to invoke a capability message on
|
||||
/// this LLViewerRegion's server
|
||||
/// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities)
|
||||
LLCapabilityListener mCapabilityListener;
|
||||
|
||||
//spatial partitions for objects in this region
|
||||
std::vector<LLViewerOctreePartition*> mObjectPartition;
|
||||
|
||||
|
|
@ -638,11 +621,6 @@ LLViewerRegion::~LLViewerRegion()
|
|||
mImpl = NULL;
|
||||
}
|
||||
|
||||
LLEventPump& LLViewerRegion::getCapAPI() const
|
||||
{
|
||||
return mImpl->mCapabilityListener.getCapAPI();
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
const LLHost& LLViewerRegion::getHost() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ class LLVOCache;
|
|||
class LLVOCacheEntry;
|
||||
class LLSpatialPartition;
|
||||
class LLEventPump;
|
||||
class LLCapabilityListener;
|
||||
class LLDataPacker;
|
||||
class LLDataPackerBinaryBuffer;
|
||||
class LLHost;
|
||||
|
|
@ -269,10 +268,6 @@ public:
|
|||
static bool isSpecialCapabilityName(const std::string &name);
|
||||
void logActiveCapabilities() const;
|
||||
|
||||
/// Get LLEventPump on which we listen for capability requests
|
||||
/// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities)
|
||||
LLEventPump& getCapAPI() const;
|
||||
|
||||
/// implements LLCapabilityProvider
|
||||
/*virtual*/ const LLHost& getHost() const;
|
||||
const U64 &getHandle() const { return mHandle; }
|
||||
|
|
|
|||
|
|
@ -1,271 +0,0 @@
|
|||
/**
|
||||
* @file llcapabilitylistener_test.cpp
|
||||
* @author Nat Goodspeed
|
||||
* @date 2008-12-31
|
||||
* @brief Test for llcapabilitylistener.cpp.
|
||||
*
|
||||
* $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$
|
||||
*/
|
||||
|
||||
// Precompiled header
|
||||
#include "../llviewerprecompiledheaders.h"
|
||||
// Own header
|
||||
#include "../llcapabilitylistener.h"
|
||||
// STL headers
|
||||
#include <stdexcept>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
// std headers
|
||||
// external library headers
|
||||
#include "boost/bind.hpp"
|
||||
// other Linden headers
|
||||
#include "../test/lltut.h"
|
||||
#include "../llcapabilityprovider.h"
|
||||
#include "lluuid.h"
|
||||
#include "tests/networkio.h"
|
||||
#include "tests/commtest.h"
|
||||
#include "tests/wrapllerrs.h"
|
||||
#include "message.h"
|
||||
#include "stringize.h"
|
||||
|
||||
#if defined(LL_WINDOWS)
|
||||
#pragma warning(disable: 4355) // using 'this' in base-class ctor initializer expr
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
* TestCapabilityProvider
|
||||
*****************************************************************************/
|
||||
struct TestCapabilityProvider: public LLCapabilityProvider
|
||||
{
|
||||
TestCapabilityProvider(const LLHost& host):
|
||||
mHost(host)
|
||||
{}
|
||||
|
||||
std::string getCapability(const std::string& cap) const
|
||||
{
|
||||
CapMap::const_iterator found = mCaps.find(cap);
|
||||
if (found != mCaps.end())
|
||||
return found->second;
|
||||
// normal LLViewerRegion lookup failure mode
|
||||
return "";
|
||||
}
|
||||
void setCapability(const std::string& cap, const std::string& url)
|
||||
{
|
||||
mCaps[cap] = url;
|
||||
}
|
||||
const LLHost& getHost() const { return mHost; }
|
||||
std::string getDescription() const { return "TestCapabilityProvider"; }
|
||||
|
||||
LLHost mHost;
|
||||
typedef std::map<std::string, std::string> CapMap;
|
||||
CapMap mCaps;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Dummy LLMessageSystem methods
|
||||
*****************************************************************************/
|
||||
/*==========================================================================*|
|
||||
// This doesn't work because we're already linking in llmessage.a, and we get
|
||||
// duplicate-symbol errors from the linker. Perhaps if I wanted to go through
|
||||
// the exercise of providing dummy versions of every single symbol defined in
|
||||
// message.o -- maybe some day.
|
||||
typedef std::vector< std::pair<std::string, std::string> > StringPairVector;
|
||||
StringPairVector call_history;
|
||||
|
||||
S32 LLMessageSystem::sendReliable(const LLHost& host)
|
||||
{
|
||||
call_history.push_back(StringPairVector::value_type("sendReliable", stringize(host)));
|
||||
return 0;
|
||||
}
|
||||
|*==========================================================================*/
|
||||
|
||||
/*****************************************************************************
|
||||
* TUT
|
||||
*****************************************************************************/
|
||||
namespace tut
|
||||
{
|
||||
struct llcapears_data: public commtest_data
|
||||
{
|
||||
TestCapabilityProvider provider;
|
||||
LLCapabilityListener regionListener;
|
||||
LLEventPump& regionPump;
|
||||
|
||||
llcapears_data():
|
||||
provider(host),
|
||||
regionListener("testCapabilityListener", NULL, provider, LLUUID(), LLUUID()),
|
||||
regionPump(regionListener.getCapAPI())
|
||||
{
|
||||
LLCurl::initClass();
|
||||
provider.setCapability("good", server + "capability-test");
|
||||
provider.setCapability("fail", server + "fail");
|
||||
}
|
||||
};
|
||||
typedef test_group<llcapears_data> llcapears_group;
|
||||
typedef llcapears_group::object llcapears_object;
|
||||
llcapears_group llsdmgr("llcapabilitylistener");
|
||||
|
||||
template<> template<>
|
||||
void llcapears_object::test<1>()
|
||||
{
|
||||
LLSD request, body;
|
||||
body["data"] = "yes";
|
||||
request["payload"] = body;
|
||||
request["reply"] = replyPump.getName();
|
||||
request["error"] = errorPump.getName();
|
||||
std::string threw;
|
||||
try
|
||||
{
|
||||
WrapLLErrs capture;
|
||||
regionPump.post(request);
|
||||
}
|
||||
catch (const WrapLLErrs::FatalException& e)
|
||||
{
|
||||
threw = e.what();
|
||||
}
|
||||
ensure_contains("missing capability name", threw, "without 'message' key");
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void llcapears_object::test<2>()
|
||||
{
|
||||
LLSD request, body;
|
||||
body["data"] = "yes";
|
||||
request["message"] = "good";
|
||||
request["payload"] = body;
|
||||
request["reply"] = replyPump.getName();
|
||||
request["error"] = errorPump.getName();
|
||||
regionPump.post(request);
|
||||
ensure("got response", netio.pump());
|
||||
ensure("success response", success);
|
||||
ensure_equals(result["reply"].asString(), "success");
|
||||
|
||||
body["status"] = 499;
|
||||
body["reason"] = "custom error message";
|
||||
request["message"] = "fail";
|
||||
request["payload"] = body;
|
||||
regionPump.post(request);
|
||||
ensure("got response", netio.pump());
|
||||
ensure("failure response", ! success);
|
||||
ensure_equals(result["status"].asInteger(), body["status"].asInteger());
|
||||
ensure_equals(result["reason"].asString(), body["reason"].asString());
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void llcapears_object::test<3>()
|
||||
{
|
||||
LLSD request, body;
|
||||
body["data"] = "yes";
|
||||
request["message"] = "unknown";
|
||||
request["payload"] = body;
|
||||
request["reply"] = replyPump.getName();
|
||||
request["error"] = errorPump.getName();
|
||||
std::string threw;
|
||||
try
|
||||
{
|
||||
WrapLLErrs capture;
|
||||
regionPump.post(request);
|
||||
}
|
||||
catch (const WrapLLErrs::FatalException& e)
|
||||
{
|
||||
threw = e.what();
|
||||
}
|
||||
ensure_contains("bad capability name", threw, "unsupported capability");
|
||||
}
|
||||
|
||||
struct TestMapper: public LLCapabilityListener::CapabilityMapper
|
||||
{
|
||||
// Instantiator gets to specify whether mapper expects a reply.
|
||||
// I'd really like to be able to test CapabilityMapper::buildMessage()
|
||||
// functionality, too, but -- even though LLCapabilityListener accepts
|
||||
// the LLMessageSystem* that it passes to CapabilityMapper --
|
||||
// LLMessageSystem::sendReliable(const LLHost&) isn't virtual, so it's
|
||||
// not helpful to pass a subclass instance. I suspect that making any
|
||||
// LLMessageSystem methods virtual would provoke howls of outrage,
|
||||
// given how heavily it's used. Nor can I just provide a local
|
||||
// definition of LLMessageSystem::sendReliable(const LLHost&) because
|
||||
// we're already linking in the rest of message.o via llmessage.a, and
|
||||
// that produces duplicate-symbol link errors.
|
||||
TestMapper(const std::string& replyMessage = std::string()):
|
||||
LLCapabilityListener::CapabilityMapper("test", replyMessage)
|
||||
{}
|
||||
virtual void buildMessage(LLMessageSystem* msg,
|
||||
const LLUUID& agentID,
|
||||
const LLUUID& sessionID,
|
||||
const std::string& capabilityName,
|
||||
const LLSD& payload) const
|
||||
{
|
||||
msg->newMessageFast(_PREHASH_SetStartLocationRequest);
|
||||
msg->nextBlockFast( _PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, agentID);
|
||||
msg->addUUIDFast(_PREHASH_SessionID, sessionID);
|
||||
msg->nextBlockFast( _PREHASH_StartLocationData);
|
||||
// corrected by sim
|
||||
msg->addStringFast(_PREHASH_SimName, "");
|
||||
msg->addU32Fast(_PREHASH_LocationID, payload["HomeLocation"]["LocationId"].asInteger());
|
||||
/*==========================================================================*|
|
||||
msg->addVector3Fast(_PREHASH_LocationPos,
|
||||
ll_vector3_from_sdmap(payload["HomeLocation"]["LocationPos"]));
|
||||
msg->addVector3Fast(_PREHASH_LocationLookAt,
|
||||
ll_vector3_from_sdmap(payload["HomeLocation"]["LocationLookAt"]));
|
||||
|*==========================================================================*/
|
||||
}
|
||||
};
|
||||
|
||||
template<> template<>
|
||||
void llcapears_object::test<4>()
|
||||
{
|
||||
TestMapper testMapper("WantReply");
|
||||
LLSD request, body;
|
||||
body["data"] = "yes";
|
||||
request["message"] = "test";
|
||||
request["payload"] = body;
|
||||
request["reply"] = replyPump.getName();
|
||||
request["error"] = errorPump.getName();
|
||||
std::string threw;
|
||||
try
|
||||
{
|
||||
WrapLLErrs capture;
|
||||
regionPump.post(request);
|
||||
}
|
||||
catch (const WrapLLErrs::FatalException& e)
|
||||
{
|
||||
threw = e.what();
|
||||
}
|
||||
ensure_contains("capability mapper wants reply", threw, "unimplemented support for reply message");
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void llcapears_object::test<5>()
|
||||
{
|
||||
TestMapper testMapper;
|
||||
std::string threw;
|
||||
try
|
||||
{
|
||||
TestMapper testMapper2;
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
threw = e.what();
|
||||
}
|
||||
ensure_contains("no dup cap mapper", threw, "DupCapMapper");
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue