diff options
author | lbsa71 | 2007-07-04 04:29:23 +0000 |
---|---|---|
committer | lbsa71 | 2007-07-04 04:29:23 +0000 |
commit | 8b3cb93b49b21b7729adc56a9c06658fb94b1e8f (patch) | |
tree | e279d472557a0966438e0eadedeb0b2579c34d3d /OpenSim/Framework/Servers/BaseHttpServer.cs | |
parent | Today's work on Building support/tools. Think I am slowly getting there. (diff) | |
download | opensim-SC-8b3cb93b49b21b7729adc56a9c06658fb94b1e8f.zip opensim-SC-8b3cb93b49b21b7729adc56a9c06658fb94b1e8f.tar.gz opensim-SC-8b3cb93b49b21b7729adc56a9c06658fb94b1e8f.tar.bz2 opensim-SC-8b3cb93b49b21b7729adc56a9c06658fb94b1e8f.tar.xz |
* Started work on converting BaseHttpServer to a stream dispatcher
Diffstat (limited to 'OpenSim/Framework/Servers/BaseHttpServer.cs')
-rw-r--r-- | OpenSim/Framework/Servers/BaseHttpServer.cs | 164 |
1 files changed, 103 insertions, 61 deletions
diff --git a/OpenSim/Framework/Servers/BaseHttpServer.cs b/OpenSim/Framework/Servers/BaseHttpServer.cs index 713793c..81028b0 100644 --- a/OpenSim/Framework/Servers/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/BaseHttpServer.cs | |||
@@ -65,6 +65,7 @@ namespace OpenSim.Framework.Servers | |||
65 | protected HttpListener m_httpListener; | 65 | protected HttpListener m_httpListener; |
66 | protected Dictionary<string, RestMethodEntry> m_restHandlers = new Dictionary<string, RestMethodEntry>(); | 66 | protected Dictionary<string, RestMethodEntry> m_restHandlers = new Dictionary<string, RestMethodEntry>(); |
67 | protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>(); | 67 | protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>(); |
68 | protected Dictionary<string, IStreamHandler> m_streamHandlers = new Dictionary<string, IStreamHandler>(); | ||
68 | protected int m_port; | 69 | protected int m_port; |
69 | protected bool firstcaps = true; | 70 | protected bool firstcaps = true; |
70 | 71 | ||
@@ -73,9 +74,14 @@ namespace OpenSim.Framework.Servers | |||
73 | m_port = port; | 74 | m_port = port; |
74 | } | 75 | } |
75 | 76 | ||
77 | private void AddStreamHandler(string path, IStreamHandler handler) | ||
78 | { | ||
79 | m_streamHandlers.Add(path, handler); | ||
80 | } | ||
81 | |||
76 | public bool AddRestHandler(string method, string path, RestMethod handler) | 82 | public bool AddRestHandler(string method, string path, RestMethod handler) |
77 | { | 83 | { |
78 | //Console.WriteLine("adding new REST handler for path " + path); | 84 | //Console.WriteLine("adding new REST handler for path " + path); |
79 | string methodKey = String.Format("{0}: {1}", method, path); | 85 | string methodKey = String.Format("{0}: {1}", method, path); |
80 | 86 | ||
81 | if (!this.m_restHandlers.ContainsKey(methodKey)) | 87 | if (!this.m_restHandlers.ContainsKey(methodKey)) |
@@ -190,75 +196,115 @@ namespace OpenSim.Framework.Servers | |||
190 | 196 | ||
191 | public virtual void HandleRequest(Object stateinfo) | 197 | public virtual void HandleRequest(Object stateinfo) |
192 | { | 198 | { |
193 | try | 199 | HttpListenerContext context = (HttpListenerContext)stateinfo; |
194 | { | ||
195 | HttpListenerContext context = (HttpListenerContext)stateinfo; | ||
196 | 200 | ||
197 | HttpListenerRequest request = context.Request; | 201 | HttpListenerRequest request = context.Request; |
198 | HttpListenerResponse response = context.Response; | 202 | HttpListenerResponse response = context.Response; |
199 | 203 | ||
200 | response.KeepAlive = false; | 204 | response.KeepAlive = false; |
201 | response.SendChunked = false; | 205 | response.SendChunked = false; |
202 | 206 | ||
203 | Stream body = request.InputStream; | 207 | string path = request.RawUrl; |
204 | Encoding encoding = Encoding.UTF8; | ||
205 | StreamReader reader = new StreamReader(body, encoding); | ||
206 | 208 | ||
207 | string requestBody = reader.ReadToEnd(); | 209 | IStreamHandler streamHandler; |
208 | body.Close(); | ||
209 | reader.Close(); | ||
210 | 210 | ||
211 | //Console.WriteLine(request.HttpMethod + " " + request.RawUrl + " Http/" + request.ProtocolVersion.ToString() + " content type: " + request.ContentType); | 211 | if(TryGetStreamHandler(path, out streamHandler)) |
212 | //Console.WriteLine(requestBody); | 212 | { |
213 | 213 | streamHandler.Handle(path, request.InputStream, response.OutputStream ); | |
214 | string responseString = ""; | 214 | } |
215 | // Console.WriteLine("new request " + request.ContentType +" at "+ request.RawUrl); | 215 | else |
216 | switch (request.ContentType) | 216 | { |
217 | { | 217 | HandleLegacyRequests(request, response); |
218 | case "text/xml": | 218 | } |
219 | // must be XML-RPC, so pass to the XML-RPC parser | 219 | } |
220 | |||
221 | responseString = ParseXMLRPC(requestBody); | ||
222 | responseString = Regex.Replace(responseString, "utf-16", "utf-8"); | ||
223 | |||
224 | response.AddHeader("Content-type", "text/xml"); | ||
225 | break; | ||
226 | |||
227 | case "application/xml": | ||
228 | case "application/octet-stream": | ||
229 | // probably LLSD we hope, otherwise it should be ignored by the parser | ||
230 | // responseString = ParseLLSDXML(requestBody); | ||
231 | responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); | ||
232 | response.AddHeader("Content-type", "application/xml"); | ||
233 | break; | ||
234 | |||
235 | case "application/x-www-form-urlencoded": | ||
236 | // a form data POST so send to the REST parser | ||
237 | responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); | ||
238 | response.AddHeader("Content-type", "text/html"); | ||
239 | break; | ||
240 | |||
241 | case null: | ||
242 | // must be REST or invalid crap, so pass to the REST parser | ||
243 | responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); | ||
244 | response.AddHeader("Content-type", "text/html"); | ||
245 | break; | ||
246 | 220 | ||
221 | private bool TryGetStreamHandler(string path, out IStreamHandler streamHandler ) | ||
222 | { | ||
223 | string bestMatch = null; | ||
224 | |||
225 | foreach (string pattern in m_streamHandlers.Keys) | ||
226 | { | ||
227 | if (path.StartsWith(pattern)) | ||
228 | { | ||
229 | if (String.IsNullOrEmpty( bestMatch ) || pattern.Length > bestMatch.Length) | ||
230 | { | ||
231 | bestMatch = pattern; | ||
232 | } | ||
247 | } | 233 | } |
234 | } | ||
248 | 235 | ||
249 | byte[] buffer = Encoding.UTF8.GetBytes(responseString); | 236 | if( String.IsNullOrEmpty( bestMatch ) ) |
250 | Stream output = response.OutputStream; | 237 | { |
251 | response.SendChunked = false; | 238 | streamHandler = null; |
252 | response.ContentLength64 = buffer.Length; | 239 | return false; |
253 | output.Write(buffer, 0, buffer.Length); | ||
254 | output.Close(); | ||
255 | } | 240 | } |
256 | catch (Exception e) | 241 | else |
257 | { | 242 | { |
258 | //Console.WriteLine(e.ToString()); | 243 | streamHandler = m_streamHandlers[bestMatch]; |
244 | return true; | ||
259 | } | 245 | } |
260 | } | 246 | } |
261 | 247 | ||
248 | private void HandleLegacyRequests(HttpListenerRequest request, HttpListenerResponse response) | ||
249 | { | ||
250 | Stream body = request.InputStream; | ||
251 | |||
252 | Encoding encoding = Encoding.UTF8; | ||
253 | StreamReader reader = new StreamReader(body, encoding); | ||
254 | |||
255 | string requestBody = reader.ReadToEnd(); | ||
256 | body.Close(); | ||
257 | reader.Close(); | ||
258 | |||
259 | //Console.WriteLine(request.HttpMethod + " " + request.RawUrl + " Http/" + request.ProtocolVersion.ToString() + " content type: " + request.ContentType); | ||
260 | //Console.WriteLine(requestBody); | ||
261 | |||
262 | string responseString = ""; | ||
263 | // Console.WriteLine("new request " + request.ContentType +" at "+ request.RawUrl); | ||
264 | switch (request.ContentType) | ||
265 | { | ||
266 | case "text/xml": | ||
267 | // must be XML-RPC, so pass to the XML-RPC parser | ||
268 | |||
269 | responseString = ParseXMLRPC(requestBody); | ||
270 | responseString = Regex.Replace(responseString, "utf-16", "utf-8"); | ||
271 | |||
272 | response.AddHeader("Content-type", "text/xml"); | ||
273 | break; | ||
274 | |||
275 | case "application/xml": | ||
276 | case "application/octet-stream": | ||
277 | // probably LLSD we hope, otherwise it should be ignored by the parser | ||
278 | // responseString = ParseLLSDXML(requestBody); | ||
279 | responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); | ||
280 | response.AddHeader("Content-type", "application/xml"); | ||
281 | break; | ||
282 | |||
283 | case "application/x-www-form-urlencoded": | ||
284 | // a form data POST so send to the REST parser | ||
285 | responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); | ||
286 | response.AddHeader("Content-type", "text/html"); | ||
287 | break; | ||
288 | |||
289 | case null: | ||
290 | // must be REST or invalid crap, so pass to the REST parser | ||
291 | responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); | ||
292 | response.AddHeader("Content-type", "text/html"); | ||
293 | break; | ||
294 | |||
295 | } | ||
296 | |||
297 | byte[] buffer = Encoding.UTF8.GetBytes(responseString); | ||
298 | Stream output = response.OutputStream; | ||
299 | response.SendChunked = false; | ||
300 | response.ContentLength64 = buffer.Length; | ||
301 | |||
302 | |||
303 | |||
304 | output.Write(buffer, 0, buffer.Length); | ||
305 | output.Close(); | ||
306 | } | ||
307 | |||
262 | public void Start() | 308 | public void Start() |
263 | { | 309 | { |
264 | MainLog.Instance.WriteLine(LogPriority.LOW, "BaseHttpServer.cs: Starting up HTTP Server"); | 310 | MainLog.Instance.WriteLine(LogPriority.LOW, "BaseHttpServer.cs: Starting up HTTP Server"); |
@@ -291,9 +337,5 @@ namespace OpenSim.Framework.Servers | |||
291 | } | 337 | } |
292 | } | 338 | } |
293 | 339 | ||
294 | public void AddLlsdMethod<TResponse, TRequest>(string path, LlsdMethod<TResponse, TRequest> handler ) | ||
295 | { | ||
296 | throw new Exception("The method or operation is not implemented."); | ||
297 | } | ||
298 | } | 340 | } |
299 | } | 341 | } |