diff options
author | Dr Scofield | 2008-06-27 15:57:33 +0000 |
---|---|---|
committer | Dr Scofield | 2008-06-27 15:57:33 +0000 |
commit | 92e04ea587714d47ecb2fc6d77bb312c0a49111e (patch) | |
tree | 3753ed93c8f5e79fcc399e1661d47471c54c15aa /OpenSim/Framework/Servers/OSHttpRequestPump.cs | |
parent | * refactor: Remove group changed responsibilty from ScheduleGroupForTerseUpdate (diff) | |
download | opensim-SC-92e04ea587714d47ecb2fc6d77bb312c0a49111e.zip opensim-SC-92e04ea587714d47ecb2fc6d77bb312c0a49111e.tar.gz opensim-SC-92e04ea587714d47ecb2fc6d77bb312c0a49111e.tar.bz2 opensim-SC-92e04ea587714d47ecb2fc6d77bb312c0a49111e.tar.xz |
status: work-in-progress, non-functional
fleshing out OSHttpRequestPump code.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/Servers/OSHttpRequestPump.cs | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/OpenSim/Framework/Servers/OSHttpRequestPump.cs b/OpenSim/Framework/Servers/OSHttpRequestPump.cs index 6214ab0..f04134c 100644 --- a/OpenSim/Framework/Servers/OSHttpRequestPump.cs +++ b/OpenSim/Framework/Servers/OSHttpRequestPump.cs | |||
@@ -26,6 +26,13 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | ||
30 | using System.Collections.Specialized; | ||
31 | using System.Net; | ||
32 | using System.Reflection; | ||
33 | using System.Text.RegularExpressions; | ||
34 | using System.Threading; | ||
35 | using log4net; | ||
29 | using HttpServer; | 36 | using HttpServer; |
30 | 37 | ||
31 | namespace OpenSim.Framework.Servers | 38 | namespace OpenSim.Framework.Servers |
@@ -39,11 +46,29 @@ namespace OpenSim.Framework.Servers | |||
39 | /// </summary> | 46 | /// </summary> |
40 | public class OSHttpRequestPump | 47 | public class OSHttpRequestPump |
41 | { | 48 | { |
49 | private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
50 | |||
42 | protected OSHttpServer _server; | 51 | protected OSHttpServer _server; |
43 | protected OSHttpRequestQueue _queue; | 52 | protected OSHttpRequestQueue _queue; |
53 | protected Thread _engine; | ||
44 | 54 | ||
55 | private int _id; | ||
56 | |||
57 | public string EngineID | ||
58 | { | ||
59 | get { return String.Format("{0}-{1}", _server.EngineID, _id); } | ||
60 | } | ||
61 | |||
62 | |||
45 | public OSHttpRequestPump() | 63 | public OSHttpRequestPump() |
46 | { | 64 | { |
65 | _engine = new Thread(new ThreadStart(Engine)); | ||
66 | _engine.Name = EngineID; | ||
67 | _engine.IsBackground = true; | ||
68 | _engine.Start(); | ||
69 | |||
70 | ThreadTracker.Add(_engine); | ||
71 | |||
47 | } | 72 | } |
48 | 73 | ||
49 | public static OSHttpRequestPump[] Pumps(OSHttpServer server, OSHttpRequestQueue queue, int poolSize) | 74 | public static OSHttpRequestPump[] Pumps(OSHttpServer server, OSHttpRequestQueue queue, int poolSize) |
@@ -53,9 +78,140 @@ namespace OpenSim.Framework.Servers | |||
53 | { | 78 | { |
54 | pumps[i]._server = server; | 79 | pumps[i]._server = server; |
55 | pumps[i]._queue = queue; | 80 | pumps[i]._queue = queue; |
81 | pumps[i]._id = i; | ||
56 | } | 82 | } |
57 | 83 | ||
58 | return pumps; | 84 | return pumps; |
59 | } | 85 | } |
86 | |||
87 | public void Start() | ||
88 | { | ||
89 | _engine = new Thread(new ThreadStart(Engine)); | ||
90 | _engine.Name = EngineID; | ||
91 | _engine.IsBackground = true; | ||
92 | _engine.Start(); | ||
93 | |||
94 | ThreadTracker.Add(_engine); | ||
95 | } | ||
96 | |||
97 | public void Engine() | ||
98 | { | ||
99 | OSHttpRequest req = null; | ||
100 | |||
101 | try { | ||
102 | while (true) | ||
103 | { | ||
104 | // get job to do | ||
105 | req = _queue.Dequeue(); | ||
106 | |||
107 | // get list of registered handlers | ||
108 | List<OSHttpHandler> handlers = _server.OSHttpHandlers; | ||
109 | |||
110 | // prune list and sort from most specific to least | ||
111 | // specific | ||
112 | handlers = MatchHandlers(req, handlers); | ||
113 | |||
114 | // process req | ||
115 | foreach(OSHttpHandler h in handlers) | ||
116 | { | ||
117 | OSHttpHandlerResult rc = h.Process(req); | ||
118 | // handler did not process the request, try | ||
119 | // next handler | ||
120 | if (OSHttpHandlerResult.Pass == rc) continue; | ||
121 | // handler is taking over processing of | ||
122 | // request, we are done | ||
123 | if (OSHttpHandlerResult.Detached == rc) break; | ||
124 | |||
125 | // request was handled, we need to clean up | ||
126 | // TODO: cleanup :-) | ||
127 | |||
128 | break; | ||
129 | } | ||
130 | |||
131 | } | ||
132 | } | ||
133 | catch (Exception e) | ||
134 | { | ||
135 | _log.DebugFormat("[{0}] something went wrong: {1}", EngineID, e.ToString()); | ||
136 | _log.ErrorFormat("[{0}] something went wrong: {1}, terminating this pump", EngineID, e.Message); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | protected List<OSHttpHandler> MatchHandlers(OSHttpRequest req, List<OSHttpHandler> handlers) | ||
141 | { | ||
142 | Dictionary<OSHttpHandler, int> scoredHandlers = new Dictionary<OSHttpHandler, int>(); | ||
143 | |||
144 | foreach (OSHttpHandler h in handlers) | ||
145 | { | ||
146 | Regex pathRegex = h.Path; | ||
147 | Dictionary<string, Regex> headerRegexs = h.Headers; | ||
148 | Regex endPointsRegex = h.IPEndPointWhitelist; | ||
149 | |||
150 | int pathMatch = 0; | ||
151 | int headersMatch = 0; | ||
152 | |||
153 | // first, check whether IPEndPointWhitelist applies | ||
154 | // and, if it does, whether client is on that white | ||
155 | // list. | ||
156 | if (null != endPointsRegex) | ||
157 | { | ||
158 | // TODO: following code requires code changes to | ||
159 | // HttpServer.HttpRequest | ||
160 | |||
161 | // IPEndPoint remote = HttpServer.HttpRequest.RemoteIPEndPoint; | ||
162 | // Match epm = endPointsRegex.Match(remote.ToString()); | ||
163 | // if (!epm.Success) continue; | ||
164 | } | ||
165 | |||
166 | // whitelist ok, now check path | ||
167 | if (null != pathRegex) | ||
168 | { | ||
169 | Match m = pathRegex.Match(req.HttpRequest.Uri.AbsolutePath); | ||
170 | if (!m.Success) continue; | ||
171 | |||
172 | scoredHandlers[h] = m.ToString().Length; | ||
173 | } | ||
174 | |||
175 | // whitelist & path ok, now check headers | ||
176 | if (null != headerRegexs) | ||
177 | { | ||
178 | // go through all header Regexs and evaluate | ||
179 | // match: | ||
180 | // if header field not present or does not match: | ||
181 | // remove handler from scoredHandlers | ||
182 | // continue | ||
183 | // else: | ||
184 | // add increment headersMatch | ||
185 | NameValueCollection headers = req.HttpRequest.Headers; | ||
186 | foreach (string tag in headerRegexs.Keys) | ||
187 | { | ||
188 | if (null != headers[tag]) | ||
189 | { | ||
190 | Match hm = headerRegexs[tag].Match(headers[tag]); | ||
191 | if (hm.Success) { | ||
192 | headersMatch++; | ||
193 | continue; | ||
194 | } | ||
195 | } | ||
196 | |||
197 | scoredHandlers.Remove(h); | ||
198 | break; | ||
199 | } | ||
200 | // check whether h got kicked out | ||
201 | if (!scoredHandlers.ContainsKey(h)) continue; | ||
202 | |||
203 | scoredHandlers[h] += headersMatch; | ||
204 | } | ||
205 | } | ||
206 | |||
207 | List<OSHttpHandler> matchingHandlers = new List<OSHttpHandler>(scoredHandlers.Keys); | ||
208 | matchingHandlers.Sort(delegate(OSHttpHandler x, OSHttpHandler y) | ||
209 | { | ||
210 | return scoredHandlers[x] - scoredHandlers[y]; | ||
211 | }); | ||
212 | |||
213 | return matchingHandlers; | ||
214 | } | ||
215 | |||
60 | } | 216 | } |
61 | } | 217 | } |