aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmessage/llsdrpcserver.h
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llmessage/llsdrpcserver.h
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to '')
-rw-r--r--linden/indra/llmessage/llsdrpcserver.h361
1 files changed, 361 insertions, 0 deletions
diff --git a/linden/indra/llmessage/llsdrpcserver.h b/linden/indra/llmessage/llsdrpcserver.h
new file mode 100644
index 0000000..35d91ee
--- /dev/null
+++ b/linden/indra/llmessage/llsdrpcserver.h
@@ -0,0 +1,361 @@
1/**
2 * @file llsdrpcserver.h
3 * @author Phoenix
4 * @date 2005-10-11
5 * @brief Declaration of the structured data remote procedure call server.
6 *
7 * Copyright (c) 2005-2007, Linden Research, Inc.
8 *
9 * The source code in this file ("Source Code") is provided by Linden Lab
10 * to you under the terms of the GNU General Public License, version 2.0
11 * ("GPL"), unless you have obtained a separate licensing agreement
12 * ("Other License"), formally executed by you and Linden Lab. Terms of
13 * the GPL can be found in doc/GPL-license.txt in this distribution, or
14 * online at http://secondlife.com/developers/opensource/gplv2
15 *
16 * There are special exceptions to the terms and conditions of the GPL as
17 * it is applied to this Source Code. View the full text of the exception
18 * in the file doc/FLOSS-exception.txt in this software distribution, or
19 * online at http://secondlife.com/developers/opensource/flossexception
20 *
21 * By copying, modifying or distributing this software, you acknowledge
22 * that you have read and understood your obligations described above,
23 * and agree to abide by those obligations.
24 *
25 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
26 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
27 * COMPLETENESS OR PERFORMANCE.
28 */
29
30#ifndef LL_LLSDRPCSERVER_H
31#define LL_LLSDRPCSERVER_H
32
33/**
34 * I've set this up to be pretty easy to use when you want to make a
35 * structured data rpc server which responds to methods by
36 * name. Derive a class from the LLSDRPCServer, and during
37 * construction (or initialization if you have the luxury) map method
38 * names to pointers to member functions. This will look a lot like:
39 *
40 * <code>
41 * class LLMessageAgents : public LLSDRPCServer {<br>
42 * public:<br>
43 * typedef LLSDRPCServer<LLUsher> mem_fn_t;<br>
44 * LLMessageAgents() {<br>
45 * mMethods["message"] = new mem_fn_t(this, &LLMessageAgents::rpc_IM);<br>
46 * mMethods["alert"] = new mem_fn_t(this, &LLMessageAgents::rpc_Alrt);<br>
47 * }<br>
48 * protected:<br>
49 * rpc_IM(const LLSD& params,
50 * const LLChannelDescriptors& channels,
51 * LLBufferArray* data)
52 * {...}<br>
53 * rpc_Alert(const LLSD& params,
54 * const LLChannelDescriptors& channels,
55 * LLBufferArray* data)
56 * {...}<br>
57 * };<br>
58 * </code>
59 *
60 * The params are an array where each element in the array is a single
61 * parameter in the call.
62 *
63 * It is up to you to pack a valid serialized llsd response into the
64 * data object passed into the method, but you can use the helper
65 * methods below to help.
66 */
67
68#include <map>
69#include "lliopipe.h"
70#include "lliohttpserver.h"
71#include "llfiltersd2xmlrpc.h"
72
73class LLSD;
74
75/**
76 * @brief Enumeration for specifying server method call status. This
77 * enumeration controls how the server class will manage the pump
78 * process/callback mechanism.
79 */
80enum ESDRPCSStatus
81{
82 // The call went ok, but the response is not yet ready. The
83 // method will arrange for the clearLock() call to be made at
84 // a later date, after which, once the chain is being pumped
85 // again, deferredResponse() will be called to gather the result
86 ESDRPCS_DEFERRED,
87
88 // The LLSDRPCServer would like to handle the method on the
89 // callback queue of the pump.
90 ESDRPCS_CALLBACK,
91
92 // The method call finished and generated output.
93 ESDRPCS_DONE,
94
95 // Method failed for some unspecified reason - you should avoid
96 // this. A generic fault will be sent to the output.
97 ESDRPCS_ERROR,
98
99 ESDRPCS_COUNT,
100};
101
102/**
103 * @class LLSDRPCMethodCallBase
104 * @brief Base class for calling a member function in an sd rpcserver
105 * implementation.
106 */
107class LLSDRPCMethodCallBase
108{
109public:
110 LLSDRPCMethodCallBase() {}
111 virtual ~LLSDRPCMethodCallBase() {}
112
113 virtual ESDRPCSStatus call(
114 const LLSD& params,
115 const LLChannelDescriptors& channels,
116 LLBufferArray* response) = 0;
117protected:
118};
119
120/**
121 * @class LLSDRPCMethodCall
122 * @brief Class which implements member function calls.
123 */
124template<class Server>
125class LLSDRPCMethodCall : public LLSDRPCMethodCallBase
126{
127public:
128 typedef ESDRPCSStatus (Server::*mem_fn)(
129 const LLSD& params,
130 const LLChannelDescriptors& channels,
131 LLBufferArray* data);
132 LLSDRPCMethodCall(Server* s, mem_fn fn) :
133 mServer(s),
134 mMemFn(fn)
135 {
136 }
137 virtual ~LLSDRPCMethodCall() {}
138 virtual ESDRPCSStatus call(
139 const LLSD& params,
140 const LLChannelDescriptors& channels,
141 LLBufferArray* data)
142 {
143 return (*mServer.*mMemFn)(params, channels, data);
144 }
145
146protected:
147 Server* mServer;
148 mem_fn mMemFn;
149 //bool (Server::*mMemFn)(const LLSD& params, LLBufferArray& data);
150};
151
152
153/**
154 * @class LLSDRPCServer
155 * @brief Basic implementation of a structure data rpc server
156 *
157 * The rpc server is also designed to appropriately straddle the pump
158 * <code>process()</code> and <code>callback()</code> to specify which
159 * thread you want to work on when handling a method call. The
160 * <code>mMethods</code> methods are called from
161 * <code>process()</code>, while the <code>mCallbackMethods</code> are
162 * called when a pump is in a <code>callback()</code> cycle.
163 */
164class LLSDRPCServer : public LLIOPipe
165{
166public:
167 LLSDRPCServer();
168 virtual ~LLSDRPCServer();
169
170 /**
171 * enumeration for generic fault codes
172 */
173 enum
174 {
175 FAULT_BAD_REQUEST = 2000,
176 FAULT_NO_RESPONSE = 2001,
177 };
178
179 /**
180 * @brief Call this method to return an rpc fault.
181 *
182 * @param channel The channel for output on the data buffer
183 * @param data buffer which will recieve the final output
184 * @param code The fault code
185 * @param msg The fault message
186 */
187 static void buildFault(
188 const LLChannelDescriptors& channels,
189 LLBufferArray* data,
190 S32 code,
191 const std::string& msg);
192
193 /**
194 * @brief Call this method to build an rpc response.
195 *
196 * @param channel The channel for output on the data buffer
197 * @param data buffer which will recieve the final output
198 * @param response The return value from the method call
199 */
200 static void buildResponse(
201 const LLChannelDescriptors& channels,
202 LLBufferArray* data,
203 const LLSD& response);
204
205protected:
206 /* @name LLIOPipe virtual implementations
207 */
208 //@{
209 /**
210 * @brief Process the data in buffer
211 */
212 virtual EStatus process_impl(
213 const LLChannelDescriptors& channels,
214 buffer_ptr_t& buffer,
215 bool& eos,
216 LLSD& context,
217 LLPumpIO* pump);
218 //@}
219
220protected:
221
222 /**
223 * @brief Enumeration to track the state of the rpc server instance
224 */
225 enum EState
226 {
227 STATE_NONE,
228 STATE_CALLBACK,
229 STATE_DEFERRED,
230 STATE_DONE
231 };
232
233 /**
234 * @brief This method is called when an http post comes in.
235 *
236 * The default behavior is to look at the method name, look up the
237 * method in the method table, and call it. If the method is not
238 * found, this function will build a fault response. You can
239 * implement your own version of this function if you want to hard
240 * wire some behavior or optimize things a bit.
241 * @param method The method name being called
242 * @param params The parameters
243 * @param channel The channel for output on the data buffer
244 * @param data The http data
245 * @return Returns the status of the method call, done/deferred/etc
246 */
247 virtual ESDRPCSStatus callMethod(
248 const std::string& method,
249 const LLSD& params,
250 const LLChannelDescriptors& channels,
251 LLBufferArray* data);
252
253 /**
254 * @brief This method is called when a pump callback is processed.
255 *
256 * The default behavior is to look at the method name, look up the
257 * method in the callback method table, and call it. If the method
258 * is not found, this function will build a fault response. You
259 * can implement your own version of this function if you want to
260 * hard wire some behavior or optimize things a bit.
261 * @param method The method name being called
262 * @param params The parameters
263 * @param channel The channel for output on the data buffer
264 * @param data The http data
265 * @return Returns the status of the method call, done/deferred/etc
266 */
267 virtual ESDRPCSStatus callbackMethod(
268 const std::string& method,
269 const LLSD& params,
270 const LLChannelDescriptors& channels,
271 LLBufferArray* data);
272
273 /**
274 * @brief Called after a deferred service is unlocked
275 *
276 * If a method returns ESDRPCS_DEFERRED, then the service chain
277 * will be locked and not processed until some other system calls
278 * clearLock() on the service instance again. At that point,
279 * once the pump starts processing the chain again, this method
280 * will be called so the service can output the final result
281 * into the buffers.
282 */
283 virtual ESDRPCSStatus deferredResponse(
284 const LLChannelDescriptors& channels,
285 LLBufferArray* data);
286
287 // donovan put this public here 7/27/06
288public:
289 /**
290 * @brief unlock a service that as ESDRPCS_DEFERRED
291 */
292 void clearLock();
293
294protected:
295 EState mState;
296 LLSD mRequest;
297 LLPumpIO* mPump;
298 S32 mLock;
299 typedef std::map<std::string, LLSDRPCMethodCallBase*> method_map_t;
300 method_map_t mMethods;
301 method_map_t mCallbackMethods;
302};
303
304/**
305 * @name Helper Templates for making LLHTTPNodes
306 *
307 * These templates help in creating nodes for handing a service from
308 * either SDRPC or XMLRPC, given a single implementation of LLSDRPCServer.
309 *
310 * To use it:
311 * \code
312 * class LLUsefulServer : public LLSDRPCServer { ... }
313 *
314 * LLHTTPNode& root = LLCreateHTTPWireServer(...);
315 * root.addNode("llsdrpc/useful", new LLSDRPCNode<LLUsefulServer>);
316 * root.addNode("xmlrpc/useful", new LLXMLRPCNode<LLUsefulServer>);
317 * \endcode
318 */
319//@{
320
321template<class Server>
322class LLSDRPCServerFactory : public LLChainIOFactory
323{
324public:
325 virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
326 {
327 lldebugs << "LLXMLSDRPCServerFactory::build" << llendl;
328 chain.push_back(LLIOPipe::ptr_t(new Server));
329 return true;
330 }
331};
332
333template<class Server>
334class LLSDRPCNode : public LLHTTPNodeForFactory<
335 LLSDRPCServerFactory<Server> >
336{
337};
338
339template<class Server>
340class LLXMLRPCServerFactory : public LLChainIOFactory
341{
342public:
343 virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
344 {
345 lldebugs << "LLXMLSDRPCServerFactory::build" << llendl;
346 chain.push_back(LLIOPipe::ptr_t(new LLFilterXMLRPCRequest2LLSD));
347 chain.push_back(LLIOPipe::ptr_t(new Server));
348 chain.push_back(LLIOPipe::ptr_t(new LLFilterSD2XMLRPCResponse));
349 return true;
350 }
351};
352
353template<class Server>
354class LLXMLRPCNode : public LLHTTPNodeForFactory<
355 LLXMLRPCServerFactory<Server> >
356{
357};
358
359//@}
360
361#endif // LL_LLSDRPCSERVER_H