summaryrefslogtreecommitdiff
path: root/indra/llmessage/lliohttpserver.h
blob: 5c1b0531ff2693de45fd6b15147523e27f7e725f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/** 
 * @file lliohttpserver.h
 * @brief Declaration of function for creating an HTTP wire server
 * @see LLIOServerSocket, LLPumpIO
 *
 * $LicenseInfo:firstyear=2005&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$
 */

#ifndef LL_LLIOHTTPSERVER_H
#define LL_LLIOHTTPSERVER_H

#include "llchainio.h"
#include "llhttpnode.h"

class LLPumpIO;

// common strings use for populating the context. bascally 'request',
// 'wildcard', and 'headers'.
extern const std::string CONTEXT_REQUEST;
extern const std::string CONTEXT_RESPONSE;
extern const std::string CONTEXT_VERB;
extern const std::string CONTEXT_HEADERS;
extern const std::string HTTP_VERB_GET;
extern const std::string HTTP_VERB_PUT;
extern const std::string HTTP_VERB_POST;
extern const std::string HTTP_VERB_DELETE;
extern const std::string HTTP_VERB_OPTIONS;

class LLIOHTTPServer
{
public:
	typedef void (*timing_callback_t)(const char* hashed_name, F32 time, void* data);

	static LLHTTPNode& create(apr_pool_t* pool, LLPumpIO& pump, U16 port);
	/**< Creates an HTTP wire server on the pump for the given TCP port.
	 *
	 *   Returns the root node of the new server.  Add LLHTTPNode instances
	 *   to this root.
	 *
	 *   Nodes that return NULL for getProtocolHandler(), will use the
	 *   default handler that interprets HTTP on the wire and converts
	 *   it into calls to get(), put(), post(), del() with appropriate
	 *   LLSD arguments and results.
	 *
	 *   To have nodes that implement some other wire protocol (XML-RPC
	 *   for example), use the helper templates below.
	 */
 
	static void createPipe(LLPumpIO::chain_t& chain, 
            const LLHTTPNode& root, const LLSD& ctx);
	/**< Create a pipe on the chain that handles HTTP requests.
	 *   The requests are served by the node tree given at root.
	 *
	 *   This is primarily useful for unit testing.
	 */

	static void setTimingCallback(timing_callback_t callback, void* data);
	/**< Register a callback function that will be called every time
	*    a GET, PUT, POST, or DELETE is handled.
	*
	* This is used to time the LLHTTPNode handler code, which often hits
	* the database or does other, slow operations. JC
	*/
};

/* @name Helper Templates
 *
 * These templates make it easy to create nodes that use thier own protocol
 * handlers rather than the default.  Typically, you subclass LLIOPipe to
 * implement the protocol, and then add a node using the templates:
 *
 * rootNode->addNode("thing", new LLHTTPNodeForPipe<LLThingPipe>);
 *
 * The templates are:
 *
 * 	LLChainIOFactoryForPipe
 * 		- a simple factory that builds instances of a pipe
 *
 * 	LLHTTPNodeForFacotry
 * 		- a HTTP node that uses a factory as the protocol handler
 *
 * 	LLHTTPNodeForPipe
 * 		- a HTTP node that uses a simple factory based on a pipe
 */
//@{

template<class Pipe>
class LLChainIOFactoryForPipe : public LLChainIOFactory
{
public:
	virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
	{   
		chain.push_back(LLIOPipe::ptr_t(new Pipe));
		return true;
	}
};

template<class Factory>
class LLHTTPNodeForFactory : public LLHTTPNode
{
public:
	const LLChainIOFactory* getProtocolHandler() const
		{ return &mProtocolHandler; }

private:
	Factory mProtocolHandler;
};

//@}


template<class Pipe>
class LLHTTPNodeForPipe : public LLHTTPNodeForFactory<
						  			LLChainIOFactoryForPipe<Pipe> >
{
};


#endif // LL_LLIOHTTPSERVER_H