LLViewerRegion WIP: Added all headers that are dragged in.
Most in particular llevents.h, which comes along with the demand that the old events in llevent.h are put in a namespace LLOldEvents. Made all changes necessary to compile the rest of the code again (without changing the actual code: it's still using the old events). This patch also removes LLStopWhenHandled and LLStandardSignal from indra/llui/llnotifications.h because those are moved to llevents.h. That seems to be the only change to indra/llui/llnotifications.h that isn't floater related, so I left the rest of that file alone.
This commit is contained in:
@@ -65,6 +65,7 @@ set(llmessage_SOURCE_FILES
|
||||
llregionpresenceverifier.cpp
|
||||
llsdappservices.cpp
|
||||
llsdhttpserver.cpp
|
||||
llsdmessage.cpp
|
||||
llsdmessagebuilder.cpp
|
||||
llsdmessagereader.cpp
|
||||
llsdrpcclient.cpp
|
||||
@@ -163,6 +164,7 @@ set(llmessage_HEADER_FILES
|
||||
llregionpresenceverifier.h
|
||||
llsdappservices.h
|
||||
llsdhttpserver.h
|
||||
llsdmessage.h
|
||||
llsdmessagebuilder.h
|
||||
llsdmessagereader.h
|
||||
llsdrpcclient.h
|
||||
|
||||
170
indra/llmessage/llsdmessage.cpp
Normal file
170
indra/llmessage/llsdmessage.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
/**
|
||||
* @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
|
||||
timeout);
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLSDMessage::EventResponder::result(const LLSD& data)
|
||||
{
|
||||
// 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(data);
|
||||
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::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
|
||||
{
|
||||
// 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"] = LLSD::Integer(status);
|
||||
info["reason"] = reason;
|
||||
info["content"] = content;
|
||||
mPumps.obtain(mErrorPump).post(info);
|
||||
}
|
||||
else // default error handling
|
||||
{
|
||||
// convention seems to be to use llinfos, but that seems a bit casual?
|
||||
LL_WARNS("LLSDMessage::EventResponder")
|
||||
<< "'" << mMessage << "' to '" << mTarget
|
||||
<< "' failed with code " << status << ": " << reason << '\n'
|
||||
<< ll_pretty_print_sd(content)
|
||||
<< 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->result(payload);
|
||||
}
|
||||
else
|
||||
{
|
||||
mResponder->errorWithContent(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()
|
||||
{
|
||||
}
|
||||
166
indra/llmessage/llsdmessage.h
Normal file
166
indra/llmessage/llsdmessage.h
Normal file
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* @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
|
||||
{
|
||||
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)
|
||||
{}
|
||||
|
||||
virtual void result(const LLSD& data);
|
||||
virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
|
||||
|
||||
private:
|
||||
LLEventPumps& mPumps;
|
||||
LLReqID mReqID;
|
||||
const std::string mTarget, mMessage, mReplyPump, mErrorPump;
|
||||
};
|
||||
|
||||
private:
|
||||
bool httpListener(const LLSD&);
|
||||
LLEventStream mEventPump;
|
||||
};
|
||||
|
||||
#endif /* ! defined(LL_LLSDMESSAGE_H) */
|
||||
Reference in New Issue
Block a user