aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r--OpenSim/Framework/Servers/OSHttpHandler.cs22
-rw-r--r--OpenSim/Framework/Servers/OSHttpRequestPump.cs137
-rw-r--r--OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs79
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
93 protected Regex _path; 93 protected Regex _path;
94 94
95 /// <summary> 95 /// <summary>
96 /// Dictionary of (query name, regular expression) tuples,
97 /// allowing us to match on URI query fields.
98 /// </summary>
99 public virtual Dictionary<string, Regex> Query
100 {
101 get { return _query; }
102 }
103 protected Dictionary<string, Regex> _query;
104
105 /// <summary>
96 /// Dictionary of (header name, regular expression) tuples, 106 /// Dictionary of (header name, regular expression) tuples,
97 /// allowing us to match on HTTP header fields. 107 /// allowing us to match on HTTP header fields.
98 /// </summary> 108 /// </summary>
@@ -119,18 +129,6 @@ namespace OpenSim.Framework.Servers
119 129
120 130
121 /// <summary> 131 /// <summary>
122 /// An OSHttpHandler that matches on the "content-type" header can
123 /// supply an OSHttpContentTypeChecker delegate which will be
124 /// invoked by the request matcher in OSHttpRequestPump.
125 /// </summary>
126 /// <returns>true if the handler is interested in the content;
127 /// false otherwise</returns>
128 internal virtual OSHttpContentTypeChecker ContentTypeChecker
129 {
130 get { return null; }
131 }
132
133 /// <summary>
134 /// Base class constructor. 132 /// Base class constructor.
135 /// </summary> 133 /// </summary>
136 /// <param name="path">null or path regex</param> 134 /// <param name="path">null or path regex</param>
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
175 _log.DebugFormat("[{0}] MatchHandlers for {1}", EngineID, req); 175 _log.DebugFormat("[{0}] MatchHandlers for {1}", EngineID, req);
176 foreach (OSHttpHandler h in handlers) 176 foreach (OSHttpHandler h in handlers)
177 { 177 {
178 Regex methodRegex = h.Method;
179 Regex pathRegex = h.Path;
180 Dictionary<string, Regex> headerRegexs = h.Headers;
181 Regex endPointsRegex = h.IPEndPointWhitelist;
182
183 // initial anchor 178 // initial anchor
184 scoredHandlers[h] = 0; 179 scoredHandlers[h] = 0;
185 180
186 // first, check whether IPEndPointWhitelist applies 181 // first, check whether IPEndPointWhitelist applies
187 // and, if it does, whether client is on that white 182 // and, if it does, whether client is on that white
188 // list. 183 // list.
189 if (null != endPointsRegex) 184 if (null != h.IPEndPointWhitelist)
190 { 185 {
191 // TODO: following code requires code changes to 186 // TODO: following code requires code changes to
192 // HttpServer.HttpRequest to become functional 187 // HttpServer.HttpRequest to become functional
@@ -194,84 +189,65 @@ namespace OpenSim.Framework.Servers
194 IPEndPoint remote = req.RemoteIPEndPoint; 189 IPEndPoint remote = req.RemoteIPEndPoint;
195 if (null != remote) 190 if (null != remote)
196 { 191 {
197 Match epm = endPointsRegex.Match(remote.ToString()); 192 Match epm = h.IPEndPointWhitelist.Match(remote.ToString());
198 if (!epm.Success) continue; 193 if (!epm.Success)
194 {
195 scoredHandlers.Remove(h);
196 continue;
197 }
199 } 198 }
200 } 199 }
201 200
202 if (null != methodRegex) 201 if (null != h.Method)
203 { 202 {
204 Match m = methodRegex.Match(req.HttpMethod); 203 Match m = h.Method.Match(req.HttpMethod);
205 if (!m.Success) continue; 204 if (!m.Success)
206 205 {
206 scoredHandlers.Remove(h);
207 continue;
208 }
207 scoredHandlers[h]++; 209 scoredHandlers[h]++;
208 } 210 }
209 211
210 // whitelist ok, now check path 212 // whitelist ok, now check path
211 if (null != pathRegex) 213 if (null != h.Path)
212 { 214 {
213 Match m = pathRegex.Match(req.RawUrl); 215 Match m = h.Path.Match(req.RawUrl);
214 if (!m.Success) continue; 216 if (!m.Success)
215 217 {
216 scoredHandlers[h] = m.ToString().Length; 218 scoredHandlers.Remove(h);
219 continue;
220 }
221 scoredHandlers[h] += m.ToString().Length;
217 } 222 }
218 223
219 // whitelist & path ok, now check headers 224 // whitelist & path ok, now check query string
220 if (null != headerRegexs) 225 if (null != h.Query)
221 { 226 {
222 int headersMatch = 0; 227 int queriesMatch = MatchOnNameValueCollection(req.QueryString, h.Query);
223 228 if (0 == queriesMatch)
224 // go through all header Regexs and evaluate
225 // match:
226 // if header field not present or does not match:
227 // remove handler from scoredHandlers
228 // continue
229 // else:
230 // add increment headersMatch
231 NameValueCollection headers = req.HttpRequest.Headers;
232 foreach (string tag in headerRegexs.Keys)
233 { 229 {
234 // do we have a header "tag"? 230 _log.DebugFormat("[{0}] request {1}", EngineID, req);
235 if (null == headers[tag]) 231 _log.DebugFormat("[{0}] dropping handler {1}", EngineID, h);
236 {
237 // no: remove the handler if it was added
238 // earlier and on to the next one
239 _log.DebugFormat("[{0}] dropping handler for {1}: null {2} header field: {3}", EngineID, req, tag, h);
240 232
241 scoredHandlers.Remove(h); 233 scoredHandlers.Remove(h);
242 break;
243 }
244
245 // does the content of header "tag" match
246 // the supplied regex?
247 Match hm = headerRegexs[tag].Match(headers[tag]);
248 if (!hm.Success) {
249 // no: remove the handler if it was added
250 // earlier and on to the next one
251 _log.DebugFormat("[{0}] dropping handler for {1}: {2} header field content \"{3}\" does not match regex {4}: {5}",
252 EngineID, req, tag, headers[tag], headerRegexs[tag].ToString(), h);
253 scoredHandlers.Remove(h);
254 break;
255 }
256
257 // if we are looking at the "content-type" tag,
258 // check wether h has a ContentTypeChecker and
259 // invoke it if it has
260 if ((null != h.ContentTypeChecker) && !h.ContentTypeChecker(req))
261 {
262 scoredHandlers.Remove(h);
263 _log.DebugFormat("[{0}] dropping handler for {1}: content checker returned false: {2}", EngineID, req, h);
264 break;
265 }
266
267 // ok: header matches
268 headersMatch++;
269 _log.DebugFormat("[{0}] MatchHandlers: found handler for {1}: {2}", EngineID, req, h.ToString());
270 continue; 234 continue;
271 } 235 }
272 // check whether h got kicked out 236 scoredHandlers[h] += queriesMatch;
273 if (!scoredHandlers.ContainsKey(h)) continue; 237 }
238
239 // whitelist, path, query string ok, now check headers
240 if (null != h.Headers)
241 {
242 int headersMatch = MatchOnNameValueCollection(req.Headers, h.Headers);
243 if (0 == headersMatch)
244 {
245 _log.DebugFormat("[{0}] request {1}", EngineID, req);
246 _log.DebugFormat("[{0}] dropping handler {1}", EngineID, h);
274 247
248 scoredHandlers.Remove(h);
249 continue;
250 }
275 scoredHandlers[h] += headersMatch; 251 scoredHandlers[h] += headersMatch;
276 } 252 }
277 } 253 }
@@ -285,6 +261,33 @@ namespace OpenSim.Framework.Servers
285 return matchingHandlers; 261 return matchingHandlers;
286 } 262 }
287 263
264 protected int MatchOnNameValueCollection(NameValueCollection collection, Dictionary<string, Regex> regexs)
265 {
266 int matched = 0;
267
268 foreach (string tag in regexs.Keys)
269 {
270 // do we have a header "tag"?
271 if (null == collection[tag])
272 {
273 return 0;
274 }
275
276 // does the content of collection[tag] match
277 // the supplied regex?
278 Match cm = regexs[tag].Match(collection[tag]);
279 if (!cm.Success) {
280 return 0;
281 }
282
283 // ok: matches
284 matched++;
285 continue;
286 }
287
288 return matched;
289 }
290
288 [ConditionalAttribute("DEBUGGING")] 291 [ConditionalAttribute("DEBUGGING")]
289 private void LogDumpHandlerList(List<OSHttpHandler> l) 292 private void LogDumpHandlerList(List<OSHttpHandler> l)
290 { 293 {
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
51 /// </summary> 51 /// </summary>
52 /// <returns>true if the handler is interested in the content; 52 /// <returns>true if the handler is interested in the content;
53 /// false otherwise</returns> 53 /// false otherwise</returns>
54 internal override OSHttpContentTypeChecker ContentTypeChecker 54 protected bool XmlRpcMethodMatch(OSHttpRequest req)
55 { 55 {
56 get 56 XmlRpcRequest xmlRpcRequest = null;
57 { 57
58 return delegate(OSHttpRequest req) 58 // check whether req is already reified
59 // if not: reify (and post to whiteboard)
60 try
61 {
62 if (req.Whiteboard.ContainsKey("xmlrequest"))
59 { 63 {
60 XmlRpcRequest xmlRpcRequest = null; 64 xmlRpcRequest = req.Whiteboard["xmlrequest"] as XmlRpcRequest;
61 65 }
62 // check whether req is already reified 66 else
63 // if not: reify (and post to whiteboard) 67 {
64 try 68 StreamReader body = new StreamReader(req.InputStream);
65 { 69 string requestBody = body.ReadToEnd();
66 if (req.Whiteboard.ContainsKey("xmlrequest")) 70 xmlRpcRequest = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody);
67 { 71 req.Whiteboard["xmlrequest"] = xmlRpcRequest;
68 xmlRpcRequest = req.Whiteboard["xmlrequest"] as XmlRpcRequest; 72 }
69 } 73 }
70 else 74 catch (XmlException)
71 { 75 {
72 StreamReader body = new StreamReader(req.InputStream); 76 _log.ErrorFormat("[OSHttpXmlRpcHandler] failed to deserialize XmlRpcRequest from {0}", req.ToString());
73 string requestBody = body.ReadToEnd(); 77 return false;
74 xmlRpcRequest = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody);
75 req.Whiteboard["xmlrequest"] = xmlRpcRequest;
76 }
77 }
78 catch (XmlException)
79 {
80 _log.ErrorFormat("[OSHttpXmlRpcHandler] failed to deserialize XmlRpcRequest from {0}", req.ToString());
81 return false;
82 }
83
84 // check against methodName
85 if ((null != xmlRpcRequest)
86 && !String.IsNullOrEmpty(xmlRpcRequest.MethodName)
87 && xmlRpcRequest.MethodName == _methodName)
88 {
89 _log.DebugFormat("[OSHttpXmlRpcHandler] located handler {0} for {1}", _methodName, req.ToString());
90 return true;
91 }
92
93 return false;
94 };
95 } 78 }
79
80 // check against methodName
81 if ((null != xmlRpcRequest)
82 && !String.IsNullOrEmpty(xmlRpcRequest.MethodName)
83 && xmlRpcRequest.MethodName == _methodName)
84 {
85 _log.DebugFormat("[OSHttpXmlRpcHandler] located handler {0} for {1}", _methodName, req.ToString());
86 return true;
87 }
88
89 return false;
96 } 90 }
97 91
98 // contains handler for processing XmlRpc Request 92 // contains handler for processing XmlRpc Request
@@ -149,8 +143,11 @@ namespace OpenSim.Framework.Servers
149 XmlRpcResponse xmlRpcResponse; 143 XmlRpcResponse xmlRpcResponse;
150 string responseString; 144 string responseString;
151 145
146 // check whether we are interested in this request
147 if (!XmlRpcMethodMatch(request)) return OSHttpHandlerResult.Pass;
148
149
152 OSHttpResponse resp = new OSHttpResponse(request); 150 OSHttpResponse resp = new OSHttpResponse(request);
153
154 try 151 try
155 { 152 {
156 // reified XmlRpcRequest must still be on the whiteboard 153 // reified XmlRpcRequest must still be on the whiteboard