aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Servers/BaseHttpServer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Servers/BaseHttpServer.cs')
-rw-r--r--OpenSim/Framework/Servers/BaseHttpServer.cs164
1 files changed, 103 insertions, 61 deletions
diff --git a/OpenSim/Framework/Servers/BaseHttpServer.cs b/OpenSim/Framework/Servers/BaseHttpServer.cs
index 713793c..81028b0 100644
--- a/OpenSim/Framework/Servers/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/BaseHttpServer.cs
@@ -65,6 +65,7 @@ namespace OpenSim.Framework.Servers
65 protected HttpListener m_httpListener; 65 protected HttpListener m_httpListener;
66 protected Dictionary<string, RestMethodEntry> m_restHandlers = new Dictionary<string, RestMethodEntry>(); 66 protected Dictionary<string, RestMethodEntry> m_restHandlers = new Dictionary<string, RestMethodEntry>();
67 protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>(); 67 protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>();
68 protected Dictionary<string, IStreamHandler> m_streamHandlers = new Dictionary<string, IStreamHandler>();
68 protected int m_port; 69 protected int m_port;
69 protected bool firstcaps = true; 70 protected bool firstcaps = true;
70 71
@@ -73,9 +74,14 @@ namespace OpenSim.Framework.Servers
73 m_port = port; 74 m_port = port;
74 } 75 }
75 76
77 private void AddStreamHandler(string path, IStreamHandler handler)
78 {
79 m_streamHandlers.Add(path, handler);
80 }
81
76 public bool AddRestHandler(string method, string path, RestMethod handler) 82 public bool AddRestHandler(string method, string path, RestMethod handler)
77 { 83 {
78 //Console.WriteLine("adding new REST handler for path " + path); 84 //Console.WriteLine("adding new REST handler for path " + path);
79 string methodKey = String.Format("{0}: {1}", method, path); 85 string methodKey = String.Format("{0}: {1}", method, path);
80 86
81 if (!this.m_restHandlers.ContainsKey(methodKey)) 87 if (!this.m_restHandlers.ContainsKey(methodKey))
@@ -190,75 +196,115 @@ namespace OpenSim.Framework.Servers
190 196
191 public virtual void HandleRequest(Object stateinfo) 197 public virtual void HandleRequest(Object stateinfo)
192 { 198 {
193 try 199 HttpListenerContext context = (HttpListenerContext)stateinfo;
194 {
195 HttpListenerContext context = (HttpListenerContext)stateinfo;
196 200
197 HttpListenerRequest request = context.Request; 201 HttpListenerRequest request = context.Request;
198 HttpListenerResponse response = context.Response; 202 HttpListenerResponse response = context.Response;
199 203
200 response.KeepAlive = false; 204 response.KeepAlive = false;
201 response.SendChunked = false; 205 response.SendChunked = false;
202 206
203 Stream body = request.InputStream; 207 string path = request.RawUrl;
204 Encoding encoding = Encoding.UTF8;
205 StreamReader reader = new StreamReader(body, encoding);
206 208
207 string requestBody = reader.ReadToEnd(); 209 IStreamHandler streamHandler;
208 body.Close();
209 reader.Close();
210 210
211 //Console.WriteLine(request.HttpMethod + " " + request.RawUrl + " Http/" + request.ProtocolVersion.ToString() + " content type: " + request.ContentType); 211 if(TryGetStreamHandler(path, out streamHandler))
212 //Console.WriteLine(requestBody); 212 {
213 213 streamHandler.Handle(path, request.InputStream, response.OutputStream );
214 string responseString = ""; 214 }
215 // Console.WriteLine("new request " + request.ContentType +" at "+ request.RawUrl); 215 else
216 switch (request.ContentType) 216 {
217 { 217 HandleLegacyRequests(request, response);
218 case "text/xml": 218 }
219 // must be XML-RPC, so pass to the XML-RPC parser 219 }
220
221 responseString = ParseXMLRPC(requestBody);
222 responseString = Regex.Replace(responseString, "utf-16", "utf-8");
223
224 response.AddHeader("Content-type", "text/xml");
225 break;
226
227 case "application/xml":
228 case "application/octet-stream":
229 // probably LLSD we hope, otherwise it should be ignored by the parser
230 // responseString = ParseLLSDXML(requestBody);
231 responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
232 response.AddHeader("Content-type", "application/xml");
233 break;
234
235 case "application/x-www-form-urlencoded":
236 // a form data POST so send to the REST parser
237 responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
238 response.AddHeader("Content-type", "text/html");
239 break;
240
241 case null:
242 // must be REST or invalid crap, so pass to the REST parser
243 responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
244 response.AddHeader("Content-type", "text/html");
245 break;
246 220
221 private bool TryGetStreamHandler(string path, out IStreamHandler streamHandler )
222 {
223 string bestMatch = null;
224
225 foreach (string pattern in m_streamHandlers.Keys)
226 {
227 if (path.StartsWith(pattern))
228 {
229 if (String.IsNullOrEmpty( bestMatch ) || pattern.Length > bestMatch.Length)
230 {
231 bestMatch = pattern;
232 }
247 } 233 }
234 }
248 235
249 byte[] buffer = Encoding.UTF8.GetBytes(responseString); 236 if( String.IsNullOrEmpty( bestMatch ) )
250 Stream output = response.OutputStream; 237 {
251 response.SendChunked = false; 238 streamHandler = null;
252 response.ContentLength64 = buffer.Length; 239 return false;
253 output.Write(buffer, 0, buffer.Length);
254 output.Close();
255 } 240 }
256 catch (Exception e) 241 else
257 { 242 {
258 //Console.WriteLine(e.ToString()); 243 streamHandler = m_streamHandlers[bestMatch];
244 return true;
259 } 245 }
260 } 246 }
261 247
248 private void HandleLegacyRequests(HttpListenerRequest request, HttpListenerResponse response)
249 {
250 Stream body = request.InputStream;
251
252 Encoding encoding = Encoding.UTF8;
253 StreamReader reader = new StreamReader(body, encoding);
254
255 string requestBody = reader.ReadToEnd();
256 body.Close();
257 reader.Close();
258
259 //Console.WriteLine(request.HttpMethod + " " + request.RawUrl + " Http/" + request.ProtocolVersion.ToString() + " content type: " + request.ContentType);
260 //Console.WriteLine(requestBody);
261
262 string responseString = "";
263 // Console.WriteLine("new request " + request.ContentType +" at "+ request.RawUrl);
264 switch (request.ContentType)
265 {
266 case "text/xml":
267 // must be XML-RPC, so pass to the XML-RPC parser
268
269 responseString = ParseXMLRPC(requestBody);
270 responseString = Regex.Replace(responseString, "utf-16", "utf-8");
271
272 response.AddHeader("Content-type", "text/xml");
273 break;
274
275 case "application/xml":
276 case "application/octet-stream":
277 // probably LLSD we hope, otherwise it should be ignored by the parser
278 // responseString = ParseLLSDXML(requestBody);
279 responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
280 response.AddHeader("Content-type", "application/xml");
281 break;
282
283 case "application/x-www-form-urlencoded":
284 // a form data POST so send to the REST parser
285 responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
286 response.AddHeader("Content-type", "text/html");
287 break;
288
289 case null:
290 // must be REST or invalid crap, so pass to the REST parser
291 responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
292 response.AddHeader("Content-type", "text/html");
293 break;
294
295 }
296
297 byte[] buffer = Encoding.UTF8.GetBytes(responseString);
298 Stream output = response.OutputStream;
299 response.SendChunked = false;
300 response.ContentLength64 = buffer.Length;
301
302
303
304 output.Write(buffer, 0, buffer.Length);
305 output.Close();
306 }
307
262 public void Start() 308 public void Start()
263 { 309 {
264 MainLog.Instance.WriteLine(LogPriority.LOW, "BaseHttpServer.cs: Starting up HTTP Server"); 310 MainLog.Instance.WriteLine(LogPriority.LOW, "BaseHttpServer.cs: Starting up HTTP Server");
@@ -291,9 +337,5 @@ namespace OpenSim.Framework.Servers
291 } 337 }
292 } 338 }
293 339
294 public void AddLlsdMethod<TResponse, TRequest>(string path, LlsdMethod<TResponse, TRequest> handler )
295 {
296 throw new Exception("The method or operation is not implemented.");
297 }
298 } 340 }
299} 341}