aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/Servers/OSHttpHandler.cs99
-rw-r--r--OpenSim/Framework/Servers/OSHttpRequestPump.cs58
-rw-r--r--OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs60
3 files changed, 108 insertions, 109 deletions
diff --git a/OpenSim/Framework/Servers/OSHttpHandler.cs b/OpenSim/Framework/Servers/OSHttpHandler.cs
index a9f42f3..8b65438 100644
--- a/OpenSim/Framework/Servers/OSHttpHandler.cs
+++ b/OpenSim/Framework/Servers/OSHttpHandler.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO;
30using System.Text.RegularExpressions; 31using System.Text.RegularExpressions;
31 32
32namespace OpenSim.Framework.Servers 33namespace OpenSim.Framework.Servers
@@ -43,16 +44,10 @@ namespace OpenSim.Framework.Servers
43 /// <description>handler did not process the request</request> 44 /// <description>handler did not process the request</request>
44 /// </item> 45 /// </item>
45 /// <item> 46 /// <item>
46 /// <term>Handled</term> 47 /// <term>Done</term>
47 /// <description>handler did process the request, OSHttpServer 48 /// <description>handler did process the request, OSHttpServer
48 /// can clean up and close the request</request> 49 /// can clean up and close the request</request>
49 /// </item> 50 /// </item>
50 /// <item>
51 /// <term>Detached</term>
52 /// <description>handler handles the request, OSHttpServer
53 /// can forget about the request and should not touch it as
54 /// the handler has taken control</request>
55 /// </item>
56 /// </list> 51 /// </list>
57 /// </summary> 52 /// </summary>
58 public enum OSHttpHandlerResult 53 public enum OSHttpHandlerResult
@@ -71,26 +66,41 @@ namespace OpenSim.Framework.Servers
71 /// false otherwise</returns> 66 /// false otherwise</returns>
72 public delegate bool OSHttpContentTypeChecker(OSHttpRequest req); 67 public delegate bool OSHttpContentTypeChecker(OSHttpRequest req);
73 68
74 public interface OSHttpHandler 69 public abstract class OSHttpHandler
75 { 70 {
76 /// <summary> 71 /// <summary>
77 /// Regular expression used to match against path of incoming 72 /// Regular expression used to match against method of
78 /// HTTP request. If you want to match any string either use 73 /// the incoming HTTP request. If you want to match any string
79 /// '.*' or null. To match for the emtpy string use '^$' 74 /// either use '.*' or null. To match on the empty string use
75 /// '^$'.
80 /// </summary> 76 /// </summary>
81 Regex Path 77 public virtual Regex Method
82 { 78 {
83 get; 79 get { return _method; }
84 } 80 }
81 protected Regex _method;
82
83 /// <summary>
84 /// Regular expression used to match against path of the
85 /// incoming HTTP request. If you want to match any string
86 /// either use '.*' or null. To match on the emtpy string use
87 /// '^$'.
88 /// </summary>
89 public virtual Regex Path
90 {
91 get { return _path; }
92 }
93 protected Regex _path;
85 94
86 /// <summary> 95 /// <summary>
87 /// Dictionary of (header name, regular expression) tuples, 96 /// Dictionary of (header name, regular expression) tuples,
88 /// allowing us to match on HTTP header fields. 97 /// allowing us to match on HTTP header fields.
89 /// </summary> 98 /// </summary>
90 Dictionary<string, Regex> Headers 99 public virtual Dictionary<string, Regex> Headers
91 { 100 {
92 get; 101 get { return _headers; }
93 } 102 }
103 protected Dictionary<string, Regex> _headers;
94 104
95 /// <summary> 105 /// <summary>
96 /// Dictionary of (header name, regular expression) tuples, 106 /// Dictionary of (header name, regular expression) tuples,
@@ -101,10 +111,11 @@ namespace OpenSim.Framework.Servers
101 /// (trivial) changes to HttpServer.HttpListener that have not 111 /// (trivial) changes to HttpServer.HttpListener that have not
102 /// been implemented. 112 /// been implemented.
103 /// </remarks> 113 /// </remarks>
104 Regex IPEndPointWhitelist 114 public virtual Regex IPEndPointWhitelist
105 { 115 {
106 get; 116 get { return _ipEndPointRegex; }
107 } 117 }
118 protected Regex _ipEndPointRegex;
108 119
109 120
110 /// <summary> 121 /// <summary>
@@ -114,11 +125,59 @@ namespace OpenSim.Framework.Servers
114 /// </summary> 125 /// </summary>
115 /// <returns>true if the handler is interested in the content; 126 /// <returns>true if the handler is interested in the content;
116 /// false otherwise</returns> 127 /// false otherwise</returns>
117 OSHttpContentTypeChecker ContentTypeChecker 128 internal virtual OSHttpContentTypeChecker ContentTypeChecker
118 { 129 {
119 get; 130 get { return null; }
131 }
132
133 /// <summary>
134 /// Base class constructor.
135 /// </summary>
136 /// <param name="path">null or path regex</param>
137 /// <param name="headers">null or dictionary of header
138 /// regexs</param>
139 /// <param name="contentType">null or content type
140 /// regex</param>
141 /// <param name="whitelist">null or IP address regex</param>
142 public OSHttpHandler(Regex method, Regex path, Dictionary<string, Regex> headers, Regex contentType, Regex whitelist)
143 {
144 _method = method;
145 _path = path;
146 _ipEndPointRegex = whitelist;
147
148 if (null == _headers && null != contentType)
149 {
150 _headers = new Dictionary<string, Regex>();
151 _headers.Add("content-type", contentType);
152 }
120 } 153 }
121 154
122 OSHttpHandlerResult Process(OSHttpRequest request); 155
156 /// <summary>
157 /// Process an incoming OSHttpRequest that matched our
158 /// requirements.
159 /// </summary>
160 /// <returns>
161 /// OSHttpHandlerResult.Pass if we are after all not
162 /// interested in the request; OSHttpHandlerResult.Done if we
163 /// did process the request.
164 /// </returns>
165 public abstract OSHttpHandlerResult Process(OSHttpRequest request);
166
167 public override string ToString()
168 {
169 StringWriter sw = new StringWriter();
170 sw.WriteLine("{0}", base.ToString());
171 sw.WriteLine(" method regex {0}", null == Method ? "null" : Method.ToString());
172 sw.WriteLine(" path regex {0}", null == Path ? "null": Path.ToString());
173 foreach (string tag in Headers.Keys)
174 {
175 sw.WriteLine(" header {0} : {1}", tag, Headers[tag].ToString());
176 }
177 sw.WriteLine(" IP whitelist {0}", null == IPEndPointWhitelist ? "null" : IPEndPointWhitelist.ToString());
178 sw.WriteLine();
179 sw.Close();
180 return sw.ToString();
181 }
123 } 182 }
124} \ No newline at end of file 183} \ No newline at end of file
diff --git a/OpenSim/Framework/Servers/OSHttpRequestPump.cs b/OpenSim/Framework/Servers/OSHttpRequestPump.cs
index be4c3ff..d05e706 100644
--- a/OpenSim/Framework/Servers/OSHttpRequestPump.cs
+++ b/OpenSim/Framework/Servers/OSHttpRequestPump.cs
@@ -175,6 +175,7 @@ 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;
178 Regex pathRegex = h.Path; 179 Regex pathRegex = h.Path;
179 Dictionary<string, Regex> headerRegexs = h.Headers; 180 Dictionary<string, Regex> headerRegexs = h.Headers;
180 Regex endPointsRegex = h.IPEndPointWhitelist; 181 Regex endPointsRegex = h.IPEndPointWhitelist;
@@ -198,10 +199,18 @@ namespace OpenSim.Framework.Servers
198 } 199 }
199 } 200 }
200 201
202 if (null != methodRegex)
203 {
204 Match m = methodRegex.Match(req.HttpMethod);
205 if (!m.Success) continue;
206
207 scoredHandlers[h]++;
208 }
209
201 // whitelist ok, now check path 210 // whitelist ok, now check path
202 if (null != pathRegex) 211 if (null != pathRegex)
203 { 212 {
204 Match m = pathRegex.Match(req.HttpRequest.Uri.AbsolutePath); 213 Match m = pathRegex.Match(req.RawUrl);
205 if (!m.Success) continue; 214 if (!m.Success) continue;
206 215
207 scoredHandlers[h] = m.ToString().Length; 216 scoredHandlers[h] = m.ToString().Length;
@@ -227,8 +236,7 @@ namespace OpenSim.Framework.Servers
227 { 236 {
228 // no: remove the handler if it was added 237 // no: remove the handler if it was added
229 // earlier and on to the next one 238 // earlier and on to the next one
230 _LogDumpOSHttpHandler(String.Format("[{0}] dropping handler for {1}: null {2} header field", 239 _log.DebugFormat("[{0}] dropping handler for {1}: null {2} header field: {3}", EngineID, req, tag, h);
231 EngineID, req, tag), h);
232 240
233 scoredHandlers.Remove(h); 241 scoredHandlers.Remove(h);
234 break; 242 break;
@@ -240,8 +248,8 @@ namespace OpenSim.Framework.Servers
240 if (!hm.Success) { 248 if (!hm.Success) {
241 // no: remove the handler if it was added 249 // no: remove the handler if it was added
242 // earlier and on to the next one 250 // earlier and on to the next one
243 _LogDumpOSHttpHandler(String.Format("[{0}] dropping handler for {1}: {2} header field content \"{3}\" does not match regex {4}", 251 _log.DebugFormat("[{0}] dropping handler for {1}: {2} header field content \"{3}\" does not match regex {4}: {5}",
244 EngineID, req, tag, headers[tag], headerRegexs[tag].ToString()), h); 252 EngineID, req, tag, headers[tag], headerRegexs[tag].ToString(), h);
245 scoredHandlers.Remove(h); 253 scoredHandlers.Remove(h);
246 break; 254 break;
247 } 255 }
@@ -252,14 +260,13 @@ namespace OpenSim.Framework.Servers
252 if ((null != h.ContentTypeChecker) && !h.ContentTypeChecker(req)) 260 if ((null != h.ContentTypeChecker) && !h.ContentTypeChecker(req))
253 { 261 {
254 scoredHandlers.Remove(h); 262 scoredHandlers.Remove(h);
255 _LogDumpOSHttpHandler(String.Format("[{0}] dropping handler for {1}: content checker returned false", 263 _log.DebugFormat("[{0}] dropping handler for {1}: content checker returned false: {2}", EngineID, req, h);
256 EngineID, req), h);
257 break; 264 break;
258 } 265 }
259 266
260 // ok: header matches 267 // ok: header matches
261 headersMatch++; 268 headersMatch++;
262 _LogDumpOSHttpHandler(String.Format("[{0}] MatchHandlers: found handler for {1}", EngineID, req), h); 269 _log.DebugFormat("[{0}] MatchHandlers: found handler for {1}: {2}", EngineID, req, h.ToString());
263 continue; 270 continue;
264 } 271 }
265 // check whether h got kicked out 272 // check whether h got kicked out
@@ -269,48 +276,21 @@ namespace OpenSim.Framework.Servers
269 } 276 }
270 } 277 }
271 278
272 foreach (OSHttpHandler hh in scoredHandlers.Keys)
273 {
274 _LogDumpOSHttpHandler("scoredHandlers:", hh);
275 }
276
277 List<OSHttpHandler> matchingHandlers = new List<OSHttpHandler>(scoredHandlers.Keys); 279 List<OSHttpHandler> matchingHandlers = new List<OSHttpHandler>(scoredHandlers.Keys);
278 _LogDumpOSHttpHandlerList("before sort: ", matchingHandlers);
279 matchingHandlers.Sort(delegate(OSHttpHandler x, OSHttpHandler y) 280 matchingHandlers.Sort(delegate(OSHttpHandler x, OSHttpHandler y)
280 { 281 {
281 return scoredHandlers[x] - scoredHandlers[y]; 282 return scoredHandlers[x] - scoredHandlers[y];
282 }); 283 });
283 284 LogDumpHandlerList(matchingHandlers);
284 _LogDumpOSHttpHandlerList("after sort: ", matchingHandlers);
285
286 return matchingHandlers; 285 return matchingHandlers;
287 } 286 }
288 287
289 [ConditionalAttribute("DEBUGGING")] 288 [ConditionalAttribute("DEBUGGING")]
290 private void _LogDumpOSHttpHandler(string msg, OSHttpHandler h) 289 private void LogDumpHandlerList(List<OSHttpHandler> l)
291 {
292 _log.Debug(msg);
293
294 StringWriter sw = new StringWriter();
295 sw.WriteLine("{0}", h.ToString());
296 sw.WriteLine(" path regex {0}", null == h.Path ? "null": h.Path.ToString());
297 foreach (string tag in h.Headers.Keys)
298 {
299 sw.WriteLine(" header[{0}] {1}", tag, h.Headers[tag].ToString());
300 }
301 sw.WriteLine(" IP whitelist {0}", null == h.IPEndPointWhitelist ? "null" : h.IPEndPointWhitelist.ToString());
302 sw.WriteLine();
303 sw.Close();
304
305 _log.Debug(sw.ToString());
306 }
307
308 [ConditionalAttribute("DEBUGGING")]
309 private void _LogDumpOSHttpHandlerList(string msg, List<OSHttpHandler> l)
310 { 290 {
311 _log.DebugFormat("OSHttpHandlerList dump: {0}", msg); 291 _log.DebugFormat("[{0}] OSHttpHandlerList dump:", EngineID);
312 foreach (OSHttpHandler h in l) 292 foreach (OSHttpHandler h in l)
313 _LogDumpOSHttpHandler("OSHttpHandler", h); 293 _log.DebugFormat(" ", h.ToString());
314 } 294 }
315 } 295 }
316} 296}
diff --git a/OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs b/OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs
index 4205547..f9ce5b1 100644
--- a/OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs
+++ b/OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs
@@ -45,49 +45,13 @@ namespace OpenSim.Framework.Servers
45 private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 /// <summary> 47 /// <summary>
48 /// Regular expression used to match against path of incoming
49 /// HTTP request. If you want to match any string either use
50 /// '.*' or null. To match for the emtpy string use '^$'
51 /// </summary>
52 public Regex Path
53 {
54 get { return _pathsRegex; }
55 }
56 private Regex _pathsRegex;
57
58 /// <summary>
59 /// Dictionary of (header name, regular expression) tuples,
60 /// allowing us to match on HTTP header fields.
61 /// </summary>
62 public Dictionary<string, Regex> Headers
63 {
64 get { return _headers; }
65 }
66 private Dictionary<string, Regex> _headers;
67
68 /// <summary>
69 /// Regex to whitelist IP end points. A null value disables
70 /// checking of IP end points.
71 /// </summary>
72 /// <remarks>
73 /// This feature is currently not implemented as it requires
74 /// (trivial) changes to HttpServer.HttpListener that have not
75 /// been implemented.
76 /// </remarks>
77 public Regex IPEndPointWhitelist
78 {
79 get { return _ipEndPointRegex; }
80 }
81 private Regex _ipEndPointRegex;
82
83 /// <summary>
84 /// An OSHttpHandler that matches on the "content-type" header can 48 /// An OSHttpHandler that matches on the "content-type" header can
85 /// supply an OSHttpContentTypeChecker delegate which will be 49 /// supply an OSHttpContentTypeChecker delegate which will be
86 /// invoked by the request matcher in OSHttpRequestPump. 50 /// invoked by the request matcher in OSHttpRequestPump.
87 /// </summary> 51 /// </summary>
88 /// <returns>true if the handler is interested in the content; 52 /// <returns>true if the handler is interested in the content;
89 /// false otherwise</returns> 53 /// false otherwise</returns>
90 public OSHttpContentTypeChecker ContentTypeChecker 54 internal override OSHttpContentTypeChecker ContentTypeChecker
91 { 55 {
92 get 56 get
93 { 57 {
@@ -132,7 +96,7 @@ namespace OpenSim.Framework.Servers
132 } 96 }
133 97
134 // contains handler for processing XmlRpc Request 98 // contains handler for processing XmlRpc Request
135 private OSHttpXmlRpcProcessor _handler; 99 private XmlRpcMethod _handler;
136 100
137 // contains XmlRpc method name 101 // contains XmlRpc method name
138 private string _methodName; 102 private string _methodName;
@@ -141,7 +105,7 @@ namespace OpenSim.Framework.Servers
141 /// <summary> 105 /// <summary>
142 /// Instantiate an XmlRpc handler. 106 /// Instantiate an XmlRpc handler.
143 /// </summary> 107 /// </summary>
144 /// <param name="handler">OSHttpXmlRpcProcessor 108 /// <param name="handler">XmlRpcMethod
145 /// delegate</param> 109 /// delegate</param>
146 /// <param name="methodName">XmlRpc method name</param> 110 /// <param name="methodName">XmlRpc method name</param>
147 /// <param name="path">XmlRpc path prefix (regular expression)</param> 111 /// <param name="path">XmlRpc path prefix (regular expression)</param>
@@ -154,28 +118,24 @@ namespace OpenSim.Framework.Servers
154 /// can be null, in which case they are not taken into account 118 /// can be null, in which case they are not taken into account
155 /// when the handler is being looked up. 119 /// when the handler is being looked up.
156 /// </remarks> 120 /// </remarks>
157 public OSHttpXmlRpcHandler(OSHttpXmlRpcProcessor handler, string methodName, Regex path, 121 public OSHttpXmlRpcHandler(XmlRpcMethod handler, string methodName, Regex path,
158 Dictionary<string, Regex> headers, Regex whitelist) 122 Dictionary<string, Regex> headers, Regex whitelist)
123 : base(new Regex(@"^POST$", RegexOptions.IgnoreCase | RegexOptions.Compiled), path, headers,
124 new Regex(@"^(text|application)/xml", RegexOptions.IgnoreCase | RegexOptions.Compiled),
125 whitelist)
159 { 126 {
160 _handler = handler; 127 _handler = handler;
161 _pathsRegex = path;
162 _methodName = methodName; 128 _methodName = methodName;
163
164 if (null == _headers) _headers = new Dictionary<string, Regex>();
165 _headers.Add("content-type", new Regex(@"^(text|application)/xml", RegexOptions.IgnoreCase |
166 RegexOptions.Compiled));
167
168 _ipEndPointRegex = whitelist;
169 } 129 }
170 130
171 131
172 /// <summary> 132 /// <summary>
173 /// Instantiate an XmlRpc handler. 133 /// Instantiate an XmlRpc handler.
174 /// </summary> 134 /// </summary>
175 /// <param name="handler">OSHttpXmlRpcProcessor 135 /// <param name="handler">XmlRpcMethod
176 /// delegate</param> 136 /// delegate</param>
177 /// <param name="methodName">XmlRpc method name</param> 137 /// <param name="methodName">XmlRpc method name</param>
178 public OSHttpXmlRpcHandler(OSHttpXmlRpcProcessor handler, string methodName) 138 public OSHttpXmlRpcHandler(XmlRpcMethod handler, string methodName)
179 : this(handler, methodName, null, null, null) 139 : this(handler, methodName, null, null, null)
180 { 140 {
181 } 141 }
@@ -184,7 +144,7 @@ namespace OpenSim.Framework.Servers
184 /// <summary> 144 /// <summary>
185 /// Invoked by OSHttpRequestPump. 145 /// Invoked by OSHttpRequestPump.
186 /// </summary> 146 /// </summary>
187 public OSHttpHandlerResult Process(OSHttpRequest request) 147 public override OSHttpHandlerResult Process(OSHttpRequest request)
188 { 148 {
189 XmlRpcResponse xmlRpcResponse; 149 XmlRpcResponse xmlRpcResponse;
190 string responseString; 150 string responseString;