From 0d528e1d226283fa9acfafbd60b8a7461f509a85 Mon Sep 17 00:00:00 2001 From: lbsa71 Date: Wed, 31 Oct 2007 12:45:03 +0000 Subject: [PATCH] * Added a streamhandler that does streams both in and out * The RestDeserialisehandler now does streams and returns an object instead of string --- OpenSim/Framework/Servers/BaseHttpServer.cs | 34 +++++++++++++----- .../Framework/Servers/BaseRequestHandler.cs | 35 +++++++++++++++++++ .../Framework/Servers/BaseStreamHandler.cs | 30 ++-------------- OpenSim/Framework/Servers/IStreamHandler.cs | 18 +++++++--- .../Servers/RestDeserialiseHandler.cs | 30 ++++++++-------- OpenSim/Region/Application/OpenSimMain.cs | 2 +- 6 files changed, 93 insertions(+), 56 deletions(-) create mode 100644 OpenSim/Framework/Servers/BaseRequestHandler.cs diff --git a/OpenSim/Framework/Servers/BaseHttpServer.cs b/OpenSim/Framework/Servers/BaseHttpServer.cs index 52d2a2c376..a4a7b2b41c 100644 --- a/OpenSim/Framework/Servers/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/BaseHttpServer.cs @@ -43,7 +43,7 @@ namespace OpenSim.Framework.Servers protected Thread m_workerThread; protected HttpListener m_httpListener; protected Dictionary m_rpcHandlers = new Dictionary(); - protected Dictionary m_streamHandlers = new Dictionary(); + protected Dictionary m_streamHandlers = new Dictionary(); protected int m_port; protected bool m_firstcaps = true; @@ -57,7 +57,7 @@ namespace OpenSim.Framework.Servers m_port = port; } - public void AddStreamHandler(IStreamHandler handler) + public void AddStreamHandler(IRequestHandler handler) { string httpMethod = handler.HttpMethod; string path = handler.Path; @@ -97,14 +97,32 @@ namespace OpenSim.Framework.Servers string path = request.RawUrl; string handlerKey = GetHandlerKey(request.HttpMethod, path); - IStreamHandler streamHandler; + IRequestHandler requestHandler; - if (TryGetStreamHandler(handlerKey, out streamHandler)) + if (TryGetStreamHandler(handlerKey, out requestHandler)) { - byte[] buffer = streamHandler.Handle(path, request.InputStream); - request.InputStream.Close(); + // Okay, so this is bad, but should be considered temporary until everything is IStreamHandler. + byte[] buffer; + if (requestHandler is IStreamedRequestHandler) + { + IStreamedRequestHandler streamedRequestHandler = requestHandler as IStreamedRequestHandler; + buffer = streamedRequestHandler.Handle(path, request.InputStream); - response.ContentType = streamHandler.ContentType; + } + else + { + IStreamHandler streamHandler = (IStreamHandler)requestHandler; + + using (MemoryStream memoryStream = new MemoryStream()) + { + streamHandler.Handle(path, request.InputStream, memoryStream); + memoryStream.Flush(); + buffer = memoryStream.ToArray(); + } + } + + request.InputStream.Close(); + response.ContentType = requestHandler.ContentType; response.ContentLength64 = buffer.LongLength; response.OutputStream.Write(buffer, 0, buffer.Length); response.OutputStream.Close(); @@ -115,7 +133,7 @@ namespace OpenSim.Framework.Servers } } - private bool TryGetStreamHandler(string handlerKey, out IStreamHandler streamHandler) + private bool TryGetStreamHandler(string handlerKey, out IRequestHandler streamHandler) { string bestMatch = null; diff --git a/OpenSim/Framework/Servers/BaseRequestHandler.cs b/OpenSim/Framework/Servers/BaseRequestHandler.cs new file mode 100644 index 0000000000..b3577631f6 --- /dev/null +++ b/OpenSim/Framework/Servers/BaseRequestHandler.cs @@ -0,0 +1,35 @@ +namespace OpenSim.Framework.Servers +{ + public class BaseRequestHandler + { + public virtual string ContentType + { + get { return "application/xml"; } + } + + private readonly string m_httpMethod; + + public virtual string HttpMethod + { + get { return m_httpMethod; } + } + + private readonly string m_path; + + protected BaseRequestHandler(string httpMethod, string path) + { + m_httpMethod = httpMethod; + m_path = path; + } + + public virtual string Path + { + get { return m_path; } + } + + protected string GetParam(string path) + { + return path.Substring(m_path.Length); + } + } +} \ No newline at end of file diff --git a/OpenSim/Framework/Servers/BaseStreamHandler.cs b/OpenSim/Framework/Servers/BaseStreamHandler.cs index cd99183fdb..a17c6ec9ab 100644 --- a/OpenSim/Framework/Servers/BaseStreamHandler.cs +++ b/OpenSim/Framework/Servers/BaseStreamHandler.cs @@ -30,38 +30,12 @@ using System.IO; namespace OpenSim.Framework.Servers { - public abstract class BaseStreamHandler : IStreamHandler + public abstract class BaseStreamHandler : BaseRequestHandler, IStreamedRequestHandler { - public virtual string ContentType - { - get { return "application/xml"; } - } - - private string m_httpMethod; - - public virtual string HttpMethod - { - get { return m_httpMethod; } - } - - private string m_path; - - public virtual string Path - { - get { return m_path; } - } - - protected string GetParam(string path) - { - return path.Substring(m_path.Length); - } - public abstract byte[] Handle(string path, Stream request); - protected BaseStreamHandler(string httpMethod, string path) + protected BaseStreamHandler(string httpMethod, string path) : base(httpMethod, path) { - m_httpMethod = httpMethod; - m_path = path; } } } \ No newline at end of file diff --git a/OpenSim/Framework/Servers/IStreamHandler.cs b/OpenSim/Framework/Servers/IStreamHandler.cs index d674172532..6dc7189e1d 100644 --- a/OpenSim/Framework/Servers/IStreamHandler.cs +++ b/OpenSim/Framework/Servers/IStreamHandler.cs @@ -30,11 +30,8 @@ using System.IO; namespace OpenSim.Framework.Servers { - public interface IStreamHandler + public interface IRequestHandler { - // Handle request stream, return byte array - byte[] Handle(string path, Stream request); - // Return response content type string ContentType { get; } @@ -44,4 +41,17 @@ namespace OpenSim.Framework.Servers // Return path string Path { get; } } + + public interface IStreamedRequestHandler : IRequestHandler + { + // Handle request stream, return byte array + byte[] Handle(string path, Stream request); + } + + public interface IStreamHandler : IRequestHandler + { + // Handle request stream, return byte array + void Handle(string path, Stream request, Stream response); + } + } \ No newline at end of file diff --git a/OpenSim/Framework/Servers/RestDeserialiseHandler.cs b/OpenSim/Framework/Servers/RestDeserialiseHandler.cs index cb500cabec..28084e2917 100644 --- a/OpenSim/Framework/Servers/RestDeserialiseHandler.cs +++ b/OpenSim/Framework/Servers/RestDeserialiseHandler.cs @@ -7,35 +7,35 @@ using System.Xml.Serialization; namespace OpenSim.Framework.Servers { - public delegate string RestDeserialiseMethod(TRequest request); + public delegate TResponse RestDeserialiseMethod(TRequest request); - public class RestDeserialisehandler : BaseStreamHandler + public class RestDeserialisehandler : BaseRequestHandler, IStreamHandler where TRequest : new() { - private RestDeserialiseMethod m_method; + private RestDeserialiseMethod m_method; - public RestDeserialisehandler(string httpMethod, string path, RestDeserialiseMethod method) + public RestDeserialisehandler(string httpMethod, string path, RestDeserialiseMethod method) : base(httpMethod, path) { m_method = method; } - public override byte[] Handle(string path, Stream request) + public void Handle(string path, Stream request, Stream responseStream ) { - Type type = typeof(TRequest); - - TRequest deserial= default(TRequest); - using (XmlTextReader xreader = new XmlTextReader(request)) + TRequest deserial; + using (XmlTextReader xmlReader = new XmlTextReader(request)) { - XmlSerializer serializer = new XmlSerializer(type); - deserial = (TRequest)serializer.Deserialize(xreader); + XmlSerializer deserializer = new XmlSerializer(typeof(TRequest)); + deserial = (TRequest)deserializer.Deserialize(xmlReader); } - string response = m_method(deserial); - - Encoding encoding = new UTF8Encoding(false); - return encoding.GetBytes(response); + TResponse response = m_method(deserial); + using (XmlWriter xmlWriter = XmlTextWriter.Create( responseStream )) + { + XmlSerializer serializer = new XmlSerializer(typeof(TResponse)); + serializer.Serialize(xmlWriter, response ); + } } } } diff --git a/OpenSim/Region/Application/OpenSimMain.cs b/OpenSim/Region/Application/OpenSimMain.cs index 6be067f97f..aec9500197 100644 --- a/OpenSim/Region/Application/OpenSimMain.cs +++ b/OpenSim/Region/Application/OpenSimMain.cs @@ -415,7 +415,7 @@ namespace OpenSim return GetPhysicsScene(m_physicsEngine); } - private class SimStatusHandler : IStreamHandler + private class SimStatusHandler : IStreamedRequestHandler { public byte[] Handle(string path, Stream request) {