diff --git a/OpenSim/Framework/Servers/OSHttpRequest.cs b/OpenSim/Framework/Servers/OSHttpRequest.cs index d733f3daab..530c91a6d9 100644 --- a/OpenSim/Framework/Servers/OSHttpRequest.cs +++ b/OpenSim/Framework/Servers/OSHttpRequest.cs @@ -30,11 +30,15 @@ using System.Collections.Specialized; using System.Net; using System.IO; using System.Text; +using HttpServer; namespace OpenSim.Framework.Servers { public class OSHttpRequest { + /// + /// soon to be deprecated + /// private string[] _acceptTypes; private Encoding _contentEncoding; private long _contentLength64; @@ -52,6 +56,9 @@ namespace OpenSim.Framework.Servers private NameValueCollection _queryString; private string _userAgent; + private HttpRequest _request; + private HttpClientContext _context; + public string[] AcceptTypes { get { return _acceptTypes; } @@ -160,5 +167,11 @@ namespace OpenSim.Framework.Servers _queryString = req.QueryString; _userAgent = req.UserAgent; } + + public OSHttpRequest(HttpClientContext context, HttpRequest req) + { + _context = context; + _request = req; + } } } diff --git a/OpenSim/Framework/Servers/OSHttpRequestPump.cs b/OpenSim/Framework/Servers/OSHttpRequestPump.cs index 8a3e73f8cb..06e41e468c 100644 --- a/OpenSim/Framework/Servers/OSHttpRequestPump.cs +++ b/OpenSim/Framework/Servers/OSHttpRequestPump.cs @@ -31,25 +31,28 @@ using HttpServer; namespace OpenSim.Framework.Servers { /// - /// OSHttpServer provides an HTTP server bound to a specific - /// port. When instantiated with just address and port it uses - /// normal HTTP, when instantiated with address, port, and X509 - /// certificate, it uses HTTPS. + /// An OSHttpRequestPump fetches incoming OSHttpRequest objects + /// from the OSHttpRequestQueue and feeds them to all subscribed + /// parties. Each OSHttpRequestPump encapsulates one thread to do + /// the work and there is a fixed number of pumps for each + /// OSHttpServer object. /// public class OSHttpRequestPump { - protected OSHttpServer _httpServer; + protected OSHttpServer _server; + protected OSHttpRequestQueue _queue; public OSHttpRequestPump() { } - public static OSHttpRequestPump[] Pumps(OSHttpServer server, int poolSize) + public static OSHttpRequestPump[] Pumps(OSHttpServer server, OSHttpRequestQueue queue, int poolSize) { OSHttpRequestPump[] pumps = new OSHttpRequestPump[poolSize]; for (int i = 0; i < pumps.Length; i++) { - pumps[i]._httpServer = server; + pumps[i]._server = server; + pumps[i]._queue = queue; } return pumps; diff --git a/OpenSim/Framework/Servers/OSHttpRequestQueue.cs b/OpenSim/Framework/Servers/OSHttpRequestQueue.cs new file mode 100644 index 0000000000..f3dfda472e --- /dev/null +++ b/OpenSim/Framework/Servers/OSHttpRequestQueue.cs @@ -0,0 +1,66 @@ +/* + * 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 OpenSim 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; +using System.Collections.Generic; +using System.Threading; +using HttpServer; + +namespace OpenSim.Framework.Servers +{ + /// + /// OSHttpRequestQueues are used to hand over incoming HTTP + /// requests to OSHttpRequestPump objects. + /// + public class OSHttpRequestQueue : Queue + { + new public void Enqueue(OSHttpRequest req) + { + lock (this) + { + base.Enqueue(req); + Monitor.Pulse(this); + } + } + + new public OSHttpRequest Dequeue() + { + OSHttpRequest req = null; + + lock (this) + { + while (null == req) + { + Monitor.Wait(this); + if (0 != this.Count) req = base.Dequeue(); + } + } + + return req; + } + } +} \ No newline at end of file diff --git a/OpenSim/Framework/Servers/OSHttpServer.cs b/OpenSim/Framework/Servers/OSHttpServer.cs index 3aa8042a86..296f853c57 100644 --- a/OpenSim/Framework/Servers/OSHttpServer.cs +++ b/OpenSim/Framework/Servers/OSHttpServer.cs @@ -50,8 +50,12 @@ namespace OpenSim.Framework.Servers // underlying HttpServer.HttpListener protected HttpListener _listener; + // underlying core/engine thread protected Thread _engine; + // Queue containing (OS)HttpRequests + protected OSHttpRequestQueue _queue; + // OSHttpRequestPumps "pumping" incoming OSHttpRequests // upwards protected OSHttpRequestPump[] _pumps; @@ -72,6 +76,11 @@ namespace OpenSim.Framework.Servers get { return _isSecure; } } + public int QueueSize + { + get { return _pumps.Length; } + } + /// /// Instantiate an HTTP server. /// @@ -80,17 +89,37 @@ namespace OpenSim.Framework.Servers _engineId = String.Format("OSHttpServer [HTTP:{0}/ps:{1}]", port, poolSize); _isSecure = false; - _pumps = OSHttpRequestPump.Pumps(this, poolSize); + _listener = new HttpListener(address, port); + _queue = new OSHttpRequestQueue(); + _pumps = OSHttpRequestPump.Pumps(this, _queue, poolSize); } /// /// Instantiate an HTTPS server. /// - public OSHttpServer(IPAddress address, int port, X509Certificate certificate, int poolSize) : - this(address, port, poolSize) + public OSHttpServer(IPAddress address, int port, X509Certificate certificate, int poolSize) { _engineId = String.Format("OSHttpServer [HTTPS:{0}/ps:{1}]", port, poolSize); _isSecure = true; + + _listener = new HttpListener(address, port, certificate); + _queue = new OSHttpRequestQueue(); + _pumps = OSHttpRequestPump.Pumps(this, _queue, poolSize); + } + + /// + /// Turn an HttpRequest into an OSHttpRequestItem and place it + /// in the queue. The OSHttpRequestQueue object will pulse the + /// next available idle pump. + /// + protected void OnHttpRequest(HttpClientContext client, HttpRequest request) + { + // turn request into OSHttpRequest + OSHttpRequest req = new OSHttpRequest(client, request); + + // place OSHttpRequest into _httpRequestQueue, will + // trigger Pulse to idle waiting pumps + _queue.Enqueue(req); } /// @@ -102,6 +131,7 @@ namespace OpenSim.Framework.Servers _engine.Name = _engineId; _engine.IsBackground = true; _engine.Start(); + ThreadTracker.Add(_engine); } @@ -111,9 +141,12 @@ namespace OpenSim.Framework.Servers { while (true) { - // do stuff + _listener.RequestHandler += OnHttpRequest; + _listener.Start(QueueSize); } } + + } }