diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 527d02cb7a..36801a2647 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -618,24 +618,35 @@ namespace OpenSim.Framework.Servers.HttpServer Culture.SetCurrentCulture(); -// // This is the REST agent interface. We require an agent to properly identify -// // itself. If the REST handler recognizes the prefix it will attempt to -// // satisfy the request. If it is not recognizable, and no damage has occurred -// // the request can be passed through to the other handlers. This is a low -// // probability event; if a request is matched it is normally expected to be -// // handled -// IHttpAgentHandler agentHandler; -// -// if (TryGetAgentHandler(request, response, out agentHandler)) -// { -// if (HandleAgentRequest(agentHandler, request, response)) -// { -// requestEndTick = Environment.TickCount; -// return; -// } -// } + // // This is the REST agent interface. We require an agent to properly identify + // // itself. If the REST handler recognizes the prefix it will attempt to + // // satisfy the request. If it is not recognizable, and no damage has occurred + // // the request can be passed through to the other handlers. This is a low + // // probability event; if a request is matched it is normally expected to be + // // handled + // IHttpAgentHandler agentHandler; + // + // if (TryGetAgentHandler(request, response, out agentHandler)) + // { + // if (HandleAgentRequest(agentHandler, request, response)) + // { + // requestEndTick = Environment.TickCount; + // return; + // } + // } + string path = request.UriPath; + if (!string.IsNullOrWhiteSpace(path) && TryGetSimpleStreamHandler(path, out ISimpleStreamHandler hdr)) + { + hdr.Handle(request, response); + if (request.InputStream != null && request.InputStream.CanRead) + request.InputStream.Dispose(); - string path = request.RawUrl; + requestEndTick = Environment.TickCount; + response.Send(); + return; + } + + path = request.RawUrl; string handlerKey = GetHandlerKey(request.HttpMethod, path); byte[] buffer = null; diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs index 62d92fb1ea..75b5a79013 100644 --- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs @@ -88,4 +88,17 @@ namespace OpenSim.Framework.Servers.HttpServer { Hashtable Handle(string path, Hashtable request); } + + public interface ISimpleStreamHandler + { + string Name { get; } + string Description { get; } + string Path { get; } + + int RequestsReceived { get; } + int RequestsHandled { get; } + + // Handle request stream, return byte array + void Handle(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse); + } } \ No newline at end of file diff --git a/OpenSim/Framework/Servers/HttpServer/SimpleBaseRequestHandler.cs b/OpenSim/Framework/Servers/HttpServer/SimpleBaseRequestHandler.cs new file mode 100644 index 0000000000..6e0ec5a397 --- /dev/null +++ b/OpenSim/Framework/Servers/HttpServer/SimpleBaseRequestHandler.cs @@ -0,0 +1,89 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; + +namespace OpenSim.Framework.Servers.HttpServer +{ + /// + /// simple Base streamed request handler + /// for well defined simple uri paths, any http method + /// + public abstract class SimpleBaseRequestHandler + { + public int RequestsReceived { get; protected set; } + + public int RequestsHandled { get; protected set; } + + private readonly string m_path; + + public string Name { get; private set; } + + public string Description { get; private set; } + + protected SimpleBaseRequestHandler(string path) : this(path, null, null) { } + + protected SimpleBaseRequestHandler(string path, string name, string description) + { + Name = name; + Description = description; + m_path = path; + } + + public string Path + { + get { return m_path; } + } + + public string GetParam(string path) + { + if (CheckParam(path)) + { + return path.Substring(m_path.Length); + } + + return string.Empty; + } + + protected bool CheckParam(string path) + { + if (string.IsNullOrEmpty(path)) + { + return false; + } + + return path.StartsWith(Path); + } + + public string[] SplitParams(string path) + { + string param = GetParam(path); + + return param.Split(new char[] { '/', '?', '&' }, StringSplitOptions.RemoveEmptyEntries); + } + } +} \ No newline at end of file diff --git a/OpenSim/Framework/Servers/HttpServer/SimpleStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/SimpleStreamHandler.cs new file mode 100644 index 0000000000..5b5a6de8c2 --- /dev/null +++ b/OpenSim/Framework/Servers/HttpServer/SimpleStreamHandler.cs @@ -0,0 +1,85 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System.IO; +using System.Net; +using OpenSim.Framework.ServiceAuth; + +namespace OpenSim.Framework.Servers.HttpServer +{ + /// + /// simple Base streamed request handler. + /// for well defined simple uri paths, any http method + /// + /// + /// Inheriting classes should override ProcessRequest() rather than Handle() + /// + public abstract class SimpleStreamHandler : SimpleBaseRequestHandler, ISimpleStreamHandler + { + protected IServiceAuth m_Auth; + + protected SimpleStreamHandler(string path) : this(path, null, null) { } + + protected SimpleStreamHandler(string path, string name, string description) + : base(path, name, description) { } + + protected SimpleStreamHandler(string path, IServiceAuth auth) + : base(path, null, null) + { + m_Auth = auth; + } + + protected SimpleStreamHandler(string path, IServiceAuth auth, string name, string description) + : base(path, name, description) + { + m_Auth = auth; + } + + public virtual void Handle(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + { + RequestsReceived++; + + if (m_Auth != null) + { + HttpStatusCode statusCode; + + if (!m_Auth.Authenticate(httpRequest.Headers, httpResponse.AddHeader, out statusCode)) + { + httpResponse.StatusCode = (int)statusCode; + return; + } + } + + ProcessRequest(httpRequest, httpResponse); + RequestsHandled++; + } + + protected virtual void ProcessRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + { + } + } +} \ No newline at end of file diff --git a/OpenSim/Tests/Common/Mock/TestOSHttpRequest.cs b/OpenSim/Tests/Common/Mock/TestOSHttpRequest.cs index e0330e7329..3925118291 100644 --- a/OpenSim/Tests/Common/Mock/TestOSHttpRequest.cs +++ b/OpenSim/Tests/Common/Mock/TestOSHttpRequest.cs @@ -186,6 +186,7 @@ namespace OpenSim.Tests.Common } public Uri Url { get; set; } + public string UriPath { get;} public string UserAgent {