aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim.Servers/BaseHttpServer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim.Servers/BaseHttpServer.cs')
-rw-r--r--OpenSim.Servers/BaseHttpServer.cs224
1 files changed, 224 insertions, 0 deletions
diff --git a/OpenSim.Servers/BaseHttpServer.cs b/OpenSim.Servers/BaseHttpServer.cs
new file mode 100644
index 0000000..2f73f46
--- /dev/null
+++ b/OpenSim.Servers/BaseHttpServer.cs
@@ -0,0 +1,224 @@
1using System;
2using System.Collections.Generic;
3using System.Net;
4using System.Text;
5using System.Text.RegularExpressions;
6using System.Threading;
7//using OpenSim.CAPS;
8using Nwc.XmlRpc;
9using System.Collections;
10
11namespace OpenSim.Servers
12{
13 public class BaseHttpServer
14 {
15 protected Thread m_workerThread;
16 protected HttpListener m_httpListener;
17 protected Dictionary<string, RestMethod> m_restHandlers = new Dictionary<string, RestMethod>();
18 protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>();
19 protected int m_port;
20
21 public BaseHttpServer(int port)
22 {
23 m_port = port;
24 }
25
26 public bool AddRestHandler(string method, string path, RestMethod handler)
27 {
28 string methodKey = String.Format("{0}: {1}", method, path);
29
30 if (!this.m_restHandlers.ContainsKey(methodKey))
31 {
32 this.m_restHandlers.Add(methodKey, handler);
33 return true;
34 }
35
36 //must already have a handler for that path so return false
37 return false;
38 }
39
40 public bool AddXmlRPCHandler(string method, XmlRpcMethod handler)
41 {
42 if (!this.m_rpcHandlers.ContainsKey(method))
43 {
44 this.m_rpcHandlers.Add(method, handler);
45 return true;
46 }
47
48 //must already have a handler for that path so return false
49 return false;
50 }
51
52 protected virtual string ProcessXMLRPCMethod(string methodName, XmlRpcRequest request)
53 {
54 XmlRpcResponse response;
55
56 XmlRpcMethod method;
57 if( this.m_rpcHandlers.TryGetValue( methodName, out method ) )
58 {
59 response = method(request);
60 }
61 else
62 {
63 response = new XmlRpcResponse();
64 Hashtable unknownMethodError = new Hashtable();
65 unknownMethodError["reason"] = "XmlRequest"; ;
66 unknownMethodError["message"] = "Unknown Rpc request";
67 unknownMethodError["login"] = "false";
68 response.Value = unknownMethodError;
69 }
70
71 return XmlRpcResponseSerializer.Singleton.Serialize(response);
72 }
73
74 protected virtual string ParseREST(string request, string path, string method)
75 {
76 string response;
77 RestMethod handler;
78
79 string requestKey = String.Format("{0}: {1}", method, path);
80
81 string bestMatch = String.Empty;
82 foreach( string currentKey in m_restHandlers.Keys )
83 {
84 if( requestKey.StartsWith( currentKey ))
85 {
86 if(currentKey.Length > bestMatch.Length )
87 {
88 bestMatch = currentKey;
89 }
90 }
91 }
92
93 if (m_restHandlers.TryGetValue(bestMatch, out handler))
94 {
95 response = handler(request, path);
96
97 }
98 else
99 {
100 response = String.Empty;
101 }
102
103 return response;
104 }
105
106 protected virtual string ParseLLSDXML(string requestBody)
107 {
108 // dummy function for now - IMPLEMENT ME!
109 return "";
110 }
111
112 protected virtual string ParseXMLRPC(string requestBody)
113 {
114 string responseString = String.Empty;
115
116 try
117 {
118 XmlRpcRequest request = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody);
119
120 string methodName = request.MethodName;
121
122 responseString = ProcessXMLRPCMethod(methodName, request );
123 }
124 catch (Exception e)
125 {
126 Console.WriteLine(e.ToString());
127 }
128 return responseString;
129 }
130
131 public virtual void HandleRequest(Object stateinfo)
132 {
133 HttpListenerContext context = (HttpListenerContext)stateinfo;
134
135 HttpListenerRequest request = context.Request;
136 HttpListenerResponse response = context.Response;
137
138 response.KeepAlive = false;
139 response.SendChunked = false;
140
141 System.IO.Stream body = request.InputStream;
142 System.Text.Encoding encoding = System.Text.Encoding.UTF8;
143 System.IO.StreamReader reader = new System.IO.StreamReader(body, encoding);
144
145 string requestBody = reader.ReadToEnd();
146 body.Close();
147 reader.Close();
148
149 //Console.WriteLine(request.HttpMethod + " " + request.RawUrl + " Http/" + request.ProtocolVersion.ToString() + " content type: " + request.ContentType);
150 //Console.WriteLine(requestBody);
151
152 string responseString = "";
153 switch (request.ContentType)
154 {
155 case "text/xml":
156 // must be XML-RPC, so pass to the XML-RPC parser
157
158 responseString = ParseXMLRPC(requestBody);
159 responseString = Regex.Replace(responseString, "utf-16", "utf-8");
160
161 response.AddHeader("Content-type", "text/xml");
162 break;
163
164 case "application/xml":
165 // probably LLSD we hope, otherwise it should be ignored by the parser
166 responseString = ParseLLSDXML(requestBody);
167 response.AddHeader("Content-type", "application/xml");
168 break;
169
170 case "application/x-www-form-urlencoded":
171 // a form data POST so send to the REST parser
172 responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
173 response.AddHeader("Content-type", "text/html");
174 break;
175
176 case null:
177 // must be REST or invalid crap, so pass to the REST parser
178 responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
179 response.AddHeader("Content-type", "text/html");
180 break;
181
182 }
183
184 byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
185 System.IO.Stream output = response.OutputStream;
186 response.SendChunked = false;
187 response.ContentLength64 = buffer.Length;
188 output.Write(buffer, 0, buffer.Length);
189 output.Close();
190 }
191
192 public void Start()
193 {
194 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("BaseHttpServer.cs: Starting up HTTP Server");
195
196 m_workerThread = new Thread(new ThreadStart(StartHTTP));
197 m_workerThread.IsBackground = true;
198 m_workerThread.Start();
199 }
200
201 private void StartHTTP()
202 {
203 try
204 {
205 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("BaseHttpServer.cs: StartHTTP() - Spawned main thread OK");
206 m_httpListener = new HttpListener();
207
208 m_httpListener.Prefixes.Add("http://+:" + m_port + "/");
209 m_httpListener.Start();
210
211 HttpListenerContext context;
212 while (true)
213 {
214 context = m_httpListener.GetContext();
215 ThreadPool.QueueUserWorkItem(new WaitCallback(HandleRequest), context);
216 }
217 }
218 catch (Exception e)
219 {
220 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(e.Message);
221 }
222 }
223 }
224}