From 8b3cb93b49b21b7729adc56a9c06658fb94b1e8f Mon Sep 17 00:00:00 2001 From: lbsa71 Date: Wed, 4 Jul 2007 04:29:23 +0000 Subject: [PATCH] * Started work on converting BaseHttpServer to a stream dispatcher --- OpenSim/Framework/Servers/BaseHttpServer.cs | 174 +++++++++++------- OpenSim/Framework/Servers/IStreamHandler.cs | 12 ++ .../Servers/OpenSim.Framework.Servers.csproj | 40 ++-- .../Framework/Servers/RestStreamHandler.cs | 15 ++ 4 files changed, 160 insertions(+), 81 deletions(-) create mode 100644 OpenSim/Framework/Servers/IStreamHandler.cs create mode 100644 OpenSim/Framework/Servers/RestStreamHandler.cs diff --git a/OpenSim/Framework/Servers/BaseHttpServer.cs b/OpenSim/Framework/Servers/BaseHttpServer.cs index 713793cf6c..81028b05d4 100644 --- a/OpenSim/Framework/Servers/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/BaseHttpServer.cs @@ -65,6 +65,7 @@ namespace OpenSim.Framework.Servers protected HttpListener m_httpListener; protected Dictionary m_restHandlers = new Dictionary(); protected Dictionary m_rpcHandlers = new Dictionary(); + protected Dictionary m_streamHandlers = new Dictionary(); protected int m_port; protected bool firstcaps = true; @@ -73,9 +74,14 @@ namespace OpenSim.Framework.Servers m_port = port; } + private void AddStreamHandler(string path, IStreamHandler handler) + { + m_streamHandlers.Add(path, handler); + } + public bool AddRestHandler(string method, string path, RestMethod handler) { - //Console.WriteLine("adding new REST handler for path " + path); + //Console.WriteLine("adding new REST handler for path " + path); string methodKey = String.Format("{0}: {1}", method, path); if (!this.m_restHandlers.ContainsKey(methodKey)) @@ -190,73 +196,113 @@ namespace OpenSim.Framework.Servers public virtual void HandleRequest(Object stateinfo) { - try + HttpListenerContext context = (HttpListenerContext)stateinfo; + + HttpListenerRequest request = context.Request; + HttpListenerResponse response = context.Response; + + response.KeepAlive = false; + response.SendChunked = false; + + string path = request.RawUrl; + + IStreamHandler streamHandler; + + if(TryGetStreamHandler(path, out streamHandler)) { - HttpListenerContext context = (HttpListenerContext)stateinfo; - - HttpListenerRequest request = context.Request; - HttpListenerResponse response = context.Response; - - response.KeepAlive = false; - response.SendChunked = false; - - Stream body = request.InputStream; - Encoding encoding = Encoding.UTF8; - StreamReader reader = new StreamReader(body, encoding); - - string requestBody = reader.ReadToEnd(); - body.Close(); - reader.Close(); - - //Console.WriteLine(request.HttpMethod + " " + request.RawUrl + " Http/" + request.ProtocolVersion.ToString() + " content type: " + request.ContentType); - //Console.WriteLine(requestBody); - - string responseString = ""; - // Console.WriteLine("new request " + request.ContentType +" at "+ request.RawUrl); - switch (request.ContentType) - { - case "text/xml": - // must be XML-RPC, so pass to the XML-RPC parser - - responseString = ParseXMLRPC(requestBody); - responseString = Regex.Replace(responseString, "utf-16", "utf-8"); - - response.AddHeader("Content-type", "text/xml"); - break; - - case "application/xml": - case "application/octet-stream": - // probably LLSD we hope, otherwise it should be ignored by the parser - // responseString = ParseLLSDXML(requestBody); - responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); - response.AddHeader("Content-type", "application/xml"); - break; - - case "application/x-www-form-urlencoded": - // a form data POST so send to the REST parser - responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); - response.AddHeader("Content-type", "text/html"); - break; - - case null: - // must be REST or invalid crap, so pass to the REST parser - responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); - response.AddHeader("Content-type", "text/html"); - break; + streamHandler.Handle(path, request.InputStream, response.OutputStream ); + } + else + { + HandleLegacyRequests(request, response); + } + } + private bool TryGetStreamHandler(string path, out IStreamHandler streamHandler ) + { + string bestMatch = null; + + foreach (string pattern in m_streamHandlers.Keys) + { + if (path.StartsWith(pattern)) + { + if (String.IsNullOrEmpty( bestMatch ) || pattern.Length > bestMatch.Length) + { + bestMatch = pattern; + } } + } - byte[] buffer = Encoding.UTF8.GetBytes(responseString); - Stream output = response.OutputStream; - response.SendChunked = false; - response.ContentLength64 = buffer.Length; - output.Write(buffer, 0, buffer.Length); - output.Close(); - } - catch (Exception e) + if( String.IsNullOrEmpty( bestMatch ) ) { - //Console.WriteLine(e.ToString()); + streamHandler = null; + return false; } + else + { + streamHandler = m_streamHandlers[bestMatch]; + return true; + } + } + + private void HandleLegacyRequests(HttpListenerRequest request, HttpListenerResponse response) + { + Stream body = request.InputStream; + + Encoding encoding = Encoding.UTF8; + StreamReader reader = new StreamReader(body, encoding); + + string requestBody = reader.ReadToEnd(); + body.Close(); + reader.Close(); + + //Console.WriteLine(request.HttpMethod + " " + request.RawUrl + " Http/" + request.ProtocolVersion.ToString() + " content type: " + request.ContentType); + //Console.WriteLine(requestBody); + + string responseString = ""; + // Console.WriteLine("new request " + request.ContentType +" at "+ request.RawUrl); + switch (request.ContentType) + { + case "text/xml": + // must be XML-RPC, so pass to the XML-RPC parser + + responseString = ParseXMLRPC(requestBody); + responseString = Regex.Replace(responseString, "utf-16", "utf-8"); + + response.AddHeader("Content-type", "text/xml"); + break; + + case "application/xml": + case "application/octet-stream": + // probably LLSD we hope, otherwise it should be ignored by the parser + // responseString = ParseLLSDXML(requestBody); + responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); + response.AddHeader("Content-type", "application/xml"); + break; + + case "application/x-www-form-urlencoded": + // a form data POST so send to the REST parser + responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); + response.AddHeader("Content-type", "text/html"); + break; + + case null: + // must be REST or invalid crap, so pass to the REST parser + responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); + response.AddHeader("Content-type", "text/html"); + break; + + } + + byte[] buffer = Encoding.UTF8.GetBytes(responseString); + Stream output = response.OutputStream; + response.SendChunked = false; + response.ContentLength64 = buffer.Length; + + + + output.Write(buffer, 0, buffer.Length); + output.Close(); } public void Start() @@ -291,9 +337,5 @@ namespace OpenSim.Framework.Servers } } - public void AddLlsdMethod(string path, LlsdMethod handler ) - { - throw new Exception("The method or operation is not implemented."); - } } } diff --git a/OpenSim/Framework/Servers/IStreamHandler.cs b/OpenSim/Framework/Servers/IStreamHandler.cs new file mode 100644 index 0000000000..88ae641dbb --- /dev/null +++ b/OpenSim/Framework/Servers/IStreamHandler.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace OpenSim.Framework.Servers +{ + public interface IStreamHandler + { + void Handle(string path, Stream request, Stream response); + } +} diff --git a/OpenSim/Framework/Servers/OpenSim.Framework.Servers.csproj b/OpenSim/Framework/Servers/OpenSim.Framework.Servers.csproj index 909bd622b6..956a9bc7a6 100644 --- a/OpenSim/Framework/Servers/OpenSim.Framework.Servers.csproj +++ b/OpenSim/Framework/Servers/OpenSim.Framework.Servers.csproj @@ -1,4 +1,4 @@ - + Local 8.0.50727 @@ -6,7 +6,8 @@ {2CC71860-0000-0000-0000-000000000000} Debug AnyCPU - + + OpenSim.Framework.Servers @@ -15,9 +16,11 @@ IE50 false Library - + + OpenSim.Framework.Servers - + + @@ -28,7 +31,8 @@ TRACE;DEBUG - + + True 4096 False @@ -37,7 +41,8 @@ False False 4 - + + False @@ -46,7 +51,8 @@ TRACE - + + False 4096 True @@ -55,22 +61,24 @@ False False 4 - + + - + ..\..\..\bin\libsecondlife.dll False - + System.dll False - + + System.Xml.dll False - + ..\..\..\bin\XMLRPC.dll False @@ -80,13 +88,13 @@ OpenSim.Framework {8ACA2445-0000-0000-0000-000000000000} {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - False + False OpenSim.Framework.Console {A7CD0630-0000-0000-0000-000000000000} {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - False + False @@ -99,12 +107,14 @@ Code + Code Code + Code @@ -119,4 +129,4 @@ - + \ No newline at end of file diff --git a/OpenSim/Framework/Servers/RestStreamHandler.cs b/OpenSim/Framework/Servers/RestStreamHandler.cs new file mode 100644 index 0000000000..145a184e4a --- /dev/null +++ b/OpenSim/Framework/Servers/RestStreamHandler.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace OpenSim.Framework.Servers +{ + public class RestStreamHandler : IStreamHandler + { + public void Handle( string path, Stream request, Stream response ) + { + + } + } +}