aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmessage/llhttpnode.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/llhttpnode.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 'linden/indra/llmessage/llhttpnode.h')
-rw-r--r--linden/indra/llmessage/llhttpnode.h325
1 files changed, 325 insertions, 0 deletions
diff --git a/linden/indra/llmessage/llhttpnode.h b/linden/indra/llmessage/llhttpnode.h
new file mode 100644
index 0000000..bbce091
--- /dev/null
+++ b/linden/indra/llmessage/llhttpnode.h
@@ -0,0 +1,325 @@
1/**
2 * @file llhttpnode.h
3 * @brief Declaration of classes for generic HTTP/LSL/REST handling.
4 *
5 * Copyright (c) 2006-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LLHTTPNODE_H
29#define LL_LLHTTPNODE_H
30
31#include "llmemory.h"
32#include "llsd.h"
33
34class LLChainIOFactory;
35
36
37/**
38 * These classes represent the HTTP framework: The URL tree, and the LLSD
39 * REST interface that such nodes implement.
40 *
41 * To implement a service, in most cases, subclass LLHTTPNode, implement
42 * get() or post(), and create a global instance of LLHTTPRegistration<>.
43 * This can all be done in a .cpp file, with no publically declared parts.
44 *
45 * To implement a server see lliohttpserver.h
46 * @see LLHTTPWireServer
47 */
48
49/**
50 * @class LLHTTPNode
51 * @brief Base class which handles url traversal, response routing
52 * and support for standard LLSD services
53 *
54 * Users of the HTTP responder will typically derive a class from this
55 * one, implement the get(), put() and/or post() methods, and then
56 * use LLHTTPRegistration to insert it into the URL tree.
57 *
58 * The default implementation handles servicing the request and creating
59 * the pipe fittings needed to read the headers, manage them, convert
60 * to and from LLSD, etc.
61 */
62class LLHTTPNode
63{
64public:
65 LLHTTPNode();
66 virtual ~LLHTTPNode();
67
68 /** @name Responses
69 Most subclasses override one or more of these methods to provide
70 the service. By default, the rest of the LLHTTPNode architecture
71 will handle requests, create the needed LLIOPump, parse the input
72 to LLSD, and format the LLSD result to the output.
73
74 The default implementation of each of these is to call
75 response->methodNotAllowed(); The "simple" versions can be
76 overridden instead in those cases where the service can return
77 an immediately computed response.
78 */
79 //@{
80public:
81 virtual LLSD get() const;
82 virtual LLSD put(const LLSD& input) const;
83 virtual LLSD post(const LLSD& input) const;
84
85 virtual LLSD del() const;
86 virtual LLSD del(const LLSD& context) const;
87
88 class Response : public LLRefCount
89 {
90 public:
91 virtual ~Response();
92
93 virtual void result(const LLSD&) = 0;
94 virtual void status(S32 code, const std::string& message) = 0;
95
96 void status(S32 code);
97 void notFound(const std::string& message);
98 void notFound();
99 void methodNotAllowed();
100 };
101
102 typedef LLPointer<Response> ResponsePtr;
103
104 virtual void get(ResponsePtr, const LLSD& context) const;
105 virtual void put(ResponsePtr, const LLSD& context, const LLSD& input) const;
106 virtual void post(ResponsePtr, const LLSD& context, const LLSD& input) const;
107 virtual void del(ResponsePtr, const LLSD& context) const;
108 //@}
109
110
111 /** @name URL traversal
112 The tree is traversed by calling getChild() with successive
113 path components, on successive results. When getChild() returns
114 null, or there are no more components, the last child responds to
115 the request.
116
117 The default behavior is generally correct, though wildcard nodes
118 will want to implement validate().
119 */
120 //@{
121public:
122 virtual LLHTTPNode* getChild(const std::string& name, LLSD& context) const;
123 /**< returns a child node, if any, at the given name
124 default looks at children and wildcard child (see below)
125 */
126
127 virtual bool handles(const LLSD& remainder, LLSD& context) const;
128 /**< return true if this node can service the remaining components;
129 default returns true if there are no remaining components
130 */
131
132 virtual bool validate(const std::string& name, LLSD& context) const;
133 /**< called only on wildcard nodes, to check if they will handle
134 the name; default is false; overrides will want to check
135 name, and return true if the name will construct to a valid url.
136 For convenience, the <code>getChild()</code> method above will
137 automatically insert the name in
138 context["request"]["wildcard"][key] if this method returns true.
139 For example, the node "agent/<agent_id>/detail" will set
140 context["request"]["wildcard"]["agent_id"] eqaul to the value
141 found during traversal.
142 */
143
144 const LLHTTPNode* traverse(const std::string& path, LLSD& context) const;
145 /**< find a node, if any, that can service this path
146 set up context["request"] information
147 */
148 //@}
149
150 /** @name Child Nodes
151 The standard node can have any number of child nodes under
152 fixed names, and optionally one "wildcard" node that can
153 handle all other names.
154
155 Usually, child nodes are add through LLHTTPRegistration, not
156 by calling this interface directly.
157
158 The added node will be now owned by the parent node.
159 */
160 //@{
161
162 virtual void addNode(const std::string& path, LLHTTPNode* nodeToAdd);
163
164 LLSD allNodePaths() const;
165 ///< Returns an arrary of node paths at and under this node
166
167 const LLHTTPNode* rootNode() const;
168 const LLHTTPNode* findNode(const std::string& name) const;
169
170 //@}
171
172 /* @name Description system
173 The Description object contains information about a service.
174 All subclasses of LLHTTPNode should override description() and use
175 the methods of the Description class to set the various properties.
176 */
177 //@{
178 class Description
179 {
180 public:
181 void shortInfo(const std::string& s){ mInfo["description"] = s; }
182 void longInfo(const std::string& s) { mInfo["details"] = s; }
183
184 // Call this method when the service supports the specified verb.
185 void getAPI() { mInfo["api"].append("GET"); }
186 void putAPI() { mInfo["api"].append("PUT"); }
187 void postAPI() { mInfo["api"].append("POST"); }
188 void delAPI() { mInfo["api"].append("DELETE"); }
189
190 void input(const std::string& s) { mInfo["input"] = s; }
191 void output(const std::string& s) { mInfo["output"] = s; }
192 void source(const char* f, int l) { mInfo["__file__"] = f;
193 mInfo["__line__"] = l; }
194
195 LLSD getInfo() const { return mInfo; }
196
197 private:
198 LLSD mInfo;
199 };
200
201 virtual void describe(Description&) const;
202
203 //@}
204
205
206 virtual const LLChainIOFactory* getProtocolHandler() const;
207 /**< Return a factory object for handling wire protocols.
208 * The base class returns NULL, as it doesn't know about
209 * wire protocols at all. This is okay for most nodes
210 * as LLIOHTTPServer is smart enough to use a default
211 * wire protocol for HTTP for such nodes. Specialized
212 * subclasses that handle things like XML-RPC will want
213 * to implement this. (See LLXMLSDRPCServerFactory.)
214 */
215
216private:
217 class Impl;
218 Impl& impl;
219};
220
221
222
223class LLSimpleResponse : public LLHTTPNode::Response
224{
225public:
226 static LLPointer<LLSimpleResponse> create();
227 ~LLSimpleResponse();
228
229 void result(const LLSD& result);
230 void status(S32 code, const std::string& message);
231
232 void print(std::ostream& out) const;
233
234 S32 mCode;
235 std::string mMessage;
236
237private:
238 LLSimpleResponse() {;} // Must be accessed through LLPointer.
239};
240
241std::ostream& operator<<(std::ostream& out, const LLSimpleResponse& resp);
242
243
244
245/**
246 * @name Automatic LLHTTPNode registration
247 *
248 * To register a node type at a particular url path, construct a global instance
249 * of LLHTTPRegistration:
250 *
251 * LLHTTPRegistration<LLMyNodeType> gHTTPServiceAlphaBeta("/alpha/beta");
252 *
253 * (Note the naming convention carefully.) This object must be global and not
254 * static. However, it needn't be declared in your .h file. It can exist
255 * solely in the .cpp file. The same is true of your subclass of LLHTTPNode:
256 * it can be declared and defined wholly within the .cpp file.
257 *
258 * When constructing a web server, use LLHTTPRegistrar to add all the registered
259 * nodes to the url tree:
260 *
261 * LLHTTPRegistrar::buidlAllServices(mRootNode);
262 */
263//@{
264
265class LLHTTPRegistrar
266{
267public:
268 class NodeFactory
269 {
270 public:
271 virtual ~NodeFactory();
272 virtual LLHTTPNode* build() const = 0;
273 };
274
275 static void buildAllServices(LLHTTPNode& root);
276
277 static void registerFactory(const std::string& path, NodeFactory& factory);
278 ///< construct an LLHTTPRegistration below to call this
279};
280
281template < class NodeType >
282class LLHTTPRegistration
283{
284public:
285 LLHTTPRegistration(const std::string& path)
286 {
287 LLHTTPRegistrar::registerFactory(path, mFactory);
288 }
289
290private:
291 class ThisNodeFactory : public LLHTTPRegistrar::NodeFactory
292 {
293 public:
294 virtual LLHTTPNode* build() const { return new NodeType; }
295 };
296
297 ThisNodeFactory mFactory;
298};
299
300template < class NodeType>
301class LLHTTPParamRegistration
302{
303public:
304 LLHTTPParamRegistration(const std::string& path, LLSD params) :
305 mFactory(params)
306 {
307 LLHTTPRegistrar::registerFactory(path, mFactory);
308 }
309
310private:
311 class ThisNodeFactory : public LLHTTPRegistrar::NodeFactory
312 {
313 public:
314 ThisNodeFactory(LLSD params) : mParams(params) {}
315 virtual LLHTTPNode* build() const { return new NodeType(mParams); }
316 private:
317 LLSD mParams;
318 };
319
320 ThisNodeFactory mFactory;
321};
322
323//@}
324
325#endif // LL_LLHTTPNODE_H