From 0ea73384d4506c83bcd9f721a13fd5be11d1cc33 Mon Sep 17 00:00:00 2001
From: Dr Scofield
Date: Fri, 18 Jul 2008 15:31:28 +0000
Subject: simplifying OSHTtpHandler (a bit), adding query string matching,
adapting OSHttpXmlRpcHandler accordingly.
NOTE: this code is not live.
---
OpenSim/Framework/Servers/OSHttpHandler.cs | 22 ++--
OpenSim/Framework/Servers/OSHttpRequestPump.cs | 137 ++++++++++++-----------
OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs | 79 +++++++------
3 files changed, 118 insertions(+), 120 deletions(-)
diff --git a/OpenSim/Framework/Servers/OSHttpHandler.cs b/OpenSim/Framework/Servers/OSHttpHandler.cs
index 8b65438..6e8f6fb 100644
--- a/OpenSim/Framework/Servers/OSHttpHandler.cs
+++ b/OpenSim/Framework/Servers/OSHttpHandler.cs
@@ -93,6 +93,16 @@ namespace OpenSim.Framework.Servers
protected Regex _path;
///
+ /// Dictionary of (query name, regular expression) tuples,
+ /// allowing us to match on URI query fields.
+ ///
+ public virtual Dictionary Query
+ {
+ get { return _query; }
+ }
+ protected Dictionary _query;
+
+ ///
/// Dictionary of (header name, regular expression) tuples,
/// allowing us to match on HTTP header fields.
///
@@ -119,18 +129,6 @@ namespace OpenSim.Framework.Servers
///
- /// An OSHttpHandler that matches on the "content-type" header can
- /// supply an OSHttpContentTypeChecker delegate which will be
- /// invoked by the request matcher in OSHttpRequestPump.
- ///
- /// true if the handler is interested in the content;
- /// false otherwise
- internal virtual OSHttpContentTypeChecker ContentTypeChecker
- {
- get { return null; }
- }
-
- ///
/// Base class constructor.
///
/// null or path regex
diff --git a/OpenSim/Framework/Servers/OSHttpRequestPump.cs b/OpenSim/Framework/Servers/OSHttpRequestPump.cs
index d05e706..8d4dc0d 100644
--- a/OpenSim/Framework/Servers/OSHttpRequestPump.cs
+++ b/OpenSim/Framework/Servers/OSHttpRequestPump.cs
@@ -175,18 +175,13 @@ namespace OpenSim.Framework.Servers
_log.DebugFormat("[{0}] MatchHandlers for {1}", EngineID, req);
foreach (OSHttpHandler h in handlers)
{
- Regex methodRegex = h.Method;
- Regex pathRegex = h.Path;
- Dictionary headerRegexs = h.Headers;
- Regex endPointsRegex = h.IPEndPointWhitelist;
-
// initial anchor
scoredHandlers[h] = 0;
// first, check whether IPEndPointWhitelist applies
// and, if it does, whether client is on that white
// list.
- if (null != endPointsRegex)
+ if (null != h.IPEndPointWhitelist)
{
// TODO: following code requires code changes to
// HttpServer.HttpRequest to become functional
@@ -194,84 +189,65 @@ namespace OpenSim.Framework.Servers
IPEndPoint remote = req.RemoteIPEndPoint;
if (null != remote)
{
- Match epm = endPointsRegex.Match(remote.ToString());
- if (!epm.Success) continue;
+ Match epm = h.IPEndPointWhitelist.Match(remote.ToString());
+ if (!epm.Success)
+ {
+ scoredHandlers.Remove(h);
+ continue;
+ }
}
}
- if (null != methodRegex)
+ if (null != h.Method)
{
- Match m = methodRegex.Match(req.HttpMethod);
- if (!m.Success) continue;
-
+ Match m = h.Method.Match(req.HttpMethod);
+ if (!m.Success)
+ {
+ scoredHandlers.Remove(h);
+ continue;
+ }
scoredHandlers[h]++;
}
// whitelist ok, now check path
- if (null != pathRegex)
+ if (null != h.Path)
{
- Match m = pathRegex.Match(req.RawUrl);
- if (!m.Success) continue;
-
- scoredHandlers[h] = m.ToString().Length;
+ Match m = h.Path.Match(req.RawUrl);
+ if (!m.Success)
+ {
+ scoredHandlers.Remove(h);
+ continue;
+ }
+ scoredHandlers[h] += m.ToString().Length;
}
- // whitelist & path ok, now check headers
- if (null != headerRegexs)
+ // whitelist & path ok, now check query string
+ if (null != h.Query)
{
- int headersMatch = 0;
-
- // 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)
+ int queriesMatch = MatchOnNameValueCollection(req.QueryString, h.Query);
+ if (0 == queriesMatch)
{
- // do we have a header "tag"?
- if (null == headers[tag])
- {
- // no: remove the handler if it was added
- // earlier and on to the next one
- _log.DebugFormat("[{0}] dropping handler for {1}: null {2} header field: {3}", EngineID, req, tag, h);
+ _log.DebugFormat("[{0}] request {1}", EngineID, req);
+ _log.DebugFormat("[{0}] dropping handler {1}", EngineID, h);
- scoredHandlers.Remove(h);
- break;
- }
-
- // does the content of header "tag" match
- // the supplied regex?
- Match hm = headerRegexs[tag].Match(headers[tag]);
- if (!hm.Success) {
- // no: remove the handler if it was added
- // earlier and on to the next one
- _log.DebugFormat("[{0}] dropping handler for {1}: {2} header field content \"{3}\" does not match regex {4}: {5}",
- EngineID, req, tag, headers[tag], headerRegexs[tag].ToString(), h);
- scoredHandlers.Remove(h);
- break;
- }
-
- // if we are looking at the "content-type" tag,
- // check wether h has a ContentTypeChecker and
- // invoke it if it has
- if ((null != h.ContentTypeChecker) && !h.ContentTypeChecker(req))
- {
- scoredHandlers.Remove(h);
- _log.DebugFormat("[{0}] dropping handler for {1}: content checker returned false: {2}", EngineID, req, h);
- break;
- }
-
- // ok: header matches
- headersMatch++;
- _log.DebugFormat("[{0}] MatchHandlers: found handler for {1}: {2}", EngineID, req, h.ToString());
+ scoredHandlers.Remove(h);
continue;
}
- // check whether h got kicked out
- if (!scoredHandlers.ContainsKey(h)) continue;
+ scoredHandlers[h] += queriesMatch;
+ }
+
+ // whitelist, path, query string ok, now check headers
+ if (null != h.Headers)
+ {
+ int headersMatch = MatchOnNameValueCollection(req.Headers, h.Headers);
+ if (0 == headersMatch)
+ {
+ _log.DebugFormat("[{0}] request {1}", EngineID, req);
+ _log.DebugFormat("[{0}] dropping handler {1}", EngineID, h);
+ scoredHandlers.Remove(h);
+ continue;
+ }
scoredHandlers[h] += headersMatch;
}
}
@@ -285,6 +261,33 @@ namespace OpenSim.Framework.Servers
return matchingHandlers;
}
+ protected int MatchOnNameValueCollection(NameValueCollection collection, Dictionary regexs)
+ {
+ int matched = 0;
+
+ foreach (string tag in regexs.Keys)
+ {
+ // do we have a header "tag"?
+ if (null == collection[tag])
+ {
+ return 0;
+ }
+
+ // does the content of collection[tag] match
+ // the supplied regex?
+ Match cm = regexs[tag].Match(collection[tag]);
+ if (!cm.Success) {
+ return 0;
+ }
+
+ // ok: matches
+ matched++;
+ continue;
+ }
+
+ return matched;
+ }
+
[ConditionalAttribute("DEBUGGING")]
private void LogDumpHandlerList(List l)
{
diff --git a/OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs b/OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs
index f9ce5b1..2c31cfd 100644
--- a/OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs
+++ b/OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs
@@ -51,48 +51,42 @@ namespace OpenSim.Framework.Servers
///
/// true if the handler is interested in the content;
/// false otherwise
- internal override OSHttpContentTypeChecker ContentTypeChecker
- {
- get
- {
- return delegate(OSHttpRequest req)
+ protected bool XmlRpcMethodMatch(OSHttpRequest req)
+ {
+ XmlRpcRequest xmlRpcRequest = null;
+
+ // check whether req is already reified
+ // if not: reify (and post to whiteboard)
+ try
+ {
+ if (req.Whiteboard.ContainsKey("xmlrequest"))
{
- XmlRpcRequest xmlRpcRequest = null;
-
- // check whether req is already reified
- // if not: reify (and post to whiteboard)
- try
- {
- if (req.Whiteboard.ContainsKey("xmlrequest"))
- {
- xmlRpcRequest = req.Whiteboard["xmlrequest"] as XmlRpcRequest;
- }
- else
- {
- StreamReader body = new StreamReader(req.InputStream);
- string requestBody = body.ReadToEnd();
- xmlRpcRequest = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody);
- req.Whiteboard["xmlrequest"] = xmlRpcRequest;
- }
- }
- catch (XmlException)
- {
- _log.ErrorFormat("[OSHttpXmlRpcHandler] failed to deserialize XmlRpcRequest from {0}", req.ToString());
- return false;
- }
-
- // check against methodName
- if ((null != xmlRpcRequest)
- && !String.IsNullOrEmpty(xmlRpcRequest.MethodName)
- && xmlRpcRequest.MethodName == _methodName)
- {
- _log.DebugFormat("[OSHttpXmlRpcHandler] located handler {0} for {1}", _methodName, req.ToString());
- return true;
- }
-
- return false;
- };
+ xmlRpcRequest = req.Whiteboard["xmlrequest"] as XmlRpcRequest;
+ }
+ else
+ {
+ StreamReader body = new StreamReader(req.InputStream);
+ string requestBody = body.ReadToEnd();
+ xmlRpcRequest = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody);
+ req.Whiteboard["xmlrequest"] = xmlRpcRequest;
+ }
+ }
+ catch (XmlException)
+ {
+ _log.ErrorFormat("[OSHttpXmlRpcHandler] failed to deserialize XmlRpcRequest from {0}", req.ToString());
+ return false;
}
+
+ // check against methodName
+ if ((null != xmlRpcRequest)
+ && !String.IsNullOrEmpty(xmlRpcRequest.MethodName)
+ && xmlRpcRequest.MethodName == _methodName)
+ {
+ _log.DebugFormat("[OSHttpXmlRpcHandler] located handler {0} for {1}", _methodName, req.ToString());
+ return true;
+ }
+
+ return false;
}
// contains handler for processing XmlRpc Request
@@ -149,8 +143,11 @@ namespace OpenSim.Framework.Servers
XmlRpcResponse xmlRpcResponse;
string responseString;
+ // check whether we are interested in this request
+ if (!XmlRpcMethodMatch(request)) return OSHttpHandlerResult.Pass;
+
+
OSHttpResponse resp = new OSHttpResponse(request);
-
try
{
// reified XmlRpcRequest must still be on the whiteboard
--
cgit v1.1