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; }
|
||||
}
|
||||
|
||||
public HttpRequest HttpRequest
|
||||
{
|
||||
get { return _request; }
|
||||
}
|
||||
|
||||
public OSHttpRequest()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -26,6 +26,13 @@
|
|||
*/
|
||||
|
||||
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;
|
||||
|
||||
namespace OpenSim.Framework.Servers
|
||||
|
@ -39,11 +46,29 @@ namespace OpenSim.Framework.Servers
|
|||
/// </summary>
|
||||
public class OSHttpRequestPump
|
||||
{
|
||||
private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected OSHttpServer _server;
|
||||
protected OSHttpRequestQueue _queue;
|
||||
protected Thread _engine;
|
||||
|
||||
private int _id;
|
||||
|
||||
public string EngineID
|
||||
{
|
||||
get { return String.Format("{0}-{1}", _server.EngineID, _id); }
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
|
@ -53,9 +78,140 @@ namespace OpenSim.Framework.Servers
|
|||
{
|
||||
pumps[i]._server = server;
|
||||
pumps[i]._queue = queue;
|
||||
pumps[i]._id = i;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
ThreadTracker.Add(_engine);
|
||||
|
||||
// start the pumps...
|
||||
for (int i = 0; i < _pumps.Length; i++)
|
||||
_pumps[i].Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
Loading…
Reference in New Issue