aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Common/OpenSim.Servers/BaseHttpServer.cs
diff options
context:
space:
mode:
authorAdam Frisby2007-07-11 08:02:47 +0000
committerAdam Frisby2007-07-11 08:02:47 +0000
commit5c7ffdde0b9642a42e8f5987e06eb01220ff7776 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /Common/OpenSim.Servers/BaseHttpServer.cs
parentWho would have known that the only way of specifying utf-8 without preamble, ... (diff)
downloadopensim-SC_OLD-5c7ffdde0b9642a42e8f5987e06eb01220ff7776.zip
opensim-SC_OLD-5c7ffdde0b9642a42e8f5987e06eb01220ff7776.tar.gz
opensim-SC_OLD-5c7ffdde0b9642a42e8f5987e06eb01220ff7776.tar.bz2
opensim-SC_OLD-5c7ffdde0b9642a42e8f5987e06eb01220ff7776.tar.xz
* Wiping trunk in prep for Sugilite
Diffstat (limited to 'Common/OpenSim.Servers/BaseHttpServer.cs')
-rw-r--r--Common/OpenSim.Servers/BaseHttpServer.cs283
1 files changed, 0 insertions, 283 deletions
diff --git a/Common/OpenSim.Servers/BaseHttpServer.cs b/Common/OpenSim.Servers/BaseHttpServer.cs
deleted file mode 100644
index ec5a6d7..0000000
--- a/Common/OpenSim.Servers/BaseHttpServer.cs
+++ /dev/null
@@ -1,283 +0,0 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Text;
32using System.Text.RegularExpressions;
33using System.Threading;
34//using OpenSim.CAPS;
35using Nwc.XmlRpc;
36using System.Collections;
37using OpenSim.Framework.Console;
38
39namespace OpenSim.Servers
40{
41 public class BaseHttpServer
42 {
43 protected class RestMethodEntry
44 {
45 private string m_path;
46 public string Path
47 {
48 get { return m_path; }
49 }
50
51 private RestMethod m_restMethod;
52 public RestMethod RestMethod
53 {
54 get { return m_restMethod; }
55 }
56
57 public RestMethodEntry(string path, RestMethod restMethod)
58 {
59 m_path = path;
60 m_restMethod = restMethod;
61 }
62 }
63
64 protected Thread m_workerThread;
65 protected HttpListener m_httpListener;
66 protected Dictionary<string, RestMethodEntry> m_restHandlers = new Dictionary<string, RestMethodEntry>();
67 protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>();
68 protected int m_port;
69
70 public BaseHttpServer(int port)
71 {
72 m_port = port;
73 }
74
75 public bool AddRestHandler(string method, string path, RestMethod handler)
76 {
77 string methodKey = String.Format("{0}: {1}", method, path);
78
79 if (!this.m_restHandlers.ContainsKey(methodKey))
80 {
81 this.m_restHandlers.Add(methodKey, new RestMethodEntry(path, handler));
82 return true;
83 }
84
85 //must already have a handler for that path so return false
86 return false;
87 }
88
89 public bool AddXmlRPCHandler(string method, XmlRpcMethod handler)
90 {
91 if (!this.m_rpcHandlers.ContainsKey(method))
92 {
93 this.m_rpcHandlers.Add(method, handler);
94 return true;
95 }
96
97 //must already have a handler for that path so return false
98 return false;
99 }
100
101 protected virtual string ProcessXMLRPCMethod(string methodName, XmlRpcRequest request)
102 {
103 XmlRpcResponse response;
104
105 XmlRpcMethod method;
106 if (this.m_rpcHandlers.TryGetValue(methodName, out method))
107 {
108 response = method(request);
109 }
110 else
111 {
112 response = new XmlRpcResponse();
113 Hashtable unknownMethodError = new Hashtable();
114 unknownMethodError["reason"] = "XmlRequest"; ;
115 unknownMethodError["message"] = "Unknown Rpc request";
116 unknownMethodError["login"] = "false";
117 response.Value = unknownMethodError;
118 }
119
120 return XmlRpcResponseSerializer.Singleton.Serialize(response);
121 }
122
123 protected virtual string ParseREST(string request, string path, string method)
124 {
125 string response;
126
127 string requestKey = String.Format("{0}: {1}", method, path);
128
129 string bestMatch = String.Empty;
130 foreach (string currentKey in m_restHandlers.Keys)
131 {
132 if (requestKey.StartsWith(currentKey))
133 {
134 if (currentKey.Length > bestMatch.Length)
135 {
136 bestMatch = currentKey;
137 }
138 }
139 }
140
141 RestMethodEntry restMethodEntry;
142 if (m_restHandlers.TryGetValue(bestMatch, out restMethodEntry))
143 {
144 RestMethod restMethod = restMethodEntry.RestMethod;
145
146 string param = path.Substring(restMethodEntry.Path.Length);
147 response = restMethod(request, path, param);
148
149 }
150 else
151 {
152 response = String.Empty;
153 }
154
155 return response;
156 }
157
158 protected virtual string ParseLLSDXML(string requestBody)
159 {
160 // dummy function for now - IMPLEMENT ME!
161 return "";
162 }
163
164 protected virtual string ParseXMLRPC(string requestBody)
165 {
166 string responseString = String.Empty;
167
168 try
169 {
170 XmlRpcRequest request = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody);
171
172 string methodName = request.MethodName;
173
174 responseString = ProcessXMLRPCMethod(methodName, request);
175 }
176 catch (Exception e)
177 {
178 Console.WriteLine(e.ToString());
179 }
180 return responseString;
181 }
182
183 public virtual void HandleRequest(Object stateinfo)
184 {
185 try
186 {
187 HttpListenerContext context = (HttpListenerContext)stateinfo;
188
189 HttpListenerRequest request = context.Request;
190 HttpListenerResponse response = context.Response;
191
192 response.KeepAlive = false;
193 response.SendChunked = false;
194
195 System.IO.Stream body = request.InputStream;
196 System.Text.Encoding encoding = System.Text.Encoding.UTF8;
197 System.IO.StreamReader reader = new System.IO.StreamReader(body, encoding);
198
199 string requestBody = reader.ReadToEnd();
200 body.Close();
201 reader.Close();
202
203 //Console.WriteLine(request.HttpMethod + " " + request.RawUrl + " Http/" + request.ProtocolVersion.ToString() + " content type: " + request.ContentType);
204 //Console.WriteLine(requestBody);
205
206 string responseString = "";
207 switch (request.ContentType)
208 {
209 case "text/xml":
210 // must be XML-RPC, so pass to the XML-RPC parser
211
212 responseString = ParseXMLRPC(requestBody);
213 responseString = Regex.Replace(responseString, "utf-16", "utf-8");
214
215 response.AddHeader("Content-type", "text/xml");
216 break;
217
218 case "application/xml":
219 // probably LLSD we hope, otherwise it should be ignored by the parser
220 responseString = ParseLLSDXML(requestBody);
221 response.AddHeader("Content-type", "application/xml");
222 break;
223
224 case "application/x-www-form-urlencoded":
225 // a form data POST so send to the REST parser
226 responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
227 response.AddHeader("Content-type", "text/html");
228 break;
229
230 case null:
231 // must be REST or invalid crap, so pass to the REST parser
232 responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
233 response.AddHeader("Content-type", "text/html");
234 break;
235
236 }
237
238 byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
239 System.IO.Stream output = response.OutputStream;
240 response.SendChunked = false;
241 response.ContentLength64 = buffer.Length;
242 output.Write(buffer, 0, buffer.Length);
243 output.Close();
244 }
245 catch (Exception e)
246 {
247 Console.WriteLine(e.ToString());
248 }
249 }
250
251 public void Start()
252 {
253 MainConsole.Instance.Verbose("BaseHttpServer.cs: Starting up HTTP Server");
254
255 m_workerThread = new Thread(new ThreadStart(StartHTTP));
256 m_workerThread.IsBackground = true;
257 m_workerThread.Start();
258 }
259
260 private void StartHTTP()
261 {
262 try
263 {
264 MainConsole.Instance.Verbose("BaseHttpServer.cs: StartHTTP() - Spawned main thread OK");
265 m_httpListener = new HttpListener();
266
267 m_httpListener.Prefixes.Add("http://+:" + m_port + "/");
268 m_httpListener.Start();
269
270 HttpListenerContext context;
271 while (true)
272 {
273 context = m_httpListener.GetContext();
274 ThreadPool.QueueUserWorkItem(new WaitCallback(HandleRequest), context);
275 }
276 }
277 catch (Exception e)
278 {
279 MainConsole.Instance.Warn(e.Message);
280 }
281 }
282 }
283}