status: work-in-progress, non-functional
fleshing out OSHttpRequestPump code.0.6.0-stable
parent
6175021300
commit
92e04ea587
|
@ -144,6 +144,11 @@ namespace OpenSim.Framework.Servers
|
||||||
get { return _queryString; }
|
get { return _queryString; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HttpRequest HttpRequest
|
||||||
|
{
|
||||||
|
get { return _request; }
|
||||||
|
}
|
||||||
|
|
||||||
public OSHttpRequest()
|
public OSHttpRequest()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading;
|
||||||
|
using log4net;
|
||||||
using HttpServer;
|
using HttpServer;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Servers
|
namespace OpenSim.Framework.Servers
|
||||||
|
@ -39,11 +46,29 @@ namespace OpenSim.Framework.Servers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class OSHttpRequestPump
|
public class OSHttpRequestPump
|
||||||
{
|
{
|
||||||
|
private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
protected OSHttpServer _server;
|
protected OSHttpServer _server;
|
||||||
protected OSHttpRequestQueue _queue;
|
protected OSHttpRequestQueue _queue;
|
||||||
|
protected Thread _engine;
|
||||||
|
|
||||||
|
private int _id;
|
||||||
|
|
||||||
|
public string EngineID
|
||||||
|
{
|
||||||
|
get { return String.Format("{0}-{1}", _server.EngineID, _id); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public OSHttpRequestPump()
|
public OSHttpRequestPump()
|
||||||
{
|
{
|
||||||
|
_engine = new Thread(new ThreadStart(Engine));
|
||||||
|
_engine.Name = EngineID;
|
||||||
|
_engine.IsBackground = true;
|
||||||
|
_engine.Start();
|
||||||
|
|
||||||
|
ThreadTracker.Add(_engine);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OSHttpRequestPump[] Pumps(OSHttpServer server, OSHttpRequestQueue queue, int poolSize)
|
public static OSHttpRequestPump[] Pumps(OSHttpServer server, OSHttpRequestQueue queue, int poolSize)
|
||||||
|
@ -53,9 +78,140 @@ namespace OpenSim.Framework.Servers
|
||||||
{
|
{
|
||||||
pumps[i]._server = server;
|
pumps[i]._server = server;
|
||||||
pumps[i]._queue = queue;
|
pumps[i]._queue = queue;
|
||||||
|
pumps[i]._id = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pumps;
|
return pumps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
_engine = new Thread(new ThreadStart(Engine));
|
||||||
|
_engine.Name = EngineID;
|
||||||
|
_engine.IsBackground = true;
|
||||||
|
_engine.Start();
|
||||||
|
|
||||||
|
ThreadTracker.Add(_engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Engine()
|
||||||
|
{
|
||||||
|
OSHttpRequest req = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
// get job to do
|
||||||
|
req = _queue.Dequeue();
|
||||||
|
|
||||||
|
// get list of registered handlers
|
||||||
|
List<OSHttpHandler> handlers = _server.OSHttpHandlers;
|
||||||
|
|
||||||
|
// prune list and sort from most specific to least
|
||||||
|
// specific
|
||||||
|
handlers = MatchHandlers(req, handlers);
|
||||||
|
|
||||||
|
// process req
|
||||||
|
foreach(OSHttpHandler h in handlers)
|
||||||
|
{
|
||||||
|
OSHttpHandlerResult rc = h.Process(req);
|
||||||
|
// handler did not process the request, try
|
||||||
|
// next handler
|
||||||
|
if (OSHttpHandlerResult.Pass == rc) continue;
|
||||||
|
// handler is taking over processing of
|
||||||
|
// request, we are done
|
||||||
|
if (OSHttpHandlerResult.Detached == rc) break;
|
||||||
|
|
||||||
|
// request was handled, we need to clean up
|
||||||
|
// TODO: cleanup :-)
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_log.DebugFormat("[{0}] something went wrong: {1}", EngineID, e.ToString());
|
||||||
|
_log.ErrorFormat("[{0}] something went wrong: {1}, terminating this pump", EngineID, e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<OSHttpHandler> MatchHandlers(OSHttpRequest req, List<OSHttpHandler> handlers)
|
||||||
|
{
|
||||||
|
Dictionary<OSHttpHandler, int> scoredHandlers = new Dictionary<OSHttpHandler, int>();
|
||||||
|
|
||||||
|
foreach (OSHttpHandler h in handlers)
|
||||||
|
{
|
||||||
|
Regex pathRegex = h.Path;
|
||||||
|
Dictionary<string, Regex> headerRegexs = h.Headers;
|
||||||
|
Regex endPointsRegex = h.IPEndPointWhitelist;
|
||||||
|
|
||||||
|
int pathMatch = 0;
|
||||||
|
int headersMatch = 0;
|
||||||
|
|
||||||
|
// first, check whether IPEndPointWhitelist applies
|
||||||
|
// and, if it does, whether client is on that white
|
||||||
|
// list.
|
||||||
|
if (null != endPointsRegex)
|
||||||
|
{
|
||||||
|
// TODO: following code requires code changes to
|
||||||
|
// HttpServer.HttpRequest
|
||||||
|
|
||||||
|
// IPEndPoint remote = HttpServer.HttpRequest.RemoteIPEndPoint;
|
||||||
|
// Match epm = endPointsRegex.Match(remote.ToString());
|
||||||
|
// if (!epm.Success) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// whitelist ok, now check path
|
||||||
|
if (null != pathRegex)
|
||||||
|
{
|
||||||
|
Match m = pathRegex.Match(req.HttpRequest.Uri.AbsolutePath);
|
||||||
|
if (!m.Success) continue;
|
||||||
|
|
||||||
|
scoredHandlers[h] = m.ToString().Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// whitelist & path ok, now check headers
|
||||||
|
if (null != headerRegexs)
|
||||||
|
{
|
||||||
|
// go through all header Regexs and evaluate
|
||||||
|
// match:
|
||||||
|
// if header field not present or does not match:
|
||||||
|
// remove handler from scoredHandlers
|
||||||
|
// continue
|
||||||
|
// else:
|
||||||
|
// add increment headersMatch
|
||||||
|
NameValueCollection headers = req.HttpRequest.Headers;
|
||||||
|
foreach (string tag in headerRegexs.Keys)
|
||||||
|
{
|
||||||
|
if (null != headers[tag])
|
||||||
|
{
|
||||||
|
Match hm = headerRegexs[tag].Match(headers[tag]);
|
||||||
|
if (hm.Success) {
|
||||||
|
headersMatch++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scoredHandlers.Remove(h);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// check whether h got kicked out
|
||||||
|
if (!scoredHandlers.ContainsKey(h)) continue;
|
||||||
|
|
||||||
|
scoredHandlers[h] += headersMatch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<OSHttpHandler> matchingHandlers = new List<OSHttpHandler>(scoredHandlers.Keys);
|
||||||
|
matchingHandlers.Sort(delegate(OSHttpHandler x, OSHttpHandler y)
|
||||||
|
{
|
||||||
|
return scoredHandlers[x] - scoredHandlers[y];
|
||||||
|
});
|
||||||
|
|
||||||
|
return matchingHandlers;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,6 +151,10 @@ namespace OpenSim.Framework.Servers
|
||||||
_engine.Start();
|
_engine.Start();
|
||||||
|
|
||||||
ThreadTracker.Add(_engine);
|
ThreadTracker.Add(_engine);
|
||||||
|
|
||||||
|
// start the pumps...
|
||||||
|
for (int i = 0; i < _pumps.Length; i++)
|
||||||
|
_pumps[i].Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
Loading…
Reference in New Issue