aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Servers/HttpServer
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Servers/HttpServer')
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs41
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs1626
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs71
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs41
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs73
-rw-r--r--OpenSim/Framework/Servers/HttpServer/GenericHTTPMethod.cs33
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpAgentHandler.cs35
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs126
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs61
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Interfaces/OpenSim.Framework.Servers.Interfaces.csproj120
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Interfaces/OpenSim.Framework.Servers.Interfaces.csproj.user12
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Interfaces/OpenSim.Framework.Servers.Interfaces.dll.build54
-rw-r--r--OpenSim/Framework/Servers/HttpServer/Interfaces/OpenSim.Framework.Servers.Interfaces.mdp34
-rw-r--r--OpenSim/Framework/Servers/HttpServer/LLSDMethod.cs34
-rw-r--r--OpenSim/Framework/Servers/HttpServer/LLSDMethodString.cs33
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpHandler.cs183
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpHttpHandler.cs145
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs228
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpRequestPump.cs298
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpRequestQueue.cs68
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs302
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpServer.cs210
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs170
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OSHttpXmlRpcHandler.cs180
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OpenSim.Framework.Servers.HttpServer.csproj180
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OpenSim.Framework.Servers.HttpServer.csproj.user12
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OpenSim.Framework.Servers.HttpServer.dll.build74
-rw-r--r--OpenSim/Framework/Servers/HttpServer/OpenSim.Framework.Servers.HttpServer.mdp54
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs66
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs56
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestMethod.cs32
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestObjectPoster.cs84
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestObjectPosterResponse.cs107
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestSessionService.cs291
-rw-r--r--OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs61
-rw-r--r--OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectPoster.cs83
-rw-r--r--OpenSim/Framework/Servers/HttpServer/XmlRpcMethod.cs33
-rwxr-xr-xOpenSim/Framework/Servers/HttpServer/bin/Debug/OpenSim.Framework.Servers.HttpServer.dllbin0 -> 41472 bytes
-rw-r--r--OpenSim/Framework/Servers/HttpServer/bin/Debug/OpenSim.Framework.Servers.HttpServer.dll.mdbbin0 -> 14486 bytes
39 files changed, 5311 insertions, 0 deletions
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs
new file mode 100644
index 0000000..fc89e30
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHTTPHandler.cs
@@ -0,0 +1,41 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29
30namespace OpenSim.Framework.Servers.HttpServer
31{
32 public abstract class BaseHTTPHandler : BaseRequestHandler, IGenericHTTPHandler
33 {
34 public abstract Hashtable Handle(string path, Hashtable Request);
35
36 protected BaseHTTPHandler(string httpMethod, string path)
37 : base(httpMethod, path)
38 {
39 }
40 }
41}
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
new file mode 100644
index 0000000..779f577
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -0,0 +1,1626 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.IO;
32using System.Net;
33using System.Net.Sockets;
34using System.Reflection;
35using System.Globalization;
36using System.Text;
37using System.Threading;
38using System.Xml;
39using HttpServer;
40using log4net;
41using Nwc.XmlRpc;
42using OpenMetaverse.StructuredData;
43using CoolHTTPListener = HttpServer.HttpListener;
44using HttpListener=System.Net.HttpListener;
45
46namespace OpenSim.Framework.Servers.HttpServer
47{
48 public class BaseHttpServer : IHttpServer
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 private HttpServerLogWriter httpserverlog = new HttpServerLogWriter();
52
53 private volatile int NotSocketErrors = 0;
54 public volatile bool HTTPDRunning = false;
55
56 protected Thread m_workerThread;
57 // protected HttpListener m_httpListener;
58 protected CoolHTTPListener m_httpListener2;
59 protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>();
60 protected Dictionary<string, bool> m_rpcHandlersKeepAlive = new Dictionary<string, bool>();
61 protected DefaultLLSDMethod m_defaultLlsdHandler = null; // <-- Moving away from the monolithic.. and going to /registered/
62 protected Dictionary<string, LLSDMethod> m_llsdHandlers = new Dictionary<string, LLSDMethod>();
63 protected Dictionary<string, IRequestHandler> m_streamHandlers = new Dictionary<string, IRequestHandler>();
64 protected Dictionary<string, GenericHTTPMethod> m_HTTPHandlers = new Dictionary<string, GenericHTTPMethod>();
65 protected Dictionary<string, IHttpAgentHandler> m_agentHandlers = new Dictionary<string, IHttpAgentHandler>();
66
67 protected uint m_port;
68 protected uint m_sslport;
69 protected bool m_ssl;
70 protected bool m_firstcaps = true;
71 protected string m_SSLCommonName = "";
72
73 public uint SSLPort
74 {
75 get { return m_sslport; }
76 }
77
78 public string SSLCommonName
79 {
80 get { return m_SSLCommonName; }
81 }
82
83 public uint Port
84 {
85 get { return m_port; }
86 }
87
88 public bool UseSSL
89 {
90 get { return m_ssl; }
91 }
92
93 public BaseHttpServer(uint port)
94 {
95 m_port = port;
96 }
97
98 public BaseHttpServer(uint port, bool ssl) : this (port)
99 {
100 m_ssl = ssl;
101 }
102
103 public BaseHttpServer(uint port, bool ssl, uint sslport, string CN) : this (port, ssl)
104 {
105 if (m_ssl)
106 {
107 m_sslport = sslport;
108 }
109 }
110
111 /// <summary>
112 /// Add a stream handler to the http server. If the handler already exists, then nothing happens.
113 /// </summary>
114 /// <param name="handler"></param>
115 public void AddStreamHandler(IRequestHandler handler)
116 {
117 string httpMethod = handler.HttpMethod;
118 string path = handler.Path;
119 string handlerKey = GetHandlerKey(httpMethod, path);
120
121 lock (m_streamHandlers)
122 {
123 if (!m_streamHandlers.ContainsKey(handlerKey))
124 {
125 // m_log.DebugFormat("[BASE HTTP SERVER]: Adding handler key {0}", handlerKey);
126 m_streamHandlers.Add(handlerKey, handler);
127 }
128 }
129 }
130
131 private static string GetHandlerKey(string httpMethod, string path)
132 {
133 return httpMethod + ":" + path;
134 }
135
136 public bool AddXmlRPCHandler(string method, XmlRpcMethod handler)
137 {
138 return AddXmlRPCHandler(method, handler, true);
139 }
140
141 public bool AddXmlRPCHandler(string method, XmlRpcMethod handler, bool keepAlive)
142 {
143 lock (m_rpcHandlers)
144 {
145 m_rpcHandlers[method] = handler;
146 m_rpcHandlersKeepAlive[method] = keepAlive; // default
147 }
148
149 return true;
150 }
151
152 public XmlRpcMethod GetXmlRPCHandler(string method)
153 {
154 lock (m_rpcHandlers)
155 {
156 if (m_rpcHandlers.ContainsKey(method))
157 {
158 return m_rpcHandlers[method];
159 }
160 else
161 {
162 return null;
163 }
164 }
165 }
166
167 public bool AddHTTPHandler(string methodName, GenericHTTPMethod handler)
168 {
169 //m_log.DebugFormat("[BASE HTTP SERVER]: Registering {0}", methodName);
170
171 lock (m_HTTPHandlers)
172 {
173 if (!m_HTTPHandlers.ContainsKey(methodName))
174 {
175 m_HTTPHandlers.Add(methodName, handler);
176 return true;
177 }
178 }
179
180 //must already have a handler for that path so return false
181 return false;
182 }
183
184 // Note that the agent string is provided simply to differentiate
185 // the handlers - it is NOT required to be an actual agent header
186 // value.
187 public bool AddAgentHandler(string agent, IHttpAgentHandler handler)
188 {
189 lock (m_agentHandlers)
190 {
191 if (!m_agentHandlers.ContainsKey(agent))
192 {
193 m_agentHandlers.Add(agent, handler);
194 return true;
195 }
196 }
197
198 //must already have a handler for that path so return false
199 return false;
200 }
201
202 public bool AddLLSDHandler(string path, LLSDMethod handler)
203 {
204 lock (m_llsdHandlers)
205 {
206 if (!m_llsdHandlers.ContainsKey(path))
207 {
208 m_llsdHandlers.Add(path, handler);
209 return true;
210 }
211 }
212 return false;
213 }
214
215 public bool SetDefaultLLSDHandler(DefaultLLSDMethod handler)
216 {
217 m_defaultLlsdHandler = handler;
218 return true;
219 }
220
221 public void OnHandleRequestIOThread(IHttpClientContext context, IHttpRequest request)
222 {
223 OSHttpRequest req = new OSHttpRequest(context, request);
224 OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request));
225 //resp.KeepAlive = req.KeepAlive;
226 //m_log.Info("[Debug BASE HTTP SERVER]: Got Request");
227 //HttpServerContextObj objstate= new HttpServerContextObj(req,resp);
228 //ThreadPool.QueueUserWorkItem(new WaitCallback(ConvertIHttpClientContextToOSHttp), (object)objstate);
229 HandleRequest(req, resp);
230 }
231
232 public void ConvertIHttpClientContextToOSHttp(object stateinfo)
233 {
234 HttpServerContextObj objstate = (HttpServerContextObj)stateinfo;
235 //OSHttpRequest request = new OSHttpRequest(objstate.context,objstate.req);
236 //OSHttpResponse resp = new OSHttpResponse(new HttpServer.HttpResponse(objstate.context, objstate.req));
237
238 OSHttpRequest request = objstate.oreq;
239 OSHttpResponse resp = objstate.oresp;
240 //OSHttpResponse resp = new OSHttpResponse(new HttpServer.HttpResponse(objstate.context, objstate.req));
241
242 /*
243 request.AcceptTypes = objstate.req.AcceptTypes;
244 request.ContentLength = (long)objstate.req.ContentLength;
245 request.Headers = objstate.req.Headers;
246 request.HttpMethod = objstate.req.Method;
247 request.InputStream = objstate.req.Body;
248 foreach (string str in request.Headers)
249 {
250 if (str.ToLower().Contains("content-type: "))
251 {
252 request.ContentType = str.Substring(13, str.Length - 13);
253 break;
254 }
255 }
256 //request.KeepAlive = objstate.req.
257 foreach (HttpServer.HttpInput httpinput in objstate.req.QueryString)
258 {
259 request.QueryString.Add(httpinput.Name, httpinput[httpinput.Name]);
260 }
261
262 //request.Query = objstate.req.//objstate.req.QueryString;
263 //foreach (
264 //request.QueryString = objstate.req.QueryString;
265
266 */
267 HandleRequest(request,resp);
268 }
269
270 public virtual void HandleRequest(OSHttpRequest request, OSHttpResponse response)
271 {
272 try
273 {
274 Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true);
275 // This is the REST agent interface. We require an agent to properly identify
276 // itself. If the REST handler recognizes the prefix it will attempt to
277 // satisfy the request. If it is not recognizable, and no damage has occurred
278 // the request can be passed through to the other handlers. This is a low
279 // probability event; if a request is matched it is normally expected to be
280 // handled
281 //m_log.Debug("[BASE HTTP SERVER]: Handling Request" + request.RawUrl);
282 IHttpAgentHandler agentHandler;
283
284 if (TryGetAgentHandler(request, response, out agentHandler))
285 {
286 if (HandleAgentRequest(agentHandler, request, response))
287 {
288 return;
289 }
290 }
291
292 IRequestHandler requestHandler;
293 //response.KeepAlive = true;
294 response.SendChunked = false;
295
296 string path = request.RawUrl;
297 string handlerKey = GetHandlerKey(request.HttpMethod, path);
298
299 //m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
300
301 if (TryGetStreamHandler(handlerKey, out requestHandler))
302 {
303 //m_log.Debug("[BASE HTTP SERVER]: Found Stream Handler");
304 // Okay, so this is bad, but should be considered temporary until everything is IStreamHandler.
305 byte[] buffer;
306
307 response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type.
308
309 if (requestHandler is IStreamedRequestHandler)
310 {
311 IStreamedRequestHandler streamedRequestHandler = requestHandler as IStreamedRequestHandler;
312
313 buffer = streamedRequestHandler.Handle(path, request.InputStream, request, response);
314 }
315 else if (requestHandler is IGenericHTTPHandler)
316 {
317 //m_log.Debug("[BASE HTTP SERVER]: Found Caps based HTTP Handler");
318 IGenericHTTPHandler HTTPRequestHandler = requestHandler as IGenericHTTPHandler;
319 Stream requestStream = request.InputStream;
320
321 Encoding encoding = Encoding.UTF8;
322 StreamReader reader = new StreamReader(requestStream, encoding);
323
324 string requestBody = reader.ReadToEnd();
325
326 reader.Close();
327 requestStream.Close();
328
329 Hashtable keysvals = new Hashtable();
330 Hashtable headervals = new Hashtable();
331 //string host = String.Empty;
332
333 string[] querystringkeys = request.QueryString.AllKeys;
334 string[] rHeaders = request.Headers.AllKeys;
335
336
337 foreach (string queryname in querystringkeys)
338 {
339 keysvals.Add(queryname, request.QueryString[queryname]);
340 }
341
342 foreach (string headername in rHeaders)
343 {
344 //m_log.Warn("[HEADER]: " + headername + "=" + request.Headers[headername]);
345 headervals[headername] = request.Headers[headername];
346 }
347
348 // if (headervals.Contains("Host"))
349 // {
350 // host = (string)headervals["Host"];
351 // }
352
353 keysvals.Add("requestbody", requestBody);
354 if (keysvals.Contains("method"))
355 {
356 //m_log.Warn("[HTTP]: Contains Method");
357 //string method = (string)keysvals["method"];
358 //m_log.Warn("[HTTP]: " + requestBody);
359
360 }
361 DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response);
362 return;
363 }
364 else
365 {
366 IStreamHandler streamHandler = (IStreamHandler)requestHandler;
367
368 using (MemoryStream memoryStream = new MemoryStream())
369 {
370 streamHandler.Handle(path, request.InputStream, memoryStream, request, response);
371 memoryStream.Flush();
372 buffer = memoryStream.ToArray();
373 }
374 }
375
376 request.InputStream.Close();
377
378 if (!response.SendChunked)
379 response.ContentLength64 = buffer.LongLength;
380
381 try
382 {
383 response.OutputStream.Write(buffer, 0, buffer.Length);
384 //response.OutputStream.Close();
385 }
386 catch (HttpListenerException)
387 {
388 m_log.WarnFormat("[BASE HTTP SERVER]: HTTP request abnormally terminated.");
389 }
390 //response.OutputStream.Close();
391 try
392 {
393 response.Send();
394 }
395 catch (SocketException e)
396 {
397 // This has to be here to prevent a Linux/Mono crash
398 m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
399 }
400 return;
401 }
402
403 if (request.AcceptTypes != null && request.AcceptTypes.Length > 0)
404 {
405 foreach (string strAccept in request.AcceptTypes)
406 {
407 if (strAccept.Contains("application/llsd+xml"))
408 {
409 //m_log.Info("[Debug BASE HTTP SERVER]: Found an application/llsd+xml accept header");
410 HandleLLSDRequests(request, response);
411 return;
412 }
413 }
414 }
415
416 switch (request.ContentType)
417 {
418 case null:
419 case "text/html":
420 //m_log.Info("[Debug BASE HTTP SERVER]: found a text/html content type");
421 HandleHTTPRequest(request, response);
422 return;
423
424 case "application/llsd+xml":
425 case "application/xml+llsd":
426 //m_log.Info("[Debug BASE HTTP SERVER]: found a application/llsd+xml content type");
427 HandleLLSDRequests(request, response);
428 return;
429
430 case "text/xml":
431 case "application/xml":
432 default:
433 //m_log.Info("[Debug BASE HTTP SERVER]: in default handler");
434 // Point of note.. the DoWeHaveA methods check for an EXACT path
435 // if (request.RawUrl.Contains("/CAPS/EQG"))
436 // {
437 // int i = 1;
438 // }
439 //m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler");
440 if (DoWeHaveALLSDHandler(request.RawUrl))
441 {
442 //m_log.Info("[Debug BASE HTTP SERVER]: Found LLSD Handler");
443 HandleLLSDRequests(request, response);
444 return;
445 }
446 //m_log.Info("[Debug BASE HTTP SERVER]: Checking for HTTP Handler");
447 if (DoWeHaveAHTTPHandler(request.RawUrl))
448 {
449 //m_log.Info("[Debug BASE HTTP SERVER]: found HTTP Handler");
450 HandleHTTPRequest(request, response);
451 return;
452 }
453
454 //m_log.Info("[Debug BASE HTTP SERVER]: Generic XMLRPC");
455 // generic login request.
456 HandleXmlRpcRequests(request, response);
457
458 return;
459 }
460 }
461 catch (SocketException e)
462 {
463 // At least on linux, it appears that if the client makes a request without requiring the response,
464 // an unconnected socket exception is thrown when we close the response output stream. There's no
465 // obvious way to tell if the client didn't require the response, so instead we'll catch and ignore
466 // the exception instead.
467 //
468 // An alternative may be to turn off all response write exceptions on the HttpListener, but let's go
469 // with the minimum first
470 m_log.WarnFormat("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e);
471 }
472 catch (EndOfStreamException e)
473 {
474 m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e);
475 }
476 catch (InvalidOperationException e)
477 {
478 m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e);
479 SendHTML500(response);
480 }
481 }
482
483 private bool TryGetStreamHandler(string handlerKey, out IRequestHandler streamHandler)
484 {
485 string bestMatch = null;
486
487 lock (m_streamHandlers)
488 {
489 foreach (string pattern in m_streamHandlers.Keys)
490 {
491 if (handlerKey.StartsWith(pattern))
492 {
493 if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length)
494 {
495 bestMatch = pattern;
496 }
497 }
498 }
499
500 if (String.IsNullOrEmpty(bestMatch))
501 {
502 streamHandler = null;
503 return false;
504 }
505 else
506 {
507 streamHandler = m_streamHandlers[bestMatch];
508 return true;
509 }
510 }
511 }
512
513 private bool TryGetHTTPHandler(string handlerKey, out GenericHTTPMethod HTTPHandler)
514 {
515 //m_log.DebugFormat("[BASE HTTP HANDLER]: Looking for HTTP handler for {0}", handlerKey);
516
517 string bestMatch = null;
518
519 lock (m_HTTPHandlers)
520 {
521 foreach (string pattern in m_HTTPHandlers.Keys)
522 {
523 if (handlerKey.StartsWith(pattern))
524 {
525 if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length)
526 {
527 bestMatch = pattern;
528 }
529 }
530 }
531
532 if (String.IsNullOrEmpty(bestMatch))
533 {
534 HTTPHandler = null;
535 return false;
536 }
537 else
538 {
539 HTTPHandler = m_HTTPHandlers[bestMatch];
540 return true;
541 }
542 }
543 }
544
545 private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler)
546 {
547 agentHandler = null;
548 try
549 {
550 foreach (IHttpAgentHandler handler in m_agentHandlers.Values)
551 {
552 if (handler.Match(request, response))
553 {
554 agentHandler = handler;
555 return true;
556 }
557 }
558 }
559 catch(KeyNotFoundException)
560 {
561 }
562
563 return false;
564 }
565
566 /// <summary>
567 /// Try all the registered xmlrpc handlers when an xmlrpc request is received.
568 /// Sends back an XMLRPC unknown request response if no handler is registered for the requested method.
569 /// </summary>
570 /// <param name="request"></param>
571 /// <param name="response"></param>
572 private void HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response)
573 {
574 Stream requestStream = request.InputStream;
575
576 Encoding encoding = Encoding.UTF8;
577 StreamReader reader = new StreamReader(requestStream, encoding);
578
579 string requestBody = reader.ReadToEnd();
580 reader.Close();
581 requestStream.Close();
582
583 string responseString = String.Empty;
584 XmlRpcRequest xmlRprcRequest = null;
585
586 try
587 {
588 xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody);
589 }
590 catch (XmlException)
591 {
592 }
593
594 if (xmlRprcRequest != null)
595 {
596 string methodName = xmlRprcRequest.MethodName;
597 if (methodName != null)
598 {
599 xmlRprcRequest.Params.Add(request.RemoteIPEndPoint); // Param[1]
600 XmlRpcResponse xmlRpcResponse;
601
602 XmlRpcMethod method;
603 bool methodWasFound;
604 lock (m_rpcHandlers)
605 {
606 methodWasFound = m_rpcHandlers.TryGetValue(methodName, out method);
607 }
608
609 if (methodWasFound)
610 {
611 xmlRprcRequest.Params.Add(request.Url); // Param[2]
612
613 try
614 {
615 xmlRpcResponse = method(xmlRprcRequest);
616 }
617 catch(Exception e)
618 {
619 // if the registered XmlRpc method threw an exception, we pass a fault-code along
620 xmlRpcResponse = new XmlRpcResponse();
621 // Code probably set in accordance with http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php
622 xmlRpcResponse.SetFault(-32603, String.Format("Requested method [{0}] threw exception: {1}",
623 methodName, e.Message));
624 }
625 // if the method wasn't found, we can't determine KeepAlive state anyway, so lets do it only here
626 response.KeepAlive = m_rpcHandlersKeepAlive[methodName];
627 }
628 else
629 {
630 xmlRpcResponse = new XmlRpcResponse();
631 // Code set in accordance with http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php
632 xmlRpcResponse.SetFault(-32601, String.Format("Requested method [{0}] not found", methodName));
633 }
634
635 responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse);
636 }
637 else
638 {
639 //HandleLLSDRequests(request, response);
640 response.ContentType = "text/plain";
641 response.StatusCode = 404;
642 response.StatusDescription = "Not Found";
643 response.ProtocolVersion = "HTTP/1.0";
644 byte[] buf = Encoding.UTF8.GetBytes("Not found");
645 response.KeepAlive = false;
646
647 m_log.ErrorFormat("[BASE HTTP SERVER] Handler not found for http request {0}", request.RawUrl);
648
649 response.SendChunked = false;
650 response.ContentLength64 = buf.Length;
651 response.ContentEncoding = Encoding.UTF8;
652 try
653 {
654 response.OutputStream.Write(buf, 0, buf.Length);
655 }
656 catch (Exception ex)
657 {
658 m_log.Warn("[HTTPD]: Error - " + ex.Message);
659 }
660 finally
661 {
662 try
663 {
664 response.Send();
665 }
666 catch (SocketException e)
667 {
668 // This has to be here to prevent a Linux/Mono crash
669 m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
670 }
671 }
672 return;
673 //responseString = "Error";
674 }
675 }
676
677 response.ContentType = "text/xml";
678
679 byte[] buffer = Encoding.UTF8.GetBytes(responseString);
680
681 response.SendChunked = false;
682 response.ContentLength64 = buffer.Length;
683 response.ContentEncoding = Encoding.UTF8;
684 try
685 {
686 response.OutputStream.Write(buffer, 0, buffer.Length);
687 }
688 catch (Exception ex)
689 {
690 m_log.Warn("[HTTPD]: Error - " + ex.Message);
691 }
692 finally
693 {
694 try
695 {
696 response.Send();
697 }
698 catch (SocketException e)
699 {
700 // This has to be here to prevent a Linux/Mono crash
701 m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
702 }
703 }
704 }
705
706 private void HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response)
707 {
708 //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request");
709 Stream requestStream = request.InputStream;
710
711 Encoding encoding = Encoding.UTF8;
712 StreamReader reader = new StreamReader(requestStream, encoding);
713
714 string requestBody = reader.ReadToEnd();
715 reader.Close();
716 requestStream.Close();
717
718 //m_log.DebugFormat("[OGP]: {0}:{1}", request.RawUrl, requestBody);
719 response.KeepAlive = true;
720
721 OSD llsdRequest = null;
722 OSD llsdResponse = null;
723
724 bool LegacyLLSDLoginLibOMV = (requestBody.Contains("passwd") && requestBody.Contains("mac") && requestBody.Contains("viewer_digest"));
725
726 if (requestBody.Length == 0)
727 // Get Request
728 {
729 requestBody = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><llsd><map><key>request</key><string>get</string></map></llsd>";
730 }
731 try
732 {
733 llsdRequest = OSDParser.DeserializeLLSDXml(requestBody);
734 }
735 catch (Exception ex)
736 {
737 m_log.Warn("[HTTPD]: Error - " + ex.Message);
738 }
739
740 if (llsdRequest != null)// && m_defaultLlsdHandler != null)
741 {
742
743 LLSDMethod llsdhandler = null;
744
745 if (TryGetLLSDHandler(request.RawUrl, out llsdhandler) && !LegacyLLSDLoginLibOMV)
746 {
747 // we found a registered llsd handler to service this request
748 llsdResponse = llsdhandler(request.RawUrl, llsdRequest, request.RemoteIPEndPoint.ToString());
749 }
750 else
751 {
752 // we didn't find a registered llsd handler to service this request
753 // check if we have a default llsd handler
754
755 if (m_defaultLlsdHandler != null)
756 {
757 // LibOMV path
758 llsdResponse = m_defaultLlsdHandler(llsdRequest);
759 }
760 else
761 {
762 // Oops, no handler for this.. give em the failed message
763 llsdResponse = GenerateNoLLSDHandlerResponse();
764 }
765 }
766
767 }
768 else
769 {
770 llsdResponse = GenerateNoLLSDHandlerResponse();
771 }
772 byte[] buffer = new byte[0];
773 if (llsdResponse.ToString() == "shutdown404!")
774 {
775 response.ContentType = "text/plain";
776 response.StatusCode = 404;
777 response.StatusDescription = "Not Found";
778 response.ProtocolVersion = "HTTP/1.0";
779 buffer = Encoding.UTF8.GetBytes("Not found");
780 }
781 else
782 {
783 response.ContentType = "application/llsd+xml";
784 //m_log.Info("[Debug BASE HTTP SERVER]: Response: " + llsdResponse.ToString());
785 buffer = OSDParser.SerializeLLSDXmlBytes(llsdResponse);
786 }
787 response.SendChunked = false;
788 response.ContentLength64 = buffer.Length;
789 response.ContentEncoding = Encoding.UTF8;
790 response.KeepAlive = true;
791
792 try
793 {
794 response.OutputStream.Write(buffer, 0, buffer.Length);
795 }
796 catch (Exception ex)
797 {
798 m_log.Warn("[HTTPD]: Error - " + ex.Message);
799 }
800 finally
801 {
802 //response.OutputStream.Close();
803 try
804 {
805 response.Send();
806 response.OutputStream.Flush();
807 response.OutputStream.Close();
808 }
809 catch (IOException e)
810 {
811 m_log.DebugFormat("[BASE HTTP SERVER] LLSD IOException {0}.", e);
812 }
813 catch (SocketException e)
814 {
815 // This has to be here to prevent a Linux/Mono crash
816 m_log.WarnFormat("[BASE HTTP SERVER] LLSD issue {0}.\nNOTE: this may be spurious on Linux.", e);
817 }
818 }
819 }
820
821 /// <summary>
822 /// Checks if we have an Exact path in the LLSD handlers for the path provided
823 /// </summary>
824 /// <param name="path">URI of the request</param>
825 /// <returns>true if we have one, false if not</returns>
826 private bool DoWeHaveALLSDHandler(string path)
827 {
828
829 string[] pathbase = path.Split('/');
830 string searchquery = "/";
831
832 if (pathbase.Length < 1)
833 return false;
834
835 for (int i = 1; i < pathbase.Length; i++)
836 {
837 searchquery += pathbase[i];
838 if (pathbase.Length - 1 != i)
839 searchquery += "/";
840 }
841
842 string bestMatch = null;
843
844 foreach (string pattern in m_llsdHandlers.Keys)
845 {
846
847 if (searchquery.StartsWith(pattern) && searchquery.Length >= pattern.Length)
848 {
849
850 bestMatch = pattern;
851
852 }
853 }
854
855 // extra kicker to remove the default XMLRPC login case.. just in case..
856 if (path != "/" && bestMatch == "/" && searchquery != "/")
857 return false;
858
859 if (path == "/")
860 return false;
861
862 if (String.IsNullOrEmpty(bestMatch))
863 {
864
865 return false;
866 }
867 else
868 {
869
870 return true;
871 }
872 }
873
874 /// <summary>
875 /// Checks if we have an Exact path in the HTTP handlers for the path provided
876 /// </summary>
877 /// <param name="path">URI of the request</param>
878 /// <returns>true if we have one, false if not</returns>
879 private bool DoWeHaveAHTTPHandler(string path)
880 {
881 string[] pathbase = path.Split('/');
882 string searchquery = "/";
883
884 if (pathbase.Length < 1)
885 return false;
886
887 for (int i = 1; i < pathbase.Length; i++)
888 {
889 searchquery += pathbase[i];
890 if (pathbase.Length - 1 != i)
891 searchquery += "/";
892 }
893
894 string bestMatch = null;
895
896 //m_log.DebugFormat("[BASE HTTP HANDLER]: Checking if we have an HTTP handler for {0}", searchquery);
897
898 lock (m_HTTPHandlers)
899 {
900 foreach (string pattern in m_HTTPHandlers.Keys)
901 {
902 if (searchquery.StartsWith(pattern) && searchquery.Length >= pattern.Length)
903 {
904 bestMatch = pattern;
905 }
906 }
907
908 // extra kicker to remove the default XMLRPC login case.. just in case..
909 if (path == "/")
910 return false;
911
912 if (String.IsNullOrEmpty(bestMatch))
913 {
914 return false;
915 }
916 else
917 {
918 return true;
919 }
920 }
921 }
922
923 private bool TryGetLLSDHandler(string path, out LLSDMethod llsdHandler)
924 {
925 llsdHandler = null;
926 // Pull out the first part of the path
927 // splitting the path by '/' means we'll get the following return..
928 // {0}/{1}/{2}
929 // where {0} isn't something we really control 100%
930
931 string[] pathbase = path.Split('/');
932 string searchquery = "/";
933
934 if (pathbase.Length < 1)
935 return false;
936
937 for (int i=1; i<pathbase.Length; i++)
938 {
939 searchquery += pathbase[i];
940 if (pathbase.Length-1 != i)
941 searchquery += "/";
942 }
943
944 // while the matching algorithm below doesn't require it, we're expecting a query in the form
945 //
946 // [] = optional
947 // /resource/UUID/action[/action]
948 //
949 // now try to get the closest match to the reigstered path
950 // at least for OGP, registered path would probably only consist of the /resource/
951
952 string bestMatch = null;
953
954 foreach (string pattern in m_llsdHandlers.Keys)
955 {
956 if (searchquery.ToLower().StartsWith(pattern.ToLower()))
957 {
958 if (String.IsNullOrEmpty(bestMatch) || searchquery.Length > bestMatch.Length)
959 {
960 // You have to specifically register for '/' and to get it, you must specificaly request it
961 //
962 if (pattern == "/" && searchquery == "/" || pattern != "/")
963 bestMatch = pattern;
964 }
965 }
966 }
967
968 if (String.IsNullOrEmpty(bestMatch))
969 {
970 llsdHandler = null;
971 return false;
972 }
973 else
974 {
975 llsdHandler = m_llsdHandlers[bestMatch];
976 return true;
977 }
978 }
979
980 private OSDMap GenerateNoLLSDHandlerResponse()
981 {
982 OSDMap map = new OSDMap();
983 map["reason"] = OSD.FromString("LLSDRequest");
984 map["message"] = OSD.FromString("No handler registered for LLSD Requests");
985 map["login"] = OSD.FromString("false");
986 return map;
987 }
988 /// <summary>
989 /// A specific agent handler was provided. Such a handler is expecetd to have an
990 /// intimate, and highly specific relationship with the client. Consequently,
991 /// nothing is done here.
992 /// </summary>
993 /// <param name="handler"></param>
994 /// <param name="request"></param>
995 /// <param name="response"></param>
996
997 private bool HandleAgentRequest(IHttpAgentHandler handler, OSHttpRequest request, OSHttpResponse response)
998 {
999 // In the case of REST, then handler is responsible for ALL aspects of
1000 // the request/response handling. Nothing is done here, not even encoding.
1001
1002 try
1003 {
1004 return handler.Handle(request, response);
1005 }
1006 catch (Exception e)
1007 {
1008 // If the handler did in fact close the stream, then this will blow
1009 // chunks. So that that doesn't disturb anybody we throw away any
1010 // and all exceptions raised. We've done our best to release the
1011 // client.
1012 try
1013 {
1014 m_log.Warn("[HTTP-AGENT]: Error - " + e.Message);
1015 response.SendChunked = false;
1016 response.KeepAlive = true;
1017 response.StatusCode = (int)OSHttpStatusCode.ServerErrorInternalError;
1018 //response.OutputStream.Close();
1019 try
1020 {
1021 response.Send();
1022 }
1023 catch (SocketException f)
1024 {
1025 // This has to be here to prevent a Linux/Mono crash
1026 m_log.WarnFormat(
1027 "[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", f);
1028 }
1029 }
1030 catch(Exception)
1031 {
1032 }
1033 }
1034
1035 // Indicate that the request has been "handled"
1036
1037 return true;
1038
1039 }
1040
1041 public void HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response)
1042 {
1043 switch (request.HttpMethod)
1044 {
1045 case "OPTIONS":
1046 response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
1047 return;
1048
1049 default:
1050 HandleContentVerbs(request, response);
1051 return;
1052 }
1053 }
1054
1055 private void HandleContentVerbs(OSHttpRequest request, OSHttpResponse response)
1056 {
1057 // This is a test. There's a workable alternative.. as this way sucks.
1058 // We'd like to put this into a text file parhaps that's easily editable.
1059 //
1060 // For this test to work, I used the following secondlife.exe parameters
1061 // "C:\Program Files\SecondLifeWindLight\SecondLifeWindLight.exe" -settings settings_windlight.xml -channel "Second Life WindLight" -set SystemLanguage en-us -loginpage http://10.1.1.2:8002/?show_login_form=TRUE -loginuri http://10.1.1.2:8002 -user 10.1.1.2
1062 //
1063 // Even after all that, there's still an error, but it's a start.
1064 //
1065 // I depend on show_login_form being in the secondlife.exe parameters to figure out
1066 // to display the form, or process it.
1067 // a better way would be nifty.
1068
1069 Stream requestStream = request.InputStream;
1070
1071 Encoding encoding = Encoding.UTF8;
1072 StreamReader reader = new StreamReader(requestStream, encoding);
1073
1074 string requestBody = reader.ReadToEnd();
1075 // avoid warning for now
1076 reader.ReadToEnd();
1077 reader.Close();
1078 requestStream.Close();
1079
1080 Hashtable keysvals = new Hashtable();
1081 Hashtable headervals = new Hashtable();
1082
1083 Hashtable requestVars = new Hashtable();
1084
1085 string host = String.Empty;
1086
1087 string[] querystringkeys = request.QueryString.AllKeys;
1088 string[] rHeaders = request.Headers.AllKeys;
1089
1090 keysvals.Add("body", requestBody);
1091 keysvals.Add("uri", request.RawUrl);
1092 keysvals.Add("content-type", request.ContentType);
1093 keysvals.Add("http-method", request.HttpMethod);
1094
1095 foreach (string queryname in querystringkeys)
1096 {
1097 keysvals.Add(queryname, request.QueryString[queryname]);
1098 requestVars.Add(queryname, keysvals[queryname]);
1099 }
1100
1101 foreach (string headername in rHeaders)
1102 {
1103 //m_log.Warn("[HEADER]: " + headername + "=" + request.Headers[headername]);
1104 headervals[headername] = request.Headers[headername];
1105 }
1106
1107 if (headervals.Contains("Host"))
1108 {
1109 host = (string)headervals["Host"];
1110 }
1111
1112 keysvals.Add("headers",headervals);
1113 keysvals.Add("querystringkeys", querystringkeys);
1114 keysvals.Add("requestvars", requestVars);
1115
1116 if (keysvals.Contains("method"))
1117 {
1118 //m_log.Warn("[HTTP]: Contains Method");
1119 string method = (string) keysvals["method"];
1120 //m_log.Warn("[HTTP]: " + requestBody);
1121 GenericHTTPMethod requestprocessor;
1122 bool foundHandler = TryGetHTTPHandler(method, out requestprocessor);
1123 if (foundHandler)
1124 {
1125 Hashtable responsedata1 = requestprocessor(keysvals);
1126 DoHTTPGruntWork(responsedata1,response);
1127
1128 //SendHTML500(response);
1129 }
1130 else
1131 {
1132 //m_log.Warn("[HTTP]: Handler Not Found");
1133 SendHTML404(response, host);
1134 }
1135 }
1136 else
1137 {
1138
1139 GenericHTTPMethod requestprocessor;
1140 bool foundHandler = TryGetHTTPHandlerPathBased(request.RawUrl, out requestprocessor);
1141 if (foundHandler)
1142 {
1143 Hashtable responsedata2 = requestprocessor(keysvals);
1144 DoHTTPGruntWork(responsedata2, response);
1145
1146 //SendHTML500(response);
1147 }
1148 else
1149 {
1150 //m_log.Warn("[HTTP]: Handler Not Found");
1151 SendHTML404(response, host);
1152 }
1153 }
1154 }
1155
1156 private bool TryGetHTTPHandlerPathBased(string path, out GenericHTTPMethod httpHandler)
1157 {
1158 httpHandler = null;
1159 // Pull out the first part of the path
1160 // splitting the path by '/' means we'll get the following return..
1161 // {0}/{1}/{2}
1162 // where {0} isn't something we really control 100%
1163
1164 string[] pathbase = path.Split('/');
1165 string searchquery = "/";
1166
1167 if (pathbase.Length < 1)
1168 return false;
1169
1170 for (int i = 1; i < pathbase.Length; i++)
1171 {
1172 searchquery += pathbase[i];
1173 if (pathbase.Length - 1 != i)
1174 searchquery += "/";
1175 }
1176
1177 // while the matching algorithm below doesn't require it, we're expecting a query in the form
1178 //
1179 // [] = optional
1180 // /resource/UUID/action[/action]
1181 //
1182 // now try to get the closest match to the reigstered path
1183 // at least for OGP, registered path would probably only consist of the /resource/
1184
1185 string bestMatch = null;
1186
1187// m_log.DebugFormat(
1188// "[BASE HTTP HANDLER]: TryGetHTTPHandlerPathBased() looking for HTTP handler to match {0}", searchquery);
1189
1190 lock (m_HTTPHandlers)
1191 {
1192 foreach (string pattern in m_HTTPHandlers.Keys)
1193 {
1194 if (searchquery.ToLower().StartsWith(pattern.ToLower()))
1195 {
1196 if (String.IsNullOrEmpty(bestMatch) || searchquery.Length > bestMatch.Length)
1197 {
1198 // You have to specifically register for '/' and to get it, you must specificaly request it
1199 //
1200 if (pattern == "/" && searchquery == "/" || pattern != "/")
1201 bestMatch = pattern;
1202 }
1203 }
1204 }
1205
1206 if (String.IsNullOrEmpty(bestMatch))
1207 {
1208 httpHandler = null;
1209 return false;
1210 }
1211 else
1212 {
1213 if (bestMatch == "/" && searchquery != "/")
1214 return false;
1215
1216 httpHandler = m_HTTPHandlers[bestMatch];
1217 return true;
1218 }
1219 }
1220 }
1221
1222 private static void DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
1223 {
1224 //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
1225 int responsecode = (int)responsedata["int_response_code"];
1226 string responseString = (string)responsedata["str_response_string"];
1227 string contentType = (string)responsedata["content_type"];
1228
1229 if (responsedata.ContainsKey("error_status_text"))
1230 {
1231 response.StatusDescription = (string)responsedata["error_status_text"];
1232 }
1233 if (responsedata.ContainsKey("http_protocol_version"))
1234 {
1235 response.ProtocolVersion = (string)responsedata["http_protocol_version"];
1236 }
1237
1238 if (responsedata.ContainsKey("keepalive"))
1239 {
1240 bool keepalive = (bool)responsedata["keepalive"];
1241 response.KeepAlive = keepalive;
1242
1243 }
1244 //Even though only one other part of the entire code uses HTTPHandlers, we shouldn't expect this
1245 //and should check for NullReferenceExceptions
1246
1247 if (string.IsNullOrEmpty(contentType))
1248 {
1249 contentType = "text/html";
1250 }
1251
1252 // The client ignores anything but 200 here for web login, so ensure that this is 200 for that
1253
1254 response.StatusCode = responsecode;
1255
1256 if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently)
1257 {
1258 response.RedirectLocation = (string)responsedata["str_redirect_location"];
1259 response.StatusCode = responsecode;
1260 }
1261
1262 response.AddHeader("Content-Type", contentType);
1263
1264 byte[] buffer;
1265
1266 if (!(contentType.Contains("image")
1267 || contentType.Contains("x-shockwave-flash")
1268 || contentType.Contains("application/x-oar")))
1269 {
1270 // Text
1271 buffer = Encoding.UTF8.GetBytes(responseString);
1272 }
1273 else
1274 {
1275 // Binary!
1276 buffer = Convert.FromBase64String(responseString);
1277 }
1278
1279 response.SendChunked = false;
1280 response.ContentLength64 = buffer.Length;
1281 response.ContentEncoding = Encoding.UTF8;
1282
1283 try
1284 {
1285 response.OutputStream.Write(buffer, 0, buffer.Length);
1286 }
1287 catch (Exception ex)
1288 {
1289 m_log.Warn("[HTTPD]: Error - " + ex.Message);
1290 }
1291 finally
1292 {
1293 //response.OutputStream.Close();
1294 try
1295 {
1296 response.Send();
1297 }
1298 catch (SocketException e)
1299 {
1300 // This has to be here to prevent a Linux/Mono crash
1301 m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
1302 }
1303 }
1304 }
1305
1306 public void SendHTML404(OSHttpResponse response, string host)
1307 {
1308 // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
1309 response.StatusCode = 404;
1310 response.AddHeader("Content-type", "text/html");
1311
1312 string responseString = GetHTTP404(host);
1313 byte[] buffer = Encoding.UTF8.GetBytes(responseString);
1314
1315 response.SendChunked = false;
1316 response.ContentLength64 = buffer.Length;
1317 response.ContentEncoding = Encoding.UTF8;
1318
1319 try
1320 {
1321 response.OutputStream.Write(buffer, 0, buffer.Length);
1322 }
1323 catch (Exception ex)
1324 {
1325 m_log.Warn("[HTTPD]: Error - " + ex.Message);
1326 }
1327 finally
1328 {
1329 //response.OutputStream.Close();
1330 try
1331 {
1332 response.Send();
1333 }
1334 catch (SocketException e)
1335 {
1336 // This has to be here to prevent a Linux/Mono crash
1337 m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
1338 }
1339 }
1340 }
1341
1342 public void SendHTML500(OSHttpResponse response)
1343 {
1344 // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
1345 response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
1346 response.AddHeader("Content-type", "text/html");
1347
1348 string responseString = GetHTTP500();
1349 byte[] buffer = Encoding.UTF8.GetBytes(responseString);
1350
1351 response.SendChunked = false;
1352 response.ContentLength64 = buffer.Length;
1353 response.ContentEncoding = Encoding.UTF8;
1354 try
1355 {
1356 response.OutputStream.Write(buffer, 0, buffer.Length);
1357 }
1358 catch (Exception ex)
1359 {
1360 m_log.Warn("[HTTPD]: Error - " + ex.Message);
1361 }
1362 finally
1363 {
1364 //response.OutputStream.Close();
1365 try
1366 {
1367 response.Send();
1368 }
1369 catch (SocketException e)
1370 {
1371 // This has to be here to prevent a Linux/Mono crash
1372 m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
1373 }
1374 }
1375 }
1376
1377 public void Start()
1378 {
1379 m_log.Info("[HTTPD]: Starting up HTTP Server");
1380
1381 //m_workerThread = new Thread(new ThreadStart(StartHTTP));
1382 //m_workerThread.Name = "HttpThread";
1383 //m_workerThread.IsBackground = true;
1384 //m_workerThread.Start();
1385 //ThreadTracker.Add(m_workerThread);
1386 StartHTTP();
1387 }
1388
1389 private void StartHTTP()
1390 {
1391 try
1392 {
1393 m_log.Info("[HTTPD]: Spawned main thread OK");
1394 //m_httpListener = new HttpListener();
1395 NotSocketErrors = 0;
1396 if (!m_ssl)
1397 {
1398 //m_httpListener.Prefixes.Add("http://+:" + m_port + "/");
1399 //m_httpListener.Prefixes.Add("http://10.1.1.5:" + m_port + "/");
1400 m_httpListener2 = new CoolHTTPListener(IPAddress.Any, (int)m_port);
1401 m_httpListener2.ExceptionThrown += httpServerException;
1402 m_httpListener2.LogWriter = httpserverlog;
1403
1404 // Uncomment this line in addition to those in HttpServerLogWriter
1405 // if you want more detailed trace information from the HttpServer
1406 //m_httpListener2.UseTraceLogs = true;
1407
1408 m_httpListener2.DisconnectHandler = httpServerDisconnectMonitor;
1409 }
1410 else
1411 {
1412 //m_httpListener.Prefixes.Add("https://+:" + (m_sslport) + "/");
1413 //m_httpListener.Prefixes.Add("http://+:" + m_port + "/");
1414 }
1415
1416 m_httpListener2.RequestHandler += OnHandleRequestIOThread;
1417 //m_httpListener.Start();
1418 m_httpListener2.Start(64);
1419 HTTPDRunning = true;
1420
1421 //HttpListenerContext context;
1422 //while (true)
1423 //{
1424 // context = m_httpListener.GetContext();
1425 // ThreadPool.QueueUserWorkItem(new WaitCallback(HandleRequest), context);
1426 // }
1427 }
1428 catch (Exception e)
1429 {
1430 m_log.Error("[HTTPD]: Error - " + e.Message);
1431 m_log.Error("[HTTPD]: Tip: Do you have permission to listen on port " + m_port + ", " + m_sslport + "?");
1432
1433 // We want this exception to halt the entire server since in current configurations we aren't too
1434 // useful without inbound HTTP.
1435 throw e;
1436 }
1437 }
1438
1439 public void httpServerDisconnectMonitor(IHttpClientContext source, SocketError err)
1440 {
1441 switch (err)
1442 {
1443 case SocketError.NotSocket:
1444 NotSocketErrors++;
1445
1446 break;
1447 }
1448 }
1449
1450 public void httpServerException(object source, Exception exception)
1451 {
1452 m_log.ErrorFormat("[HTTPSERVER]: {0} had an exception {1}", source.ToString(), exception.ToString());
1453 /*
1454 if (HTTPDRunning)// && NotSocketErrors > 5)
1455 {
1456 Stop();
1457 Thread.Sleep(200);
1458 StartHTTP();
1459 m_log.Warn("[HTTPSERVER]: Died. Trying to kick.....");
1460 }
1461 */
1462 }
1463
1464 public void Stop()
1465 {
1466 HTTPDRunning = false;
1467 m_httpListener2.ExceptionThrown -= httpServerException;
1468 m_httpListener2.DisconnectHandler = null;
1469
1470 m_httpListener2.LogWriter = null;
1471 m_httpListener2.RequestHandler -= OnHandleRequestIOThread;
1472
1473 m_httpListener2.Stop();
1474 }
1475
1476 public void RemoveStreamHandler(string httpMethod, string path)
1477 {
1478 string handlerKey = GetHandlerKey(httpMethod, path);
1479
1480 //m_log.DebugFormat("[BASE HTTP SERVER]: Removing handler key {0}", handlerKey);
1481
1482 lock (m_streamHandlers) m_streamHandlers.Remove(handlerKey);
1483 }
1484
1485 public void RemoveHTTPHandler(string httpMethod, string path)
1486 {
1487 lock (m_HTTPHandlers)
1488 {
1489 if (httpMethod != null && httpMethod.Length == 0)
1490 {
1491 m_HTTPHandlers.Remove(path);
1492 return;
1493 }
1494
1495 m_HTTPHandlers.Remove(GetHandlerKey(httpMethod, path));
1496 }
1497 }
1498
1499 public bool RemoveAgentHandler(string agent, IHttpAgentHandler handler)
1500 {
1501 try
1502 {
1503 if (handler == m_agentHandlers[agent])
1504 {
1505 m_agentHandlers.Remove(agent);
1506 return true;
1507 }
1508 }
1509 catch(KeyNotFoundException)
1510 {
1511 }
1512
1513 return false;
1514 }
1515
1516 public bool RemoveLLSDHandler(string path, LLSDMethod handler)
1517 {
1518 try
1519 {
1520 if (handler == m_llsdHandlers[path])
1521 {
1522 m_llsdHandlers.Remove(path);
1523 return true;
1524 }
1525 }
1526 catch (KeyNotFoundException)
1527 {
1528 // This is an exception to prevent crashing because of invalid code
1529 }
1530
1531 return false;
1532 }
1533
1534 public string GetHTTP404(string host)
1535 {
1536 string file = Path.Combine(".", "http_404.html");
1537 if (!File.Exists(file))
1538 return getDefaultHTTP404(host);
1539
1540 StreamReader sr = File.OpenText(file);
1541 string result = sr.ReadToEnd();
1542 sr.Close();
1543 return result;
1544 }
1545
1546 public string GetHTTP500()
1547 {
1548 string file = Path.Combine(".", "http_500.html");
1549 if (!File.Exists(file))
1550 return getDefaultHTTP500();
1551
1552 StreamReader sr = File.OpenText(file);
1553 string result = sr.ReadToEnd();
1554 sr.Close();
1555 return result;
1556 }
1557
1558 // Fallback HTTP responses in case the HTTP error response files don't exist
1559 private static string getDefaultHTTP404(string host)
1560 {
1561 return "<HTML><HEAD><TITLE>404 Page not found</TITLE><BODY><BR /><H1>Ooops!</H1><P>The page you requested has been obsconded with by knomes. Find hippos quick!</P><P>If you are trying to log-in, your link parameters should have: &quot;-loginpage http://" + host + "/?method=login -loginuri http://" + host + "/&quot; in your link </P></BODY></HTML>";
1562 }
1563
1564 private static string getDefaultHTTP500()
1565 {
1566 return "<HTML><HEAD><TITLE>500 Internal Server Error</TITLE><BODY><BR /><H1>Ooops!</H1><P>The server you requested is overun by knomes! Find hippos quick!</P></BODY></HTML>";
1567 }
1568 }
1569
1570 public class HttpServerContextObj
1571 {
1572 public IHttpClientContext context = null;
1573 public IHttpRequest req = null;
1574 public OSHttpRequest oreq = null;
1575 public OSHttpResponse oresp = null;
1576
1577 public HttpServerContextObj(IHttpClientContext contxt, IHttpRequest reqs)
1578 {
1579 context = contxt;
1580 req = reqs;
1581 }
1582
1583 public HttpServerContextObj(OSHttpRequest osreq, OSHttpResponse osresp)
1584 {
1585 oreq = osreq;
1586 oresp = osresp;
1587 }
1588 }
1589
1590 /// <summary>
1591 /// Relays HttpServer log messages to our own logging mechanism.
1592 /// </summary>
1593 /// There is also a UseTraceLogs line in this file that can be uncommented for more detailed log information
1594 public class HttpServerLogWriter : ILogWriter
1595 {
1596 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
1597
1598 public void Write(object source, LogPrio priority, string message)
1599 {
1600 /*
1601 switch (priority)
1602 {
1603 case HttpServer.LogPrio.Debug:
1604 m_log.DebugFormat("[{0}]: {1}", source.ToString(), message);
1605 break;
1606 case HttpServer.LogPrio.Error:
1607 m_log.ErrorFormat("[{0}]: {1}", source.ToString(), message);
1608 break;
1609 case HttpServer.LogPrio.Info:
1610 m_log.InfoFormat("[{0}]: {1}", source.ToString(), message);
1611 break;
1612 case HttpServer.LogPrio.Warning:
1613 m_log.WarnFormat("[{0}]: {1}", source.ToString(), message);
1614 break;
1615 case HttpServer.LogPrio.Fatal:
1616 m_log.ErrorFormat("[{0}]: FATAL! - {1}", source.ToString(), message);
1617 break;
1618 default:
1619 break;
1620 }
1621 */
1622
1623 return;
1624 }
1625 }
1626}
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs
new file mode 100644
index 0000000..9334972
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29
30namespace OpenSim.Framework.Servers.HttpServer
31{
32 public class BaseRequestHandler
33 {
34 public virtual string ContentType
35 {
36 get { return "application/xml"; }
37 }
38
39 private readonly string m_httpMethod;
40
41 public virtual string HttpMethod
42 {
43 get { return m_httpMethod; }
44 }
45
46 private readonly string m_path;
47
48 protected BaseRequestHandler(string httpMethod, string path)
49 {
50 m_httpMethod = httpMethod;
51 m_path = path;
52 }
53
54 public virtual string Path
55 {
56 get { return m_path; }
57 }
58
59 protected string GetParam(string path)
60 {
61 try
62 {
63 return path.Substring(m_path.Length);
64 }
65 catch (Exception)
66 {
67 return String.Empty;
68 }
69 }
70 }
71}
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
new file mode 100644
index 0000000..734e3e4
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs
@@ -0,0 +1,41 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.IO;
29
30namespace OpenSim.Framework.Servers.HttpServer
31{
32 public abstract class BaseStreamHandler : BaseRequestHandler, IStreamedRequestHandler
33 {
34 public abstract byte[] Handle(string path, Stream request,
35 OSHttpRequest httpRequest, OSHttpResponse httpResponse);
36
37 protected BaseStreamHandler(string httpMethod, string path) : base(httpMethod, path)
38 {
39 }
40 }
41}
diff --git a/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs
new file mode 100644
index 0000000..fe5bcbc
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs
@@ -0,0 +1,73 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.IO;
29using System.Text;
30
31namespace OpenSim.Framework.Servers.HttpServer
32{
33 public delegate string BinaryMethod(byte[] data, string path, string param);
34
35 public class BinaryStreamHandler : BaseStreamHandler
36 {
37 private BinaryMethod m_method;
38
39 public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
40 {
41 byte[] data = ReadFully(request);
42 string param = GetParam(path);
43 string responseString = m_method(data, path, param);
44
45 return Encoding.UTF8.GetBytes(responseString);
46 }
47
48 public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod)
49 : base(httpMethod, path)
50 {
51 m_method = binaryMethod;
52 }
53
54 private static byte[] ReadFully(Stream stream)
55 {
56 byte[] buffer = new byte[32768];
57 using (MemoryStream ms = new MemoryStream())
58 {
59 while (true)
60 {
61 int read = stream.Read(buffer, 0, buffer.Length);
62
63 if (read <= 0)
64 {
65 return ms.ToArray();
66 }
67
68 ms.Write(buffer, 0, read);
69 }
70 }
71 }
72 }
73}
diff --git a/OpenSim/Framework/Servers/HttpServer/GenericHTTPMethod.cs b/OpenSim/Framework/Servers/HttpServer/GenericHTTPMethod.cs
new file mode 100644
index 0000000..060761a
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/GenericHTTPMethod.cs
@@ -0,0 +1,33 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29
30namespace OpenSim.Framework.Servers.HttpServer
31{
32 public delegate Hashtable GenericHTTPMethod(Hashtable request);
33}
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpAgentHandler.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpAgentHandler.cs
new file mode 100644
index 0000000..60c8e6e
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpAgentHandler.cs
@@ -0,0 +1,35 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28namespace OpenSim.Framework.Servers.HttpServer
29{
30 public interface IHttpAgentHandler
31 {
32 bool Handle(OSHttpRequest req, OSHttpResponse resp);
33 bool Match(OSHttpRequest req, OSHttpResponse resp);
34 }
35}
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs
new file mode 100644
index 0000000..6e3cc49
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IHttpServer.cs
@@ -0,0 +1,126 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using Nwc.XmlRpc;
29
30namespace OpenSim.Framework.Servers.HttpServer
31{
32 /// <summary>
33 /// Interface to OpenSimulator's built in HTTP server. Use this to register handlers (http, llsd, xmlrpc, etc.)
34 /// for given URLs.
35 /// </summary>
36 public interface IHttpServer
37 {
38 uint SSLPort { get; }
39 string SSLCommonName { get; }
40
41 uint Port { get; }
42 bool UseSSL { get; }
43
44 // Note that the agent string is provided simply to differentiate
45 // the handlers - it is NOT required to be an actual agent header
46 // value.
47 bool AddAgentHandler(string agent, IHttpAgentHandler handler);
48
49 /// <summary>
50 /// Add a handler for an HTTP request
51 /// </summary>
52 ///
53 /// This handler can actually be invoked either as
54 ///
55 /// http://<hostname>:<port>/?method=<methodName>
56 ///
57 /// or
58 ///
59 /// http://<hostname>:<port><method>
60 ///
61 /// if the method name starts with a slash. For example, AddHTTPHandler("/object/", ...) on a standalone region
62 /// server will register a handler that can be invoked with either
63 ///
64 /// http://localhost:9000/?method=/object/
65 ///
66 /// or
67 ///
68 /// http://localhost:9000/object/
69 ///
70 /// <param name="methodName"></param>
71 /// <param name="handler"></param>
72 /// <returns>
73 /// true if the handler was successfully registered, false if a handler with the same name already existed.
74 /// </returns>
75 bool AddHTTPHandler(string methodName, GenericHTTPMethod handler);
76
77 /// <summary>
78 /// Adds a LLSD handler, yay.
79 /// </summary>
80 /// <param name="path">/resource/ path</param>
81 /// <param name="handler">handle the LLSD response</param>
82 /// <returns></returns>
83 bool AddLLSDHandler(string path, LLSDMethod handler);
84
85 /// <summary>
86 /// Add a stream handler to the http server. If the handler already exists, then nothing happens.
87 /// </summary>
88 /// <param name="handler"></param>
89 void AddStreamHandler(IRequestHandler handler);
90
91 bool AddXmlRPCHandler(string method, XmlRpcMethod handler);
92 bool AddXmlRPCHandler(string method, XmlRpcMethod handler, bool keepAlive);
93
94 /// <summary>
95 /// Gets the XML RPC handler for given method name
96 /// </summary>
97 /// <param name="method">Name of the method</param>
98 /// <returns>Returns null if not found</returns>
99 XmlRpcMethod GetXmlRPCHandler(string method);
100
101 bool SetDefaultLLSDHandler(DefaultLLSDMethod handler);
102
103 /// <summary>
104 /// Remove the agent if it is registered.
105 /// </summary>
106 /// <param name="agent"></param>
107 /// <param name="handler"></param>
108 /// <returns></returns>
109 bool RemoveAgentHandler(string agent, IHttpAgentHandler handler);
110
111 /// <summary>
112 /// Remove an HTTP handler
113 /// </summary>
114 /// <param name="httpMethod"></param>
115 /// <param name="path"></param>
116 void RemoveHTTPHandler(string httpMethod, string path);
117
118 bool RemoveLLSDHandler(string path, LLSDMethod handler);
119
120 void RemoveStreamHandler(string httpMethod, string path);
121
122 string GetHTTP404(string host);
123
124 string GetHTTP500();
125 }
126}
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs
new file mode 100644
index 0000000..6e27aba
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs
@@ -0,0 +1,61 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using System.IO;
30
31namespace OpenSim.Framework.Servers.HttpServer
32{
33 public interface IRequestHandler
34 {
35 // Return response content type
36 string ContentType { get; }
37
38 // Return required http method
39 string HttpMethod { get; }
40
41 // Return path
42 string Path { get; }
43 }
44
45 public interface IStreamedRequestHandler : IRequestHandler
46 {
47 // Handle request stream, return byte array
48 byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse);
49 }
50
51 public interface IStreamHandler : IRequestHandler
52 {
53 // Handle request stream, return byte array
54 void Handle(string path, Stream request, Stream response, OSHttpRequest httpReqbuest, OSHttpResponse httpResponse);
55 }
56
57 public interface IGenericHTTPHandler : IRequestHandler
58 {
59 Hashtable Handle(string path, Hashtable request);
60 }
61}
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/OpenSim.Framework.Servers.Interfaces.csproj b/OpenSim/Framework/Servers/HttpServer/Interfaces/OpenSim.Framework.Servers.Interfaces.csproj
new file mode 100644
index 0000000..e8700f1
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/OpenSim.Framework.Servers.Interfaces.csproj
@@ -0,0 +1,120 @@
1<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
2 <PropertyGroup>
3 <ProjectType>Local</ProjectType>
4 <ProductVersion>8.0.50727</ProductVersion>
5 <SchemaVersion>2.0</SchemaVersion>
6 <ProjectGuid>{8673D009-0000-0000-0000-000000000000}</ProjectGuid>
7 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
8 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
9 <ApplicationIcon></ApplicationIcon>
10 <AssemblyKeyContainerName>
11 </AssemblyKeyContainerName>
12 <AssemblyName>OpenSim.Framework.Servers.Interfaces</AssemblyName>
13 <DefaultClientScript>JScript</DefaultClientScript>
14 <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
15 <DefaultTargetSchema>IE50</DefaultTargetSchema>
16 <DelaySign>false</DelaySign>
17 <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
18 <OutputType>Library</OutputType>
19 <AppDesignerFolder></AppDesignerFolder>
20 <RootNamespace>OpenSim.Framework.Servers.Interfaces</RootNamespace>
21 <StartupObject></StartupObject>
22 <StartArguments></StartArguments>
23 <FileUpgradeFlags>
24 </FileUpgradeFlags>
25 </PropertyGroup>
26 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
27 <AllowUnsafeBlocks>False</AllowUnsafeBlocks>
28 <BaseAddress>285212672</BaseAddress>
29 <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
30 <ConfigurationOverrideFile>
31 </ConfigurationOverrideFile>
32 <DefineConstants>TRACE;DEBUG</DefineConstants>
33 <DocumentationFile></DocumentationFile>
34 <DebugSymbols>True</DebugSymbols>
35 <FileAlignment>4096</FileAlignment>
36 <Optimize>False</Optimize>
37 <OutputPath>../../../../bin/</OutputPath>
38 <RegisterForComInterop>False</RegisterForComInterop>
39 <RemoveIntegerChecks>False</RemoveIntegerChecks>
40 <TreatWarningsAsErrors>False</TreatWarningsAsErrors>
41 <WarningLevel>4</WarningLevel>
42 <NoStdLib>False</NoStdLib>
43 <NoWarn></NoWarn>
44 </PropertyGroup>
45 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
46 <AllowUnsafeBlocks>False</AllowUnsafeBlocks>
47 <BaseAddress>285212672</BaseAddress>
48 <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
49 <ConfigurationOverrideFile>
50 </ConfigurationOverrideFile>
51 <DefineConstants>TRACE</DefineConstants>
52 <DocumentationFile></DocumentationFile>
53 <DebugSymbols>False</DebugSymbols>
54 <FileAlignment>4096</FileAlignment>
55 <Optimize>True</Optimize>
56 <OutputPath>../../../../bin/</OutputPath>
57 <RegisterForComInterop>False</RegisterForComInterop>
58 <RemoveIntegerChecks>False</RemoveIntegerChecks>
59 <TreatWarningsAsErrors>False</TreatWarningsAsErrors>
60 <WarningLevel>4</WarningLevel>
61 <NoStdLib>False</NoStdLib>
62 <NoWarn></NoWarn>
63 </PropertyGroup>
64 <ItemGroup>
65 <Reference Include="HttpServer_OpenSim.dll" >
66 <Name>HttpServer_OpenSim.dll</Name>
67 <Private>False</Private>
68 </Reference>
69 <Reference Include="log4net.dll" >
70 <Name>log4net.dll</Name>
71 <Private>False</Private>
72 </Reference>
73 <Reference Include="OpenMetaverse.StructuredData.dll" >
74 <Name>OpenMetaverse.StructuredData.dll</Name>
75 <Private>False</Private>
76 </Reference>
77 <Reference Include="OpenMetaverseTypes.dll" >
78 <Name>OpenMetaverseTypes.dll</Name>
79 <Private>False</Private>
80 </Reference>
81 <Reference Include="System" >
82 <Name>System</Name>
83 <Private>False</Private>
84 </Reference>
85 <Reference Include="System.Xml" >
86 <Name>System.Xml</Name>
87 <Private>False</Private>
88 </Reference>
89 <Reference Include="XMLRPC.dll" >
90 <Name>XMLRPC.dll</Name>
91 <Private>False</Private>
92 </Reference>
93 </ItemGroup>
94 <ItemGroup>
95 <ProjectReference Include="../../../Data/OpenSim.Data.csproj">
96 <Name>OpenSim.Data</Name>
97 <Project>{B75A430B-0000-0000-0000-000000000000}</Project>
98 <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
99 <Private>False</Private>
100 </ProjectReference>
101 </ItemGroup>
102 <ItemGroup>
103 <Compile Include="IHttpAgentHandler.cs">
104 <SubType>Code</SubType>
105 </Compile>
106 <Compile Include="IHttpServer.cs">
107 <SubType>Code</SubType>
108 </Compile>
109 <Compile Include="IStreamHandler.cs">
110 <SubType>Code</SubType>
111 </Compile>
112 </ItemGroup>
113 <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
114 <PropertyGroup>
115 <PreBuildEvent>
116 </PreBuildEvent>
117 <PostBuildEvent>
118 </PostBuildEvent>
119 </PropertyGroup>
120</Project>
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/OpenSim.Framework.Servers.Interfaces.csproj.user b/OpenSim/Framework/Servers/HttpServer/Interfaces/OpenSim.Framework.Servers.Interfaces.csproj.user
new file mode 100644
index 0000000..b73b33f
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/OpenSim.Framework.Servers.Interfaces.csproj.user
@@ -0,0 +1,12 @@
1<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <PropertyGroup>
3 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <ReferencePath>/root/opensim-commit/bin/</ReferencePath>
6 <LastOpenVersion>8.0.50727</LastOpenVersion>
7 <ProjectView>ProjectFiles</ProjectView>
8 <ProjectTrust>0</ProjectTrust>
9 </PropertyGroup>
10 <PropertyGroup Condition = " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
11 <PropertyGroup Condition = " '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
12</Project>
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/OpenSim.Framework.Servers.Interfaces.dll.build b/OpenSim/Framework/Servers/HttpServer/Interfaces/OpenSim.Framework.Servers.Interfaces.dll.build
new file mode 100644
index 0000000..102300f
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/OpenSim.Framework.Servers.Interfaces.dll.build
@@ -0,0 +1,54 @@
1<?xml version="1.0" ?>
2<project name="OpenSim.Framework.Servers.Interfaces" default="build">
3 <target name="build">
4 <echo message="Build Directory is ${project::get-base-directory()}/${build.dir}" />
5 <mkdir dir="${project::get-base-directory()}/${build.dir}" />
6 <copy todir="${project::get-base-directory()}/${build.dir}" flatten="true">
7 <fileset basedir="${project::get-base-directory()}">
8 </fileset>
9 </copy>
10 <copy todir="${project::get-base-directory()}/${build.dir}">
11 <fileset basedir=".">
12 </fileset>
13 </copy>
14 <csc target="library" debug="${build.debug}" unsafe="False" warnaserror="False" define="TRACE;DEBUG" nostdlib="False" main="" output="${project::get-base-directory()}/${build.dir}/${project::get-name()}.dll">
15 <resources prefix="OpenSim.Framework.Servers.Interfaces" dynamicprefix="true" >
16 </resources>
17 <sources failonempty="true">
18 <include name="IHttpAgentHandler.cs" />
19 <include name="IHttpServer.cs" />
20 <include name="IStreamHandler.cs" />
21 </sources>
22 <references basedir="${project::get-base-directory()}">
23 <lib>
24 <include name="${project::get-base-directory()}" />
25 <include name="${project::get-base-directory()}/../../../../bin" />
26 </lib>
27 <include name="../../../../bin/HttpServer_OpenSim.dll" />
28 <include name="../../../../bin/log4net.dll" />
29 <include name="../../../../bin/OpenMetaverse.StructuredData.dll" />
30 <include name="../../../../bin/OpenMetaverseTypes.dll" />
31 <include name="OpenSim.Data.dll" />
32 <include name="System.dll" />
33 <include name="System.Xml.dll" />
34 <include name="../../../../bin/XMLRPC.dll" />
35 </references>
36 </csc>
37 <echo message="Copying from [${project::get-base-directory()}/${build.dir}/] to [${project::get-base-directory()}/../../../../bin/" />
38 <mkdir dir="${project::get-base-directory()}/../../../../bin/"/>
39 <copy todir="${project::get-base-directory()}/../../../../bin/">
40 <fileset basedir="${project::get-base-directory()}/${build.dir}/" >
41 <include name="*.dll"/>
42 <include name="*.exe"/>
43 <include name="*.mdb" if='${build.debug}'/>
44 <include name="*.pdb" if='${build.debug}'/>
45 </fileset>
46 </copy>
47 </target>
48 <target name="clean">
49 <delete dir="${bin.dir}" failonerror="false" />
50 <delete dir="${obj.dir}" failonerror="false" />
51 </target>
52 <target name="doc" description="Creates documentation.">
53 </target>
54</project>
diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/OpenSim.Framework.Servers.Interfaces.mdp b/OpenSim/Framework/Servers/HttpServer/Interfaces/OpenSim.Framework.Servers.Interfaces.mdp
new file mode 100644
index 0000000..96f6b46
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/OpenSim.Framework.Servers.Interfaces.mdp
@@ -0,0 +1,34 @@
1<Project name="OpenSim.Framework.Servers.Interfaces" description="" standardNamespace="OpenSim.Framework.Servers.Interfaces" newfilesearch="None" enableviewstate="True" fileversion="2.0" language="C#" clr-version="Net_2_0" ctype="DotNetProject">
2 <Configurations active="Debug">
3 <Configuration name="Debug" ctype="DotNetProjectConfiguration">
4 <Output directory="./../../../../bin/" assembly="OpenSim.Framework.Servers.Interfaces" executeScript="" executeBeforeBuild="" executeAfterBuild="" executeBeforeBuildArguments="" executeAfterBuildArguments="" />
5 <Build debugmode="True" target="Library" />
6 <Execution runwithwarnings="True" consolepause="True" runtime="MsNet" clr-version="Net_2_0" />
7 <CodeGeneration compiler="Csc" warninglevel="4" nowarn="" includedebuginformation="True" optimize="False" unsafecodeallowed="False" generateoverflowchecks="False" mainclass="" target="Library" definesymbols="TRACE;DEBUG" generatexmldocumentation="False" win32Icon="" ctype="CSharpCompilerParameters" />
8 </Configuration>
9 <Configuration name="Release" ctype="DotNetProjectConfiguration">
10 <Output directory="./../../../../bin/" assembly="OpenSim.Framework.Servers.Interfaces" executeScript="" executeBeforeBuild="" executeAfterBuild="" executeBeforeBuildArguments="" executeAfterBuildArguments="" />
11 <Build debugmode="True" target="Library" />
12 <Execution runwithwarnings="True" consolepause="True" runtime="MsNet" clr-version="Net_2_0" />
13 <CodeGeneration compiler="Csc" warninglevel="4" nowarn="" includedebuginformation="False" optimize="True" unsafecodeallowed="False" generateoverflowchecks="False" mainclass="" target="Library" definesymbols="TRACE" generatexmldocumentation="False" win32Icon="" ctype="CSharpCompilerParameters" />
14 </Configuration>
15 </Configurations>
16 <DeploymentInformation target="" script="" strategy="File">
17 <excludeFiles />
18 </DeploymentInformation>
19 <Contents>
20 <File name="./IHttpAgentHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
21 <File name="./IHttpServer.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
22 <File name="./IStreamHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
23 </Contents>
24 <References>
25 <ProjectReference type="Assembly" refto="../../../../bin/HttpServer_OpenSim.dll" localcopy="False" />
26 <ProjectReference type="Assembly" refto="../../../../bin/log4net.dll" localcopy="False" />
27 <ProjectReference type="Assembly" refto="../../../../bin/OpenMetaverse.StructuredData.dll" localcopy="False" />
28 <ProjectReference type="Assembly" refto="../../../../bin/OpenMetaverseTypes.dll" localcopy="False" />
29 <ProjectReference type="Project" localcopy="False" refto="OpenSim.Data" />
30 <ProjectReference type="Gac" localcopy="False" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
31 <ProjectReference type="Gac" localcopy="False" refto="System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
32 <ProjectReference type="Assembly" refto="../../../../bin/XMLRPC.dll" localcopy="False" />
33 </References>
34</Project>
diff --git a/OpenSim/Framework/Servers/HttpServer/LLSDMethod.cs b/OpenSim/Framework/Servers/HttpServer/LLSDMethod.cs
new file mode 100644
index 0000000..d669182
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/LLSDMethod.cs
@@ -0,0 +1,34 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse.StructuredData;
29
30namespace OpenSim.Framework.Servers.HttpServer
31{
32 public delegate OSD LLSDMethod( string path, OSD request, string endpoint );
33 public delegate OSD DefaultLLSDMethod(OSD request);
34}
diff --git a/OpenSim/Framework/Servers/HttpServer/LLSDMethodString.cs b/OpenSim/Framework/Servers/HttpServer/LLSDMethodString.cs
new file mode 100644
index 0000000..61def78
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/LLSDMethodString.cs
@@ -0,0 +1,33 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse.StructuredData;
29
30namespace OpenSim.Framework.Servers.HttpServer
31{
32 public delegate OSD LLSDMethodString(OSD request, string thePath);
33}
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpHandler.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpHandler.cs
new file mode 100644
index 0000000..f1788a0
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpHandler.cs
@@ -0,0 +1,183 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Text.RegularExpressions;
32
33namespace OpenSim.Framework.Servers.HttpServer
34{
35 /// <sumary>
36 /// Any OSHttpHandler must return one of the following results:
37 /// <list type = "table">
38 /// <listheader>
39 /// <term>result code</term>
40 /// <description>meaning</description>
41 /// </listheader>
42 /// <item>
43 /// <term>Pass</term>
44 /// <description>handler did not process the request</request>
45 /// </item>
46 /// <item>
47 /// <term>Done</term>
48 /// <description>handler did process the request, OSHttpServer
49 /// can clean up and close the request</request>
50 /// </item>
51 /// </list>
52 /// </summary>
53 public enum OSHttpHandlerResult
54 {
55 Unprocessed,
56 Pass,
57 Done,
58 }
59
60 /// <summary>
61 /// An OSHttpHandler that matches on the "content-type" header can
62 /// supply an OSHttpContentTypeChecker delegate which will be
63 /// invoked by the request matcher in OSHttpRequestPump.
64 /// </summary>
65 /// <returns>true if the handler is interested in the content;
66 /// false otherwise</returns>
67 public delegate bool OSHttpContentTypeChecker(OSHttpRequest req);
68
69 public abstract class OSHttpHandler
70 {
71 /// <summary>
72 /// Regular expression used to match against method of
73 /// the incoming HTTP request. If you want to match any string
74 /// either use '.*' or null. To match on the empty string use
75 /// '^$'.
76 /// </summary>
77 public virtual Regex Method
78 {
79 get { return _method; }
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;
94
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>
106 /// Dictionary of (header name, regular expression) tuples,
107 /// allowing us to match on HTTP header fields.
108 /// </summary>
109 public virtual Dictionary<string, Regex> Headers
110 {
111 get { return _headers; }
112 }
113 protected Dictionary<string, Regex> _headers;
114
115 /// <summary>
116 /// Dictionary of (header name, regular expression) tuples,
117 /// allowing us to match on HTTP header fields.
118 /// </summary>
119 /// <remarks>
120 /// This feature is currently not implemented as it requires
121 /// (trivial) changes to HttpServer.HttpListener that have not
122 /// been implemented.
123 /// </remarks>
124 public virtual Regex IPEndPointWhitelist
125 {
126 get { return _ipEndPointRegex; }
127 }
128 protected Regex _ipEndPointRegex;
129
130
131 /// <summary>
132 /// Base class constructor.
133 /// </summary>
134 /// <param name="path">null or path regex</param>
135 /// <param name="headers">null or dictionary of header
136 /// regexs</param>
137 /// <param name="contentType">null or content type
138 /// regex</param>
139 /// <param name="whitelist">null or IP address regex</param>
140 public OSHttpHandler(Regex method, Regex path, Dictionary<string, Regex> query,
141 Dictionary<string, Regex> headers, Regex contentType, Regex whitelist)
142 {
143 _method = method;
144 _path = path;
145 _query = query;
146 _ipEndPointRegex = whitelist;
147
148 if (null == _headers && null != contentType)
149 {
150 _headers = new Dictionary<string, Regex>();
151 _headers.Add("content-type", contentType);
152 }
153 }
154
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 }
182 }
183}
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpHttpHandler.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpHttpHandler.cs
new file mode 100644
index 0000000..09d6f52
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpHttpHandler.cs
@@ -0,0 +1,145 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.IO;
32using System.Net;
33using System.Reflection;
34using System.Text;
35using System.Text.RegularExpressions;
36using System.Xml;
37using log4net;
38using Nwc.XmlRpc;
39
40namespace OpenSim.Framework.Servers.HttpServer
41{
42 public delegate XmlRpcResponse OSHttpHttpProcessor(XmlRpcRequest request);
43
44 public class OSHttpHttpHandler: OSHttpHandler
45 {
46 private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 // contains handler for processing HTTP Request
49 private GenericHTTPMethod _handler;
50
51 /// <summary>
52 /// Instantiate an HTTP handler.
53 /// </summary>
54 /// <param name="handler">a GenericHTTPMethod</param>
55 /// <param name="method">null or HTTP method regex</param>
56 /// <param name="path">null or path regex</param>
57 /// <param name="query">null or dictionary with query regexs</param>
58 /// <param name="headers">null or dictionary with header
59 /// regexs</param>
60 /// <param name="whitelist">null or IP address whitelist</param>
61 public OSHttpHttpHandler(GenericHTTPMethod handler, Regex method, Regex path,
62 Dictionary<string, Regex> query,
63 Dictionary<string, Regex> headers, Regex whitelist)
64 : base(method, path, query, headers, new Regex(@"^text/html", RegexOptions.IgnoreCase | RegexOptions.Compiled),
65 whitelist)
66 {
67 _handler = handler;
68 }
69
70 /// <summary>
71 /// Instantiate an HTTP handler.
72 /// </summary>
73 /// <param name="handler">a GenericHTTPMethod</param>
74 public OSHttpHttpHandler(GenericHTTPMethod handler)
75 : this(handler, new Regex(@"^GET$", RegexOptions.IgnoreCase | RegexOptions.Compiled), null, null, null, null)
76 {
77 }
78
79 /// <summary>
80 /// Invoked by OSHttpRequestPump.
81 /// </summary>
82 public override OSHttpHandlerResult Process(OSHttpRequest request)
83 {
84 // call handler method
85 Hashtable responseData = _handler(request.Query);
86
87 int responseCode = (int)responseData["int_response_code"];
88 string responseString = (string)responseData["str_response_string"];
89 string contentType = (string)responseData["content_type"];
90
91 //Even though only one other part of the entire code uses HTTPHandlers, we shouldn't expect this
92 //and should check for NullReferenceExceptions
93
94 if (string.IsNullOrEmpty(contentType))
95 {
96 contentType = "text/html";
97 }
98
99 OSHttpResponse response = new OSHttpResponse(request);
100
101 // We're forgoing the usual error status codes here because the client
102 // ignores anything but 200 and 301
103
104 response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
105
106 if (responseCode == (int)OSHttpStatusCode.RedirectMovedPermanently)
107 {
108 response.RedirectLocation = (string)responseData["str_redirect_location"];
109 response.StatusCode = responseCode;
110 }
111
112 response.AddHeader("Content-type", contentType);
113
114 byte[] buffer;
115
116 if (!contentType.Contains("image"))
117 {
118 buffer = Encoding.UTF8.GetBytes(responseString);
119 }
120 else
121 {
122 buffer = Convert.FromBase64String(responseString);
123 }
124
125 response.SendChunked = false;
126 response.ContentLength64 = buffer.Length;
127 response.ContentEncoding = Encoding.UTF8;
128
129 try
130 {
131 response.Body.Write(buffer, 0, buffer.Length);
132 }
133 catch (Exception ex)
134 {
135 _log.ErrorFormat("[OSHttpHttpHandler]: Error: {0}", ex.Message);
136 }
137 finally
138 {
139 response.Send();
140 }
141
142 return OSHttpHandlerResult.Done;
143 }
144 }
145}
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
new file mode 100644
index 0000000..0ca868c
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpRequest.cs
@@ -0,0 +1,228 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Collections.Specialized;
32using System.IO;
33using System.Net;
34using System.Reflection;
35using System.Text;
36using HttpServer;
37using log4net;
38
39namespace OpenSim.Framework.Servers.HttpServer
40{
41 public class OSHttpRequest
42 {
43 private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44
45 protected IHttpRequest _request = null;
46 protected IHttpClientContext _context = null;
47
48 public string[] AcceptTypes
49 {
50 get { return _request.AcceptTypes; }
51 }
52
53 public Encoding ContentEncoding
54 {
55 get { return _contentEncoding; }
56 }
57 private Encoding _contentEncoding;
58
59 public long ContentLength
60 {
61 get { return _request.ContentLength; }
62 }
63
64 public long ContentLength64
65 {
66 get { return ContentLength; }
67 }
68
69 public string ContentType
70 {
71 get { return _contentType; }
72 }
73 private string _contentType;
74
75 public bool HasEntityBody
76 {
77 get { return _request.ContentLength != 0; }
78 }
79
80 public NameValueCollection Headers
81 {
82 get { return _request.Headers; }
83 }
84
85 public string HttpMethod
86 {
87 get { return _request.Method; }
88 }
89
90 public Stream InputStream
91 {
92 get { return _request.Body; }
93 }
94
95 public bool IsSecured
96 {
97 get { return _context.Secured; }
98 }
99
100 public bool KeepAlive
101 {
102 get { return ConnectionType.KeepAlive == _request.Connection; }
103 }
104
105 public NameValueCollection QueryString
106 {
107 get { return _queryString; }
108 }
109 private NameValueCollection _queryString;
110
111 public Hashtable Query
112 {
113 get { return _query; }
114 }
115 private Hashtable _query;
116
117 public string RawUrl
118 {
119 get { return _request.Uri.AbsolutePath; }
120 }
121
122 public IPEndPoint RemoteIPEndPoint
123 {
124 get { return _remoteIPEndPoint; }
125 }
126 private IPEndPoint _remoteIPEndPoint;
127
128 public Uri Url
129 {
130 get { return _request.Uri; }
131 }
132
133 public string UserAgent
134 {
135 get { return _userAgent; }
136 }
137 private string _userAgent;
138
139 internal IHttpRequest IHttpRequest
140 {
141 get { return _request; }
142 }
143
144 internal IHttpClientContext IHttpClientContext
145 {
146 get { return _context; }
147 }
148
149 /// <summary>
150 /// Internal whiteboard for handlers to store temporary stuff
151 /// into.
152 /// </summary>
153 internal Dictionary<string, object> Whiteboard
154 {
155 get { return _whiteboard; }
156 }
157 private Dictionary<string, object> _whiteboard = new Dictionary<string, object>();
158
159
160 public OSHttpRequest() {}
161
162 public OSHttpRequest(IHttpClientContext context, IHttpRequest req)
163 {
164 _request = req;
165 _context = context;
166
167 if (null != req.Headers["content-encoding"])
168 _contentEncoding = Encoding.GetEncoding(_request.Headers["content-encoding"]);
169 if (null != req.Headers["content-type"])
170 _contentType = _request.Headers["content-type"];
171 if (null != req.Headers["user-agent"])
172 _userAgent = req.Headers["user-agent"];
173 if (null != req.Headers["remote_addr"])
174 {
175 try
176 {
177 IPAddress addr = IPAddress.Parse(req.Headers["remote_addr"]);
178 int port = Int32.Parse(req.Headers["remote_port"]);
179 _remoteIPEndPoint = new IPEndPoint(addr, port);
180 }
181 catch (FormatException)
182 {
183 _log.ErrorFormat("[OSHttpRequest]: format exception on addr/port {0}:{1}, ignoring",
184 req.Headers["remote_addr"], req.Headers["remote_port"]);
185 }
186 }
187
188 _queryString = new NameValueCollection();
189 _query = new Hashtable();
190 try
191 {
192 foreach (HttpInputItem item in req.QueryString)
193 {
194 try
195 {
196 _queryString.Add(item.Name, item.Value);
197 _query[item.Name] = item.Value;
198 }
199 catch (InvalidCastException)
200 {
201 _log.DebugFormat("[OSHttpRequest]: error parsing {0} query item, skipping it", item.Name);
202 continue;
203 }
204 }
205 }
206 catch (Exception)
207 {
208 _log.ErrorFormat("[OSHttpRequest]: Error parsing querystring");
209 }
210 }
211
212 public override string ToString()
213 {
214 StringBuilder me = new StringBuilder();
215 me.Append(String.Format("OSHttpRequest: {0} {1}\n", HttpMethod, RawUrl));
216 foreach (string k in Headers.AllKeys)
217 {
218 me.Append(String.Format(" {0}: {1}\n", k, Headers[k]));
219 }
220 if (null != RemoteIPEndPoint)
221 {
222 me.Append(String.Format(" IP: {0}\n", RemoteIPEndPoint));
223 }
224
225 return me.ToString();
226 }
227 }
228}
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpRequestPump.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpRequestPump.cs
new file mode 100644
index 0000000..893fa1b
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpRequestPump.cs
@@ -0,0 +1,298 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28// #define DEBUGGING
29
30using System;
31using System.Collections.Generic;
32using System.Collections.Specialized;
33using System.Diagnostics;
34using System.IO;
35using System.Net;
36using System.Reflection;
37using System.Text.RegularExpressions;
38using System.Threading;
39using log4net;
40using HttpServer;
41
42namespace OpenSim.Framework.Servers.HttpServer
43{
44 /// <summary>
45 /// An OSHttpRequestPump fetches incoming OSHttpRequest objects
46 /// from the OSHttpRequestQueue and feeds them to all subscribed
47 /// parties. Each OSHttpRequestPump encapsulates one thread to do
48 /// the work and there is a fixed number of pumps for each
49 /// OSHttpServer object.
50 /// </summary>
51 public class OSHttpRequestPump
52 {
53 private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
55 protected OSHttpServer _server;
56 protected OSHttpRequestQueue _queue;
57 protected Thread _engine;
58
59 private int _id;
60
61 public string EngineID
62 {
63 get { return String.Format("{0} pump {1}", _server.EngineID, _id); }
64 }
65
66 public OSHttpRequestPump(OSHttpServer server, OSHttpRequestQueue queue, int id)
67 {
68 _server = server;
69 _queue = queue;
70 _id = id;
71
72 _engine = new Thread(new ThreadStart(Engine));
73 _engine.Name = EngineID;
74 _engine.IsBackground = true;
75 _engine.Start();
76
77 ThreadTracker.Add(_engine);
78 }
79
80 public static OSHttpRequestPump[] Pumps(OSHttpServer server, OSHttpRequestQueue queue, int poolSize)
81 {
82 OSHttpRequestPump[] pumps = new OSHttpRequestPump[poolSize];
83 for (int i = 0; i < pumps.Length; i++)
84 {
85 pumps[i] = new OSHttpRequestPump(server, queue, i);
86 }
87
88 return pumps;
89 }
90
91 public void Start()
92 {
93 _engine = new Thread(new ThreadStart(Engine));
94 _engine.Name = EngineID;
95 _engine.IsBackground = true;
96 _engine.Start();
97
98 ThreadTracker.Add(_engine);
99 }
100
101 public void Engine()
102 {
103 OSHttpRequest req = null;
104
105 while (true)
106 {
107 try
108 {
109 // dequeue an OSHttpRequest from OSHttpServer's
110 // request queue
111 req = _queue.Dequeue();
112
113 // get a copy of the list of registered handlers
114 List<OSHttpHandler> handlers = _server.OSHttpHandlers;
115
116 // prune list and have it sorted from most
117 // specific to least specific
118 handlers = MatchHandlers(req, handlers);
119
120 // process req: we try each handler in turn until
121 // we are either out of handlers or get back a
122 // Pass or Done
123 OSHttpHandlerResult rc = OSHttpHandlerResult.Unprocessed;
124 foreach (OSHttpHandler h in handlers)
125 {
126 rc = h.Process(req);
127
128 // Pass: handler did not process the request,
129 // try next handler
130 if (OSHttpHandlerResult.Pass == rc) continue;
131
132 // Handled: handler has processed the request
133 if (OSHttpHandlerResult.Done == rc) break;
134
135 // hmm, something went wrong
136 throw new Exception(String.Format("[{0}] got unexpected OSHttpHandlerResult {1}", EngineID, rc));
137 }
138
139 if (OSHttpHandlerResult.Unprocessed == rc)
140 {
141 _log.InfoFormat("[{0}] OSHttpHandler: no handler registered for {1}", EngineID, req);
142
143 // set up response header
144 OSHttpResponse resp = new OSHttpResponse(req);
145 resp.StatusCode = (int)OSHttpStatusCode.ClientErrorNotFound;
146 resp.StatusDescription = String.Format("no handler on call for {0}", req);
147 resp.ContentType = "text/html";
148
149 // add explanatory message
150 StreamWriter body = new StreamWriter(resp.Body);
151 body.WriteLine("<html>");
152 body.WriteLine("<header><title>Ooops...</title><header>");
153 body.WriteLine(String.Format("<body><p>{0}</p></body>", resp.StatusDescription));
154 body.WriteLine("</html>");
155 body.Flush();
156
157 // and ship it back
158 resp.Send();
159 }
160 }
161 catch (Exception e)
162 {
163 _log.DebugFormat("[{0}] OSHttpHandler problem: {1}", EngineID, e.ToString());
164 _log.ErrorFormat("[{0}] OSHttpHandler problem: {1}", EngineID, e.Message);
165 }
166 }
167 }
168
169 protected List<OSHttpHandler> MatchHandlers(OSHttpRequest req, List<OSHttpHandler> handlers)
170 {
171 Dictionary<OSHttpHandler, int> scoredHandlers = new Dictionary<OSHttpHandler, int>();
172
173 _log.DebugFormat("[{0}] MatchHandlers for {1}", EngineID, req);
174 foreach (OSHttpHandler h in handlers)
175 {
176 // initial anchor
177 scoredHandlers[h] = 0;
178
179 // first, check whether IPEndPointWhitelist applies
180 // and, if it does, whether client is on that white
181 // list.
182 if (null != h.IPEndPointWhitelist)
183 {
184 // TODO: following code requires code changes to
185 // HttpServer.HttpRequest to become functional
186
187 IPEndPoint remote = req.RemoteIPEndPoint;
188 if (null != remote)
189 {
190 Match epm = h.IPEndPointWhitelist.Match(remote.ToString());
191 if (!epm.Success)
192 {
193 scoredHandlers.Remove(h);
194 continue;
195 }
196 }
197 }
198
199 if (null != h.Method)
200 {
201 Match m = h.Method.Match(req.HttpMethod);
202 if (!m.Success)
203 {
204 scoredHandlers.Remove(h);
205 continue;
206 }
207 scoredHandlers[h]++;
208 }
209
210 // whitelist ok, now check path
211 if (null != h.Path)
212 {
213 Match m = h.Path.Match(req.RawUrl);
214 if (!m.Success)
215 {
216 scoredHandlers.Remove(h);
217 continue;
218 }
219 scoredHandlers[h] += m.ToString().Length;
220 }
221
222 // whitelist & path ok, now check query string
223 if (null != h.Query)
224 {
225 int queriesMatch = MatchOnNameValueCollection(req.QueryString, h.Query);
226 if (0 == queriesMatch)
227 {
228 _log.DebugFormat("[{0}] request {1}", EngineID, req);
229 _log.DebugFormat("[{0}] dropping handler {1}", EngineID, h);
230
231 scoredHandlers.Remove(h);
232 continue;
233 }
234 scoredHandlers[h] += queriesMatch;
235 }
236
237 // whitelist, path, query string ok, now check headers
238 if (null != h.Headers)
239 {
240 int headersMatch = MatchOnNameValueCollection(req.Headers, h.Headers);
241 if (0 == headersMatch)
242 {
243 _log.DebugFormat("[{0}] request {1}", EngineID, req);
244 _log.DebugFormat("[{0}] dropping handler {1}", EngineID, h);
245
246 scoredHandlers.Remove(h);
247 continue;
248 }
249 scoredHandlers[h] += headersMatch;
250 }
251 }
252
253 List<OSHttpHandler> matchingHandlers = new List<OSHttpHandler>(scoredHandlers.Keys);
254 matchingHandlers.Sort(delegate(OSHttpHandler x, OSHttpHandler y)
255 {
256 return scoredHandlers[x] - scoredHandlers[y];
257 });
258 LogDumpHandlerList(matchingHandlers);
259 return matchingHandlers;
260 }
261
262 protected int MatchOnNameValueCollection(NameValueCollection collection, Dictionary<string, Regex> regexs)
263 {
264 int matched = 0;
265
266 foreach (string tag in regexs.Keys)
267 {
268 // do we have a header "tag"?
269 if (null == collection[tag])
270 {
271 return 0;
272 }
273
274 // does the content of collection[tag] match
275 // the supplied regex?
276 Match cm = regexs[tag].Match(collection[tag]);
277 if (!cm.Success)
278 {
279 return 0;
280 }
281
282 // ok: matches
283 matched++;
284 continue;
285 }
286
287 return matched;
288 }
289
290 [ConditionalAttribute("DEBUGGING")]
291 private void LogDumpHandlerList(List<OSHttpHandler> l)
292 {
293 _log.DebugFormat("[{0}] OSHttpHandlerList dump:", EngineID);
294 foreach (OSHttpHandler h in l)
295 _log.DebugFormat(" ", h.ToString());
296 }
297 }
298}
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpRequestQueue.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpRequestQueue.cs
new file mode 100644
index 0000000..4e34b41
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpRequestQueue.cs
@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Threading;
31using HttpServer;
32
33namespace OpenSim.Framework.Servers.HttpServer
34{
35 /// <summary>
36 /// OSHttpRequestQueues are used to hand over incoming HTTP
37 /// requests to OSHttpRequestPump objects.
38 /// </summary>
39 public class OSHttpRequestQueue : Queue<OSHttpRequest>
40 {
41 private object _syncObject = new object();
42
43 new public void Enqueue(OSHttpRequest req)
44 {
45 lock (_syncObject)
46 {
47 base.Enqueue(req);
48 Monitor.Pulse(_syncObject);
49 }
50 }
51
52 new public OSHttpRequest Dequeue()
53 {
54 OSHttpRequest req = null;
55
56 lock (_syncObject)
57 {
58 while (null == req)
59 {
60 Monitor.Wait(_syncObject);
61 if (0 != this.Count) req = base.Dequeue();
62 }
63 }
64
65 return req;
66 }
67 }
68}
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs
new file mode 100644
index 0000000..210d122
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs
@@ -0,0 +1,302 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.IO;
29using System.Net;
30using System.Text;
31using HttpServer;
32
33namespace OpenSim.Framework.Servers.HttpServer
34{
35 /// <summary>
36 /// OSHttpResponse is the OpenSim representation of an HTTP
37 /// response.
38 /// </summary>
39 public class OSHttpResponse
40 {
41 /// <summary>
42 /// Content type property.
43 /// </summary>
44 /// <remarks>
45 /// Setting this property will also set IsContentTypeSet to
46 /// true.
47 /// </remarks>
48 public string ContentType
49 {
50 get
51 {
52 return _httpResponse.ContentType;
53 }
54
55 set
56 {
57 _httpResponse.ContentType = value;
58 }
59 }
60
61 /// <summary>
62 /// Boolean property indicating whether the content type
63 /// property actively has been set.
64 /// </summary>
65 /// <remarks>
66 /// IsContentTypeSet will go away together with .NET base.
67 /// </remarks>
68 // public bool IsContentTypeSet
69 // {
70 // get { return _contentTypeSet; }
71 // }
72 // private bool _contentTypeSet;
73
74
75 /// <summary>
76 /// Length of the body content; 0 if there is no body.
77 /// </summary>
78 public long ContentLength
79 {
80 get
81 {
82 return _httpResponse.ContentLength;
83 }
84
85 set
86 {
87 _httpResponse.ContentLength = value;
88 }
89 }
90
91 /// <summary>
92 /// Alias for ContentLength.
93 /// </summary>
94 public long ContentLength64
95 {
96 get { return ContentLength; }
97 set { ContentLength = value; }
98 }
99
100 /// <summary>
101 /// Encoding of the body content.
102 /// </summary>
103 public Encoding ContentEncoding
104 {
105 get
106 {
107 return _httpResponse.Encoding;
108 }
109
110 set
111 {
112 _httpResponse.Encoding = value;
113 }
114 }
115
116 public bool KeepAlive
117 {
118 get
119 {
120 return _httpResponse.Connection == ConnectionType.KeepAlive;
121 }
122
123 set
124 {
125 if (value)
126 _httpResponse.Connection = ConnectionType.KeepAlive;
127 else
128 _httpResponse.Connection = ConnectionType.Close;
129 }
130 }
131
132 /// <summary>
133 /// Get or set the keep alive timeout property (default is
134 /// 20). Setting this to 0 also disables KeepAlive. Setting
135 /// this to something else but 0 also enable KeepAlive.
136 /// </summary>
137 public int KeepAliveTimeout
138 {
139 get
140 {
141 return _httpResponse.KeepAlive;
142 }
143
144 set
145 {
146 if (value == 0)
147 {
148 _httpResponse.Connection = ConnectionType.Close;
149 _httpResponse.KeepAlive = 0;
150 }
151 else
152 {
153 _httpResponse.Connection = ConnectionType.KeepAlive;
154 _httpResponse.KeepAlive = value;
155 }
156 }
157 }
158
159 /// <summary>
160 /// Return the output stream feeding the body.
161 /// </summary>
162 /// <remarks>
163 /// On its way out...
164 /// </remarks>
165 public Stream OutputStream
166 {
167 get
168 {
169 return _httpResponse.Body;
170 }
171 }
172
173 public string ProtocolVersion
174 {
175 get
176 {
177 return _httpResponse.ProtocolVersion;
178 }
179
180 set
181 {
182 _httpResponse.ProtocolVersion = value;
183 }
184 }
185
186 /// <summary>
187 /// Return the output stream feeding the body.
188 /// </summary>
189 public Stream Body
190 {
191 get
192 {
193 return _httpResponse.Body;
194 }
195 }
196
197 /// <summary>
198 /// Set a redirct location.
199 /// </summary>
200 public string RedirectLocation
201 {
202 // get { return _redirectLocation; }
203 set
204 {
205 _httpResponse.Redirect(value);
206 }
207 }
208
209
210 /// <summary>
211 /// Chunk transfers.
212 /// </summary>
213 public bool SendChunked
214 {
215 get
216 {
217 return _httpResponse.Chunked;
218 }
219
220 set
221 {
222 _httpResponse.Chunked = value;
223 }
224 }
225
226 /// <summary>
227 /// HTTP status code.
228 /// </summary>
229 public int StatusCode
230 {
231 get
232 {
233 return (int)_httpResponse.Status;
234 }
235
236 set
237 {
238 _httpResponse.Status = (HttpStatusCode)value;
239 }
240 }
241
242
243 /// <summary>
244 /// HTTP status description.
245 /// </summary>
246 public string StatusDescription
247 {
248 get
249 {
250 return _httpResponse.Reason;
251 }
252
253 set
254 {
255 _httpResponse.Reason = value;
256 }
257 }
258
259
260 protected IHttpResponse _httpResponse;
261
262 public OSHttpResponse() {}
263
264 public OSHttpResponse(IHttpResponse resp)
265 {
266 _httpResponse = resp;
267 }
268
269 /// <summary>
270 /// Instantiate an OSHttpResponse object from an OSHttpRequest
271 /// object.
272 /// </summary
273 /// <param name="req">Incoming OSHttpRequest to which we are
274 /// replying</param>
275 public OSHttpResponse(OSHttpRequest req)
276 {
277 _httpResponse = new HttpResponse(req.IHttpClientContext, req.IHttpRequest);
278 }
279
280 /// <summary>
281 /// Add a header field and content to the response.
282 /// </summary>
283 /// <param name="key">string containing the header field
284 /// name</param>
285 /// <param name="value">string containing the header field
286 /// value</param>
287 public void AddHeader(string key, string value)
288 {
289 _httpResponse.AddHeader(key, value);
290 }
291
292 /// <summary>
293 /// Send the response back to the remote client
294 /// </summary>
295 public void Send()
296 {
297 _httpResponse.Body.Flush();
298 _httpResponse.Send();
299
300 }
301 }
302}
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpServer.cs
new file mode 100644
index 0000000..e84f314
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpServer.cs
@@ -0,0 +1,210 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Net.Sockets;
32using System.Reflection;
33using System.Text.RegularExpressions;
34using System.Threading;
35using System.Security.Cryptography.X509Certificates;
36using log4net;
37using HttpServer;
38
39using HttpListener = HttpServer.HttpListener;
40
41namespace OpenSim.Framework.Servers.HttpServer
42{
43 /// <summary>
44 /// OSHttpServer provides an HTTP server bound to a specific
45 /// port. When instantiated with just address and port it uses
46 /// normal HTTP, when instantiated with address, port, and X509
47 /// certificate, it uses HTTPS.
48 /// </summary>
49 public class OSHttpServer
50 {
51 private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
53 private object _syncObject = new object();
54
55 // underlying HttpServer.HttpListener
56 protected HttpListener _listener;
57 // underlying core/engine thread
58 protected Thread _engine;
59
60 // Queue containing (OS)HttpRequests
61 protected OSHttpRequestQueue _queue;
62
63 // OSHttpRequestPumps "pumping" incoming OSHttpRequests
64 // upwards
65 protected OSHttpRequestPump[] _pumps;
66
67 // thread identifier
68 protected string _engineId;
69 public string EngineID
70 {
71 get { return _engineId; }
72 }
73
74 /// <summary>
75 /// True if this is an HTTPS connection; false otherwise.
76 /// </summary>
77 protected bool _isSecure;
78 public bool IsSecure
79 {
80 get { return _isSecure; }
81 }
82
83 public int QueueSize
84 {
85 get { return _pumps.Length; }
86 }
87
88 /// <summary>
89 /// List of registered OSHttpHandlers for this OSHttpServer instance.
90 /// </summary>
91 protected List<OSHttpHandler> _httpHandlers = new List<OSHttpHandler>();
92 public List<OSHttpHandler> OSHttpHandlers
93 {
94 get
95 {
96 lock (_httpHandlers)
97 {
98 return new List<OSHttpHandler>(_httpHandlers);
99 }
100 }
101 }
102
103
104 /// <summary>
105 /// Instantiate an HTTP server.
106 /// </summary>
107 public OSHttpServer(IPAddress address, int port, int poolSize)
108 {
109 _engineId = String.Format("OSHttpServer (HTTP:{0})", port);
110 _isSecure = false;
111 _log.DebugFormat("[{0}] HTTP server instantiated", EngineID);
112
113 _listener = new HttpListener(address, port);
114 _queue = new OSHttpRequestQueue();
115 _pumps = OSHttpRequestPump.Pumps(this, _queue, poolSize);
116 }
117
118 /// <summary>
119 /// Instantiate an HTTPS server.
120 /// </summary>
121 public OSHttpServer(IPAddress address, int port, X509Certificate certificate, int poolSize)
122 {
123 _engineId = String.Format("OSHttpServer [HTTPS:{0}/ps:{1}]", port, poolSize);
124 _isSecure = true;
125 _log.DebugFormat("[{0}] HTTPS server instantiated", EngineID);
126
127 _listener = new HttpListener(address, port, certificate);
128 _queue = new OSHttpRequestQueue();
129 _pumps = OSHttpRequestPump.Pumps(this, _queue, poolSize);
130 }
131
132 /// <summary>
133 /// Turn an HttpRequest into an OSHttpRequestItem and place it
134 /// in the queue. The OSHttpRequestQueue object will pulse the
135 /// next available idle pump.
136 /// </summary>
137 protected void OnHttpRequest(HttpClientContext client, HttpRequest request)
138 {
139 // turn request into OSHttpRequest
140 OSHttpRequest req = new OSHttpRequest(client, request);
141
142 // place OSHttpRequest into _httpRequestQueue, will
143 // trigger Pulse to idle waiting pumps
144 _queue.Enqueue(req);
145 }
146
147 /// <summary>
148 /// Start the HTTP server engine.
149 /// </summary>
150 public void Start()
151 {
152 _engine = new Thread(new ThreadStart(Engine));
153 _engine.Name = _engineId;
154 _engine.IsBackground = true;
155 _engine.Start();
156
157 ThreadTracker.Add(_engine);
158
159 // start the pumps...
160 for (int i = 0; i < _pumps.Length; i++)
161 _pumps[i].Start();
162 }
163
164 public void Stop()
165 {
166 lock (_syncObject) Monitor.Pulse(_syncObject);
167 }
168
169 /// <summary>
170 /// Engine keeps the HTTP server running.
171 /// </summary>
172 private void Engine()
173 {
174 try {
175 _listener.RequestHandler += OnHttpRequest;
176 _listener.Start(QueueSize);
177 _log.InfoFormat("[{0}] HTTP server started", EngineID);
178
179 lock (_syncObject) Monitor.Wait(_syncObject);
180 }
181 catch (Exception ex)
182 {
183 _log.DebugFormat("[{0}] HTTP server startup failed: {1}", EngineID, ex.ToString());
184 }
185
186 _log.InfoFormat("[{0}] HTTP server terminated", EngineID);
187 }
188
189
190 /// <summary>
191 /// Add an HTTP request handler.
192 /// </summary>
193 /// <param name="handler">OSHttpHandler delegate</param>
194 /// <param name="path">regex object for path matching</parm>
195 /// <param name="headers">dictionary containing header names
196 /// and regular expressions to match against header values</param>
197 public void AddHandler(OSHttpHandler handler)
198 {
199 lock (_httpHandlers)
200 {
201 if (_httpHandlers.Contains(handler))
202 {
203 _log.DebugFormat("[OSHttpServer] attempt to add already existing handler ignored");
204 return;
205 }
206 _httpHandlers.Add(handler);
207 }
208 }
209 }
210}
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs
new file mode 100644
index 0000000..2f1ca0f
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpStatusCodes.cs
@@ -0,0 +1,170 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28namespace OpenSim.Framework.Servers.HttpServer
29{
30 /// <summary>
31 /// HTTP status codes (almost) as defined by W3C in
32 /// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
33 /// </summary>
34 public enum OSHttpStatusCode: int
35 {
36 // 1xx Informational status codes providing a provisional
37 // response.
38 // 100 Tells client that to keep on going sending its request
39 InfoContinue = 100,
40 // 101 Server understands request, proposes to switch to different
41 // application level protocol
42 InfoSwitchingProtocols = 101,
43
44
45 // 2xx Success codes
46 // 200 Request successful
47 SuccessOk = 200,
48 // 201 Request successful, new resource created
49 SuccessOkCreated = 201,
50 // 202 Request accepted, processing still on-going
51 SuccessOkAccepted = 202,
52 // 203 Request successful, meta information not authoritative
53 SuccessOkNonAuthoritativeInformation = 203,
54 // 204 Request successful, nothing to return in the body
55 SuccessOkNoContent = 204,
56 // 205 Request successful, reset displayed content
57 SuccessOkResetContent = 205,
58 // 206 Request successful, partial content returned
59 SuccessOkPartialContent = 206,
60
61 // 3xx Redirect code: user agent needs to go somewhere else
62 // 300 Redirect: different presentation forms available, take
63 // a pick
64 RedirectMultipleChoices = 300,
65 // 301 Redirect: requested resource has moved and now lives
66 // somewhere else
67 RedirectMovedPermanently = 301,
68 // 302 Redirect: Resource temporarily somewhere else, location
69 // might change
70 RedirectFound = 302,
71 // 303 Redirect: See other as result of a POST
72 RedirectSeeOther = 303,
73 // 304 Redirect: Resource still the same as before
74 RedirectNotModified = 304,
75 // 305 Redirect: Resource must be accessed via proxy provided
76 // in location field
77 RedirectUseProxy = 305,
78 // 307 Redirect: Resource temporarily somewhere else, location
79 // might change
80 RedirectMovedTemporarily = 307,
81
82 // 4xx Client error: the client borked the request
83 // 400 Client error: bad request, server does not grok what
84 // the client wants
85 ClientErrorBadRequest = 400,
86 // 401 Client error: the client is not authorized, response
87 // provides WWW-Authenticate header field with a challenge
88 ClientErrorUnauthorized = 401,
89 // 402 Client error: Payment required (reserved for future use)
90 ClientErrorPaymentRequired = 402,
91 // 403 Client error: Server understood request, will not
92 // deliver, do not try again.
93 ClientErrorForbidden = 403,
94 // 404 Client error: Server cannot find anything matching the
95 // client request.
96 ClientErrorNotFound = 404,
97 // 405 Client error: The method specified by the client in the
98 // request is not allowed for the resource requested
99 ClientErrorMethodNotAllowed = 405,
100 // 406 Client error: Server cannot generate suitable response
101 // for the resource and content characteristics requested by
102 // the client
103 ClientErrorNotAcceptable = 406,
104 // 407 Client error: Similar to 401, Server requests that
105 // client authenticate itself with the proxy first
106 ClientErrorProxyAuthRequired = 407,
107 // 408 Client error: Server got impatient with client and
108 // decided to give up waiting for the client's request to
109 // arrive
110 ClientErrorRequestTimeout = 408,
111 // 409 Client error: Server could not fulfill the request for
112 // a resource as there is a conflict with the current state of
113 // the resource but thinks client can do something about this
114 ClientErrorConflict = 409,
115 // 410 Client error: The resource has moved somewhere else,
116 // but server has no clue where.
117 ClientErrorGone = 410,
118 // 411 Client error: The server is picky again and insists on
119 // having a content-length header field in the request
120 ClientErrorLengthRequired = 411,
121 // 412 Client error: one or more preconditions supplied in the
122 // client's request is false
123 ClientErrorPreconditionFailed = 412,
124 // 413 Client error: For fear of reflux, the server refuses to
125 // swallow that much data.
126 ClientErrorRequestEntityToLarge = 413,
127 // 414 Client error: The server considers the Request-URI to
128 // be indecently long and refuses to even look at it.
129 ClientErrorRequestURITooLong = 414,
130 // 415 Client error: The server has no clue about the media
131 // type requested by the client (contrary to popular belief it
132 // is not a warez server)
133 ClientErrorUnsupportedMediaType = 415,
134 // 416 Client error: The requested range cannot be delivered
135 // by the server.
136 ClientErrorRequestRangeNotSatisfiable = 416,
137 // 417 Client error: The expectations of the client as
138 // expressed in one or more Expect header fields cannot be met
139 // by the server, the server is awfully sorry about this.
140 ClientErrorExpectationFailed = 417,
141 // 499 Client error: Wildcard error.
142 ClientErrorJoker = 499,
143
144 // 5xx Server errors (rare)
145 // 500 Server error: something really strange and unexpected
146 // happened
147 ServerErrorInternalError = 500,
148 // 501 Server error: The server does not do the functionality
149 // required to carry out the client request. not at
150 // all. certainly not before breakfast. but also not after
151 // breakfast.
152 ServerErrorNotImplemented = 501,
153 // 502 Server error: While acting as a proxy or a gateway, the
154 // server got ditched by the upstream server and as a
155 // consequence regretfully cannot fulfill the client's request
156 ServerErrorBadGateway = 502,
157 // 503 Server error: Due to unforseen circumstances the server
158 // cannot currently deliver the service requested. Retry-After
159 // header might indicate when to try again.
160 ServerErrorServiceUnavailable = 503,
161 // 504 Server error: The server blames the upstream server
162 // for not being able to deliver the service requested and
163 // claims that the upstream server is too slow delivering the
164 // goods.
165 ServerErrorGatewayTimeout = 504,
166 // 505 Server error: The server does not support the HTTP
167 // version conveyed in the client's request.
168 ServerErrorHttpVersionNotSupported = 505,
169 }
170}
diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpXmlRpcHandler.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpXmlRpcHandler.cs
new file mode 100644
index 0000000..49bae48
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/OSHttpXmlRpcHandler.cs
@@ -0,0 +1,180 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Net;
32using System.Reflection;
33using System.Text;
34using System.Text.RegularExpressions;
35using System.Xml;
36using log4net;
37using Nwc.XmlRpc;
38
39namespace OpenSim.Framework.Servers.HttpServer
40{
41 public delegate XmlRpcResponse OSHttpXmlRpcProcessor(XmlRpcRequest request);
42
43 public class OSHttpXmlRpcHandler: OSHttpHandler
44 {
45 private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
47 /// <summary>
48 /// XmlRpcMethodMatch tries to reify (deserialize) an incoming
49 /// XmlRpc request (and posts it to the "whiteboard") and
50 /// checks whether the method name is one we are interested
51 /// in.
52 /// </summary>
53 /// <returns>true if the handler is interested in the content;
54 /// false otherwise</returns>
55 protected bool XmlRpcMethodMatch(OSHttpRequest req)
56 {
57 XmlRpcRequest xmlRpcRequest = null;
58
59 // check whether req is already reified
60 // if not: reify (and post to whiteboard)
61 try
62 {
63 if (req.Whiteboard.ContainsKey("xmlrequest"))
64 {
65 xmlRpcRequest = req.Whiteboard["xmlrequest"] as XmlRpcRequest;
66 }
67 else
68 {
69 StreamReader body = new StreamReader(req.InputStream);
70 string requestBody = body.ReadToEnd();
71 xmlRpcRequest = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody);
72 req.Whiteboard["xmlrequest"] = xmlRpcRequest;
73 }
74 }
75 catch (XmlException)
76 {
77 _log.ErrorFormat("[OSHttpXmlRpcHandler] failed to deserialize XmlRpcRequest from {0}", req.ToString());
78 return false;
79 }
80
81 // check against methodName
82 if ((null != xmlRpcRequest)
83 && !String.IsNullOrEmpty(xmlRpcRequest.MethodName)
84 && xmlRpcRequest.MethodName == _methodName)
85 {
86 _log.DebugFormat("[OSHttpXmlRpcHandler] located handler {0} for {1}", _methodName, req.ToString());
87 return true;
88 }
89
90 return false;
91 }
92
93 // contains handler for processing XmlRpc Request
94 private XmlRpcMethod _handler;
95
96 // contains XmlRpc method name
97 private string _methodName;
98
99
100 /// <summary>
101 /// Instantiate an XmlRpc handler.
102 /// </summary>
103 /// <param name="handler">XmlRpcMethod
104 /// delegate</param>
105 /// <param name="methodName">XmlRpc method name</param>
106 /// <param name="path">XmlRpc path prefix (regular expression)</param>
107 /// <param name="headers">Dictionary with header names and
108 /// regular expressions to match content of headers</param>
109 /// <param name="whitelist">IP whitelist of remote end points
110 /// to accept (regular expression)</param>
111 /// <remarks>
112 /// Except for handler and methodName, all other parameters
113 /// can be null, in which case they are not taken into account
114 /// when the handler is being looked up.
115 /// </remarks>
116 public OSHttpXmlRpcHandler(XmlRpcMethod handler, string methodName, Regex path,
117 Dictionary<string, Regex> headers, Regex whitelist)
118 : base(new Regex(@"^POST$", RegexOptions.IgnoreCase | RegexOptions.Compiled), path, null, headers,
119 new Regex(@"^(text|application)/xml", RegexOptions.IgnoreCase | RegexOptions.Compiled),
120 whitelist)
121 {
122 _handler = handler;
123 _methodName = methodName;
124 }
125
126
127 /// <summary>
128 /// Instantiate an XmlRpc handler.
129 /// </summary>
130 /// <param name="handler">XmlRpcMethod
131 /// delegate</param>
132 /// <param name="methodName">XmlRpc method name</param>
133 public OSHttpXmlRpcHandler(XmlRpcMethod handler, string methodName)
134 : this(handler, methodName, null, null, null)
135 {
136 }
137
138
139 /// <summary>
140 /// Invoked by OSHttpRequestPump.
141 /// </summary>
142 public override OSHttpHandlerResult Process(OSHttpRequest request)
143 {
144 XmlRpcResponse xmlRpcResponse;
145 string responseString;
146
147 // check whether we are interested in this request
148 if (!XmlRpcMethodMatch(request)) return OSHttpHandlerResult.Pass;
149
150
151 OSHttpResponse resp = new OSHttpResponse(request);
152 try
153 {
154 // reified XmlRpcRequest must still be on the whiteboard
155 XmlRpcRequest xmlRpcRequest = request.Whiteboard["xmlrequest"] as XmlRpcRequest;
156 xmlRpcResponse = _handler(xmlRpcRequest);
157 responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse);
158
159 resp.ContentType = "text/xml";
160 byte[] buffer = Encoding.UTF8.GetBytes(responseString);
161
162 resp.SendChunked = false;
163 resp.ContentLength = buffer.Length;
164 resp.ContentEncoding = Encoding.UTF8;
165
166 resp.Body.Write(buffer, 0, buffer.Length);
167 resp.Body.Flush();
168
169 resp.Send();
170
171 }
172 catch (Exception ex)
173 {
174 _log.WarnFormat("[OSHttpXmlRpcHandler]: Error: {0}", ex.Message);
175 return OSHttpHandlerResult.Pass;
176 }
177 return OSHttpHandlerResult.Done;
178 }
179 }
180}
diff --git a/OpenSim/Framework/Servers/HttpServer/OpenSim.Framework.Servers.HttpServer.csproj b/OpenSim/Framework/Servers/HttpServer/OpenSim.Framework.Servers.HttpServer.csproj
new file mode 100644
index 0000000..097a251
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/OpenSim.Framework.Servers.HttpServer.csproj
@@ -0,0 +1,180 @@
1<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
2 <PropertyGroup>
3 <ProjectType>Local</ProjectType>
4 <ProductVersion>8.0.50727</ProductVersion>
5 <SchemaVersion>2.0</SchemaVersion>
6 <ProjectGuid>{1CBD339A-0000-0000-0000-000000000000}</ProjectGuid>
7 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
8 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
9 <ApplicationIcon></ApplicationIcon>
10 <AssemblyKeyContainerName>
11 </AssemblyKeyContainerName>
12 <AssemblyName>OpenSim.Framework.Servers.HttpServer</AssemblyName>
13 <DefaultClientScript>JScript</DefaultClientScript>
14 <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
15 <DefaultTargetSchema>IE50</DefaultTargetSchema>
16 <DelaySign>false</DelaySign>
17 <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
18 <OutputType>Library</OutputType>
19 <AppDesignerFolder></AppDesignerFolder>
20 <RootNamespace>OpenSim.Framework.Servers.HttpServer</RootNamespace>
21 <StartupObject></StartupObject>
22 <StartArguments></StartArguments>
23 <FileUpgradeFlags>
24 </FileUpgradeFlags>
25 </PropertyGroup>
26 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
27 <AllowUnsafeBlocks>False</AllowUnsafeBlocks>
28 <BaseAddress>285212672</BaseAddress>
29 <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
30 <ConfigurationOverrideFile>
31 </ConfigurationOverrideFile>
32 <DefineConstants>TRACE;DEBUG</DefineConstants>
33 <DocumentationFile></DocumentationFile>
34 <DebugSymbols>True</DebugSymbols>
35 <FileAlignment>4096</FileAlignment>
36 <Optimize>False</Optimize>
37 <OutputPath>../../../../bin/</OutputPath>
38 <RegisterForComInterop>False</RegisterForComInterop>
39 <RemoveIntegerChecks>False</RemoveIntegerChecks>
40 <TreatWarningsAsErrors>False</TreatWarningsAsErrors>
41 <WarningLevel>4</WarningLevel>
42 <NoStdLib>False</NoStdLib>
43 <NoWarn></NoWarn>
44 </PropertyGroup>
45 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
46 <AllowUnsafeBlocks>False</AllowUnsafeBlocks>
47 <BaseAddress>285212672</BaseAddress>
48 <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
49 <ConfigurationOverrideFile>
50 </ConfigurationOverrideFile>
51 <DefineConstants>TRACE</DefineConstants>
52 <DocumentationFile></DocumentationFile>
53 <DebugSymbols>False</DebugSymbols>
54 <FileAlignment>4096</FileAlignment>
55 <Optimize>True</Optimize>
56 <OutputPath>../../../../bin/</OutputPath>
57 <RegisterForComInterop>False</RegisterForComInterop>
58 <RemoveIntegerChecks>False</RemoveIntegerChecks>
59 <TreatWarningsAsErrors>False</TreatWarningsAsErrors>
60 <WarningLevel>4</WarningLevel>
61 <NoStdLib>False</NoStdLib>
62 <NoWarn></NoWarn>
63 </PropertyGroup>
64 <ItemGroup>
65 <Reference Include="HttpServer_OpenSim.dll" >
66 <Name>HttpServer_OpenSim.dll</Name>
67 <Private>False</Private>
68 </Reference>
69 <Reference Include="log4net.dll" >
70 <Name>log4net.dll</Name>
71 <Private>False</Private>
72 </Reference>
73 <Reference Include="OpenMetaverse.StructuredData.dll" >
74 <Name>OpenMetaverse.StructuredData.dll</Name>
75 <Private>False</Private>
76 </Reference>
77 <Reference Include="OpenMetaverseTypes.dll" >
78 <Name>OpenMetaverseTypes.dll</Name>
79 <Private>False</Private>
80 </Reference>
81 <Reference Include="System" >
82 <Name>System</Name>
83 <Private>False</Private>
84 </Reference>
85 <Reference Include="System.Xml" >
86 <Name>System.Xml</Name>
87 <Private>False</Private>
88 </Reference>
89 <Reference Include="XMLRPC.dll" >
90 <Name>XMLRPC.dll</Name>
91 <Private>False</Private>
92 </Reference>
93 </ItemGroup>
94 <ItemGroup>
95 <ProjectReference Include="../../../Data/OpenSim.Data.csproj">
96 <Name>OpenSim.Data</Name>
97 <Project>{B75A430B-0000-0000-0000-000000000000}</Project>
98 <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
99 <Private>False</Private>
100 </ProjectReference>
101 </ItemGroup>
102 <ItemGroup>
103 <Compile Include="BaseHTTPHandler.cs">
104 <SubType>Code</SubType>
105 </Compile>
106 <Compile Include="BaseHttpServer.cs">
107 <SubType>Code</SubType>
108 </Compile>
109 <Compile Include="BaseRequestHandler.cs">
110 <SubType>Code</SubType>
111 </Compile>
112 <Compile Include="BaseStreamHandler.cs">
113 <SubType>Code</SubType>
114 </Compile>
115 <Compile Include="BinaryStreamHandler.cs">
116 <SubType>Code</SubType>
117 </Compile>
118 <Compile Include="GenericHTTPMethod.cs">
119 <SubType>Code</SubType>
120 </Compile>
121 <Compile Include="LLSDMethod.cs">
122 <SubType>Code</SubType>
123 </Compile>
124 <Compile Include="LLSDMethodString.cs">
125 <SubType>Code</SubType>
126 </Compile>
127 <Compile Include="OSHttpRequest.cs">
128 <SubType>Code</SubType>
129 </Compile>
130 <Compile Include="OSHttpResponse.cs">
131 <SubType>Code</SubType>
132 </Compile>
133 <Compile Include="OSHttpStatusCodes.cs">
134 <SubType>Code</SubType>
135 </Compile>
136 <Compile Include="RestDeserialiseHandler.cs">
137 <SubType>Code</SubType>
138 </Compile>
139 <Compile Include="RestHTTPHandler.cs">
140 <SubType>Code</SubType>
141 </Compile>
142 <Compile Include="RestMethod.cs">
143 <SubType>Code</SubType>
144 </Compile>
145 <Compile Include="RestObjectPoster.cs">
146 <SubType>Code</SubType>
147 </Compile>
148 <Compile Include="RestObjectPosterResponse.cs">
149 <SubType>Code</SubType>
150 </Compile>
151 <Compile Include="RestSessionService.cs">
152 <SubType>Code</SubType>
153 </Compile>
154 <Compile Include="RestStreamHandler.cs">
155 <SubType>Code</SubType>
156 </Compile>
157 <Compile Include="SynchronousRestObjectPoster.cs">
158 <SubType>Code</SubType>
159 </Compile>
160 <Compile Include="XmlRpcMethod.cs">
161 <SubType>Code</SubType>
162 </Compile>
163 <Compile Include="Interfaces/IHttpAgentHandler.cs">
164 <SubType>Code</SubType>
165 </Compile>
166 <Compile Include="Interfaces/IHttpServer.cs">
167 <SubType>Code</SubType>
168 </Compile>
169 <Compile Include="Interfaces/IStreamHandler.cs">
170 <SubType>Code</SubType>
171 </Compile>
172 </ItemGroup>
173 <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
174 <PropertyGroup>
175 <PreBuildEvent>
176 </PreBuildEvent>
177 <PostBuildEvent>
178 </PostBuildEvent>
179 </PropertyGroup>
180</Project>
diff --git a/OpenSim/Framework/Servers/HttpServer/OpenSim.Framework.Servers.HttpServer.csproj.user b/OpenSim/Framework/Servers/HttpServer/OpenSim.Framework.Servers.HttpServer.csproj.user
new file mode 100644
index 0000000..b73b33f
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/OpenSim.Framework.Servers.HttpServer.csproj.user
@@ -0,0 +1,12 @@
1<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <PropertyGroup>
3 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <ReferencePath>/root/opensim-commit/bin/</ReferencePath>
6 <LastOpenVersion>8.0.50727</LastOpenVersion>
7 <ProjectView>ProjectFiles</ProjectView>
8 <ProjectTrust>0</ProjectTrust>
9 </PropertyGroup>
10 <PropertyGroup Condition = " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
11 <PropertyGroup Condition = " '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
12</Project>
diff --git a/OpenSim/Framework/Servers/HttpServer/OpenSim.Framework.Servers.HttpServer.dll.build b/OpenSim/Framework/Servers/HttpServer/OpenSim.Framework.Servers.HttpServer.dll.build
new file mode 100644
index 0000000..f814703
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/OpenSim.Framework.Servers.HttpServer.dll.build
@@ -0,0 +1,74 @@
1<?xml version="1.0" ?>
2<project name="OpenSim.Framework.Servers.HttpServer" default="build">
3 <target name="build">
4 <echo message="Build Directory is ${project::get-base-directory()}/${build.dir}" />
5 <mkdir dir="${project::get-base-directory()}/${build.dir}" />
6 <copy todir="${project::get-base-directory()}/${build.dir}" flatten="true">
7 <fileset basedir="${project::get-base-directory()}">
8 </fileset>
9 </copy>
10 <copy todir="${project::get-base-directory()}/${build.dir}">
11 <fileset basedir=".">
12 </fileset>
13 </copy>
14 <csc target="library" debug="${build.debug}" unsafe="False" warnaserror="False" define="TRACE;DEBUG" nostdlib="False" main="" output="${project::get-base-directory()}/${build.dir}/${project::get-name()}.dll">
15 <resources prefix="OpenSim.Framework.Servers.HttpServer" dynamicprefix="true" >
16 </resources>
17 <sources failonempty="true">
18 <include name="BaseHTTPHandler.cs" />
19 <include name="BaseHttpServer.cs" />
20 <include name="BaseRequestHandler.cs" />
21 <include name="BaseStreamHandler.cs" />
22 <include name="BinaryStreamHandler.cs" />
23 <include name="GenericHTTPMethod.cs" />
24 <include name="LLSDMethod.cs" />
25 <include name="LLSDMethodString.cs" />
26 <include name="OSHttpRequest.cs" />
27 <include name="OSHttpResponse.cs" />
28 <include name="OSHttpStatusCodes.cs" />
29 <include name="RestDeserialiseHandler.cs" />
30 <include name="RestHTTPHandler.cs" />
31 <include name="RestMethod.cs" />
32 <include name="RestObjectPoster.cs" />
33 <include name="RestObjectPosterResponse.cs" />
34 <include name="RestSessionService.cs" />
35 <include name="RestStreamHandler.cs" />
36 <include name="SynchronousRestObjectPoster.cs" />
37 <include name="XmlRpcMethod.cs" />
38 <include name="Interfaces/IHttpAgentHandler.cs" />
39 <include name="Interfaces/IHttpServer.cs" />
40 <include name="Interfaces/IStreamHandler.cs" />
41 </sources>
42 <references basedir="${project::get-base-directory()}">
43 <lib>
44 <include name="${project::get-base-directory()}" />
45 <include name="${project::get-base-directory()}/../../../../bin" />
46 </lib>
47 <include name="../../../../bin/HttpServer_OpenSim.dll" />
48 <include name="../../../../bin/log4net.dll" />
49 <include name="../../../../bin/OpenMetaverse.StructuredData.dll" />
50 <include name="../../../../bin/OpenMetaverseTypes.dll" />
51 <include name="OpenSim.Data.dll" />
52 <include name="System.dll" />
53 <include name="System.Xml.dll" />
54 <include name="../../../../bin/XMLRPC.dll" />
55 </references>
56 </csc>
57 <echo message="Copying from [${project::get-base-directory()}/${build.dir}/] to [${project::get-base-directory()}/../../../../bin/" />
58 <mkdir dir="${project::get-base-directory()}/../../../../bin/"/>
59 <copy todir="${project::get-base-directory()}/../../../../bin/">
60 <fileset basedir="${project::get-base-directory()}/${build.dir}/" >
61 <include name="*.dll"/>
62 <include name="*.exe"/>
63 <include name="*.mdb" if='${build.debug}'/>
64 <include name="*.pdb" if='${build.debug}'/>
65 </fileset>
66 </copy>
67 </target>
68 <target name="clean">
69 <delete dir="${bin.dir}" failonerror="false" />
70 <delete dir="${obj.dir}" failonerror="false" />
71 </target>
72 <target name="doc" description="Creates documentation.">
73 </target>
74</project>
diff --git a/OpenSim/Framework/Servers/HttpServer/OpenSim.Framework.Servers.HttpServer.mdp b/OpenSim/Framework/Servers/HttpServer/OpenSim.Framework.Servers.HttpServer.mdp
new file mode 100644
index 0000000..7556d59
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/OpenSim.Framework.Servers.HttpServer.mdp
@@ -0,0 +1,54 @@
1<Project name="OpenSim.Framework.Servers.HttpServer" description="" standardNamespace="OpenSim.Framework.Servers.HttpServer" newfilesearch="None" enableviewstate="True" fileversion="2.0" language="C#" clr-version="Net_2_0" ctype="DotNetProject">
2 <Configurations active="Debug">
3 <Configuration name="Debug" ctype="DotNetProjectConfiguration">
4 <Output directory="./../../../../bin/" assembly="OpenSim.Framework.Servers.HttpServer" executeScript="" executeBeforeBuild="" executeAfterBuild="" executeBeforeBuildArguments="" executeAfterBuildArguments="" />
5 <Build debugmode="True" target="Library" />
6 <Execution runwithwarnings="True" consolepause="True" runtime="MsNet" clr-version="Net_2_0" />
7 <CodeGeneration compiler="Csc" warninglevel="4" nowarn="" includedebuginformation="True" optimize="False" unsafecodeallowed="False" generateoverflowchecks="False" mainclass="" target="Library" definesymbols="TRACE;DEBUG" generatexmldocumentation="False" win32Icon="" ctype="CSharpCompilerParameters" />
8 </Configuration>
9 <Configuration name="Release" ctype="DotNetProjectConfiguration">
10 <Output directory="./../../../../bin/" assembly="OpenSim.Framework.Servers.HttpServer" executeScript="" executeBeforeBuild="" executeAfterBuild="" executeBeforeBuildArguments="" executeAfterBuildArguments="" />
11 <Build debugmode="True" target="Library" />
12 <Execution runwithwarnings="True" consolepause="True" runtime="MsNet" clr-version="Net_2_0" />
13 <CodeGeneration compiler="Csc" warninglevel="4" nowarn="" includedebuginformation="False" optimize="True" unsafecodeallowed="False" generateoverflowchecks="False" mainclass="" target="Library" definesymbols="TRACE" generatexmldocumentation="False" win32Icon="" ctype="CSharpCompilerParameters" />
14 </Configuration>
15 </Configurations>
16 <DeploymentInformation target="" script="" strategy="File">
17 <excludeFiles />
18 </DeploymentInformation>
19 <Contents>
20 <File name="./BaseHTTPHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
21 <File name="./BaseHttpServer.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
22 <File name="./BaseRequestHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
23 <File name="./BaseStreamHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
24 <File name="./BinaryStreamHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
25 <File name="./GenericHTTPMethod.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
26 <File name="./LLSDMethod.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
27 <File name="./LLSDMethodString.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
28 <File name="./OSHttpRequest.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
29 <File name="./OSHttpResponse.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
30 <File name="./OSHttpStatusCodes.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
31 <File name="./RestDeserialiseHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
32 <File name="./RestHTTPHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
33 <File name="./RestMethod.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
34 <File name="./RestObjectPoster.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
35 <File name="./RestObjectPosterResponse.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
36 <File name="./RestSessionService.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
37 <File name="./RestStreamHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
38 <File name="./SynchronousRestObjectPoster.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
39 <File name="./XmlRpcMethod.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
40 <File name="./Interfaces/IHttpAgentHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
41 <File name="./Interfaces/IHttpServer.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
42 <File name="./Interfaces/IStreamHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
43 </Contents>
44 <References>
45 <ProjectReference type="Assembly" refto="../../../../bin/HttpServer_OpenSim.dll" localcopy="False" />
46 <ProjectReference type="Assembly" refto="../../../../bin/log4net.dll" localcopy="False" />
47 <ProjectReference type="Assembly" refto="../../../../bin/OpenMetaverse.StructuredData.dll" localcopy="False" />
48 <ProjectReference type="Assembly" refto="../../../../bin/OpenMetaverseTypes.dll" localcopy="False" />
49 <ProjectReference type="Project" localcopy="False" refto="OpenSim.Data" />
50 <ProjectReference type="Gac" localcopy="False" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
51 <ProjectReference type="Gac" localcopy="False" refto="System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
52 <ProjectReference type="Assembly" refto="../../../../bin/XMLRPC.dll" localcopy="False" />
53 </References>
54</Project>
diff --git a/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs
new file mode 100644
index 0000000..d5ab926
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs
@@ -0,0 +1,66 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.IO;
29using System.Xml;
30using System.Xml.Serialization;
31
32namespace OpenSim.Framework.Servers.HttpServer
33{
34 public delegate TResponse RestDeserialiseMethod<TRequest, TResponse>(TRequest request);
35
36 public class RestDeserialiseHandler<TRequest, TResponse> : BaseRequestHandler, IStreamHandler
37 where TRequest : new()
38 {
39 private RestDeserialiseMethod<TRequest, TResponse> m_method;
40
41 public RestDeserialiseHandler(string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method)
42 : base(httpMethod, path)
43 {
44 m_method = method;
45 }
46
47 public void Handle(string path, Stream request, Stream responseStream,
48 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
49 {
50 TRequest deserial;
51 using (XmlTextReader xmlReader = new XmlTextReader(request))
52 {
53 XmlSerializer deserializer = new XmlSerializer(typeof (TRequest));
54 deserial = (TRequest) deserializer.Deserialize(xmlReader);
55 }
56
57 TResponse response = m_method(deserial);
58
59 using (XmlWriter xmlWriter = XmlTextWriter.Create(responseStream))
60 {
61 XmlSerializer serializer = new XmlSerializer(typeof (TResponse));
62 serializer.Serialize(xmlWriter, response);
63 }
64 }
65 }
66}
diff --git a/OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs
new file mode 100644
index 0000000..175a0f2
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/RestHTTPHandler.cs
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29
30namespace OpenSim.Framework.Servers.HttpServer
31{
32 public class RestHTTPHandler : BaseHTTPHandler
33 {
34 private GenericHTTPMethod m_dhttpMethod;
35
36 public GenericHTTPMethod Method
37 {
38 get { return m_dhttpMethod; }
39 }
40
41 public override Hashtable Handle(string path, Hashtable request)
42 {
43
44 string param = GetParam(path);
45 request.Add("param", param);
46 request.Add("path", path);
47 return m_dhttpMethod(request);
48 }
49
50 public RestHTTPHandler(string httpMethod, string path, GenericHTTPMethod dhttpMethod)
51 : base(httpMethod, path)
52 {
53 m_dhttpMethod = dhttpMethod;
54 }
55 }
56}
diff --git a/OpenSim/Framework/Servers/HttpServer/RestMethod.cs b/OpenSim/Framework/Servers/HttpServer/RestMethod.cs
new file mode 100644
index 0000000..08ee35a
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/RestMethod.cs
@@ -0,0 +1,32 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28namespace OpenSim.Framework.Servers.HttpServer
29{
30 public delegate string RestMethod(string request, string path, string param,
31 OSHttpRequest httpRequest, OSHttpResponse httpResponse);
32}
diff --git a/OpenSim/Framework/Servers/HttpServer/RestObjectPoster.cs b/OpenSim/Framework/Servers/HttpServer/RestObjectPoster.cs
new file mode 100644
index 0000000..5a424d8
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/RestObjectPoster.cs
@@ -0,0 +1,84 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Net;
31using System.Text;
32using System.Xml;
33using System.Xml.Serialization;
34
35namespace OpenSim.Framework.Servers.HttpServer
36{
37 /// <summary>
38 /// Makes an asynchronous REST request which doesn't require us to do anything with the response.
39 /// </summary>
40 public class RestObjectPoster
41 {
42 public static void BeginPostObject<TRequest>(string requestUrl, TRequest obj)
43 {
44 BeginPostObject("POST", requestUrl, obj);
45 }
46
47 public static void BeginPostObject<TRequest>(string verb, string requestUrl, TRequest obj)
48 {
49 Type type = typeof (TRequest);
50
51 WebRequest request = WebRequest.Create(requestUrl);
52 request.Method = verb;
53 request.ContentType = "text/xml";
54
55 MemoryStream buffer = new MemoryStream();
56
57 XmlWriterSettings settings = new XmlWriterSettings();
58 settings.Encoding = Encoding.UTF8;
59
60 using (XmlWriter writer = XmlWriter.Create(buffer, settings))
61 {
62 XmlSerializer serializer = new XmlSerializer(type);
63 serializer.Serialize(writer, obj);
64 writer.Flush();
65 }
66
67 int length = (int) buffer.Length;
68 request.ContentLength = length;
69
70 Stream requestStream = request.GetRequestStream();
71 requestStream.Write(buffer.ToArray(), 0, length);
72 // IAsyncResult result = request.BeginGetResponse(AsyncCallback, request);
73 request.BeginGetResponse(AsyncCallback, request);
74 }
75
76 private static void AsyncCallback(IAsyncResult result)
77 {
78 WebRequest request = (WebRequest) result.AsyncState;
79 using (WebResponse resp = request.EndGetResponse(result))
80 {
81 }
82 }
83 }
84}
diff --git a/OpenSim/Framework/Servers/HttpServer/RestObjectPosterResponse.cs b/OpenSim/Framework/Servers/HttpServer/RestObjectPosterResponse.cs
new file mode 100644
index 0000000..690c583
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/RestObjectPosterResponse.cs
@@ -0,0 +1,107 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Net;
31using System.Text;
32using System.Xml;
33using System.Xml.Serialization;
34
35namespace OpenSim.Framework.Servers.HttpServer
36{
37 public delegate void ReturnResponse<T>(T reponse);
38
39 /// <summary>
40 /// Makes an asynchronous REST request with a callback to invoke with the response.
41 /// </summary>
42 public class RestObjectPosterResponse<TResponse>
43 {
44// private static readonly log4net.ILog m_log
45// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
46
47 public ReturnResponse<TResponse> ResponseCallback;
48
49 public void BeginPostObject<TRequest>(string requestUrl, TRequest obj)
50 {
51 BeginPostObject("POST", requestUrl, obj);
52 }
53
54 public void BeginPostObject<TRequest>(string verb, string requestUrl, TRequest obj)
55 {
56 Type type = typeof (TRequest);
57
58 WebRequest request = WebRequest.Create(requestUrl);
59 request.Method = verb;
60 request.ContentType = "text/xml";
61 request.Timeout = 10000;
62
63 MemoryStream buffer = new MemoryStream();
64
65 XmlWriterSettings settings = new XmlWriterSettings();
66 settings.Encoding = Encoding.UTF8;
67
68 using (XmlWriter writer = XmlWriter.Create(buffer, settings))
69 {
70 XmlSerializer serializer = new XmlSerializer(type);
71 serializer.Serialize(writer, obj);
72 writer.Flush();
73 }
74
75 int length = (int) buffer.Length;
76 request.ContentLength = length;
77
78 Stream requestStream = request.GetRequestStream();
79 requestStream.Write(buffer.ToArray(), 0, length);
80 requestStream.Close();
81 // IAsyncResult result = request.BeginGetResponse(AsyncCallback, request);
82 request.BeginGetResponse(AsyncCallback, request);
83 }
84
85 private void AsyncCallback(IAsyncResult result)
86 {
87 WebRequest request = (WebRequest) result.AsyncState;
88 using (WebResponse resp = request.EndGetResponse(result))
89 {
90 TResponse deserial;
91 XmlSerializer deserializer = new XmlSerializer(typeof (TResponse));
92 Stream stream = resp.GetResponseStream();
93
94 // This is currently a bad debug stanza since it gobbles us the response...
95// StreamReader reader = new StreamReader(stream);
96// m_log.DebugFormat("[REST OBJECT POSTER RESPONSE]: Received {0}", reader.ReadToEnd());
97
98 deserial = (TResponse) deserializer.Deserialize(stream);
99
100 if (deserial != null && ResponseCallback != null)
101 {
102 ResponseCallback(deserial);
103 }
104 }
105 }
106 }
107}
diff --git a/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs b/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs
new file mode 100644
index 0000000..f5e4248
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs
@@ -0,0 +1,291 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Net;
31using System.Reflection;
32using System.Text;
33using System.Xml;
34using System.Xml.Serialization;
35using log4net;
36
37namespace OpenSim.Framework.Servers.HttpServer
38{
39 public class RestSessionObject<TRequest>
40 {
41 private string sid;
42 private string aid;
43 private TRequest request_body;
44
45 public string SessionID
46 {
47 get { return sid; }
48 set { sid = value; }
49 }
50
51 public string AvatarID
52 {
53 get { return aid; }
54 set { aid = value; }
55 }
56
57 public TRequest Body
58 {
59 get { return request_body; }
60 set { request_body = value; }
61 }
62 }
63
64 public class SynchronousRestSessionObjectPoster<TRequest, TResponse>
65 {
66 public static TResponse BeginPostObject(string verb, string requestUrl, TRequest obj, string sid, string aid)
67 {
68 RestSessionObject<TRequest> sobj = new RestSessionObject<TRequest>();
69 sobj.SessionID = sid;
70 sobj.AvatarID = aid;
71 sobj.Body = obj;
72
73 Type type = typeof(RestSessionObject<TRequest>);
74
75 WebRequest request = WebRequest.Create(requestUrl);
76 request.Method = verb;
77 request.ContentType = "text/xml";
78
79 MemoryStream buffer = new MemoryStream();
80
81 XmlWriterSettings settings = new XmlWriterSettings();
82 settings.Encoding = Encoding.UTF8;
83
84 using (XmlWriter writer = XmlWriter.Create(buffer, settings))
85 {
86 XmlSerializer serializer = new XmlSerializer(type);
87 serializer.Serialize(writer, sobj);
88 writer.Flush();
89 }
90
91 int length = (int)buffer.Length;
92 request.ContentLength = length;
93
94 Stream requestStream = request.GetRequestStream();
95 requestStream.Write(buffer.ToArray(), 0, length);
96 TResponse deserial = default(TResponse);
97 using (WebResponse resp = request.GetResponse())
98 {
99 XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
100 deserial = (TResponse)deserializer.Deserialize(resp.GetResponseStream());
101 }
102 return deserial;
103 }
104 }
105
106 public class RestSessionObjectPosterResponse<TRequest, TResponse>
107 {
108 public ReturnResponse<TResponse> ResponseCallback;
109
110 public void BeginPostObject(string requestUrl, TRequest obj, string sid, string aid)
111 {
112 BeginPostObject("POST", requestUrl, obj, sid, aid);
113 }
114
115 public void BeginPostObject(string verb, string requestUrl, TRequest obj, string sid, string aid)
116 {
117 RestSessionObject<TRequest> sobj = new RestSessionObject<TRequest>();
118 sobj.SessionID = sid;
119 sobj.AvatarID = aid;
120 sobj.Body = obj;
121
122 Type type = typeof(RestSessionObject<TRequest>);
123
124 WebRequest request = WebRequest.Create(requestUrl);
125 request.Method = verb;
126 request.ContentType = "text/xml";
127 request.Timeout = 10000;
128
129 MemoryStream buffer = new MemoryStream();
130
131 XmlWriterSettings settings = new XmlWriterSettings();
132 settings.Encoding = Encoding.UTF8;
133
134 using (XmlWriter writer = XmlWriter.Create(buffer, settings))
135 {
136 XmlSerializer serializer = new XmlSerializer(type);
137 serializer.Serialize(writer, sobj);
138 writer.Flush();
139 }
140
141 int length = (int)buffer.Length;
142 request.ContentLength = length;
143
144 Stream requestStream = request.GetRequestStream();
145 requestStream.Write(buffer.ToArray(), 0, length);
146 requestStream.Close();
147 // IAsyncResult result = request.BeginGetResponse(AsyncCallback, request);
148 request.BeginGetResponse(AsyncCallback, request);
149 }
150
151 private void AsyncCallback(IAsyncResult result)
152 {
153 WebRequest request = (WebRequest)result.AsyncState;
154 using (WebResponse resp = request.EndGetResponse(result))
155 {
156 TResponse deserial;
157 XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
158 Stream stream = resp.GetResponseStream();
159
160 // This is currently a bad debug stanza since it gobbles us the response...
161 // StreamReader reader = new StreamReader(stream);
162 // m_log.DebugFormat("[REST OBJECT POSTER RESPONSE]: Received {0}", reader.ReadToEnd());
163
164 deserial = (TResponse)deserializer.Deserialize(stream);
165
166 if (deserial != null && ResponseCallback != null)
167 {
168 ResponseCallback(deserial);
169 }
170 }
171 }
172 }
173
174 public delegate bool CheckIdentityMethod(string sid, string aid);
175
176 public class RestDeserialiseSecureHandler<TRequest, TResponse> : BaseRequestHandler, IStreamHandler
177 where TRequest : new()
178 {
179 private static readonly ILog m_log
180 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
181
182 private RestDeserialiseMethod<TRequest, TResponse> m_method;
183 private CheckIdentityMethod m_smethod;
184
185 public RestDeserialiseSecureHandler(
186 string httpMethod, string path,
187 RestDeserialiseMethod<TRequest, TResponse> method, CheckIdentityMethod smethod)
188 : base(httpMethod, path)
189 {
190 m_smethod = smethod;
191 m_method = method;
192 }
193
194 public void Handle(string path, Stream request, Stream responseStream,
195 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
196 {
197 RestSessionObject<TRequest> deserial = default(RestSessionObject<TRequest>);
198 bool fail = false;
199
200 using (XmlTextReader xmlReader = new XmlTextReader(request))
201 {
202 try
203 {
204 XmlSerializer deserializer = new XmlSerializer(typeof(RestSessionObject<TRequest>));
205 deserial = (RestSessionObject<TRequest>)deserializer.Deserialize(xmlReader);
206 }
207 catch (Exception e)
208 {
209 m_log.Error("[REST]: Deserialization problem. Ignoring request. " + e);
210 fail = true;
211 }
212 }
213
214 TResponse response = default(TResponse);
215 if (!fail && m_smethod(deserial.SessionID, deserial.AvatarID))
216 {
217 response = m_method(deserial.Body);
218 }
219
220 using (XmlWriter xmlWriter = XmlTextWriter.Create(responseStream))
221 {
222 XmlSerializer serializer = new XmlSerializer(typeof(TResponse));
223 serializer.Serialize(xmlWriter, response);
224 }
225 }
226 }
227
228 public delegate bool CheckTrustedSourceMethod(IPEndPoint peer);
229
230 public class RestDeserialiseTrustedHandler<TRequest, TResponse> : BaseRequestHandler, IStreamHandler
231 where TRequest : new()
232 {
233 private static readonly ILog m_log
234 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
235
236 /// <summary>
237 /// The operation to perform once trust has been established.
238 /// </summary>
239 /// <param name="httpMethod"></param>
240 /// <param name="path"></param>
241 /// <param name="method"></param>
242 /// <param name="tmethod"></param>
243 private RestDeserialiseMethod<TRequest, TResponse> m_method;
244
245 /// <summary>
246 /// The method used to check whether a request is trusted.
247 /// </summary>
248 private CheckTrustedSourceMethod m_tmethod;
249
250 public RestDeserialiseTrustedHandler(string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method, CheckTrustedSourceMethod tmethod)
251 : base(httpMethod, path)
252 {
253 m_tmethod = tmethod;
254 m_method = method;
255 }
256
257 public void Handle(string path, Stream request, Stream responseStream,
258 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
259 {
260 TRequest deserial = default(TRequest);
261 bool fail = false;
262
263 using (XmlTextReader xmlReader = new XmlTextReader(request))
264 {
265 try
266 {
267 XmlSerializer deserializer = new XmlSerializer(typeof(TRequest));
268 deserial = (TRequest)deserializer.Deserialize(xmlReader);
269 }
270 catch (Exception e)
271 {
272 m_log.Error("[REST]: Deserialization problem. Ignoring request. " + e);
273 fail = true;
274 }
275 }
276
277 TResponse response = default(TResponse);
278 if (!fail && m_tmethod(httpRequest.RemoteIPEndPoint))
279 {
280 response = m_method(deserial);
281 }
282
283 using (XmlWriter xmlWriter = XmlTextWriter.Create(responseStream))
284 {
285 XmlSerializer serializer = new XmlSerializer(typeof(TResponse));
286 serializer.Serialize(xmlWriter, response);
287 }
288 }
289 }
290
291}
diff --git a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs
new file mode 100644
index 0000000..f213c15
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs
@@ -0,0 +1,61 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.IO;
29using System.Text;
30
31namespace OpenSim.Framework.Servers.HttpServer
32{
33 public class RestStreamHandler : BaseStreamHandler
34 {
35 private RestMethod m_restMethod;
36
37 public RestMethod Method
38 {
39 get { return m_restMethod; }
40 }
41
42 public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
43 {
44 Encoding encoding = Encoding.UTF8;
45 StreamReader streamReader = new StreamReader(request, encoding);
46
47 string requestBody = streamReader.ReadToEnd();
48 streamReader.Close();
49
50 string param = GetParam(path);
51 string responseString = m_restMethod(requestBody, path, param, httpRequest, httpResponse);
52
53 return Encoding.UTF8.GetBytes(responseString);
54 }
55
56 public RestStreamHandler(string httpMethod, string path, RestMethod restMethod) : base(httpMethod, path)
57 {
58 m_restMethod = restMethod;
59 }
60 }
61}
diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectPoster.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectPoster.cs
new file mode 100644
index 0000000..b754c36
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectPoster.cs
@@ -0,0 +1,83 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Net;
31using System.Text;
32using System.Xml;
33using System.Xml.Serialization;
34
35namespace OpenSim.Framework.Servers.HttpServer
36{
37 public class SynchronousRestObjectPoster
38 {
39 /// <summary>
40 /// Perform a synchronous REST request.
41 /// </summary>
42 /// <param name="verb"></param>
43 /// <param name="requestUrl"></param>
44 /// <param name="obj"> </param>
45 /// <returns></returns>
46 ///
47 /// <exception cref="System.Net.WebException">Thrown if we encounter a network issue while posting
48 /// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
49 public static TResponse BeginPostObject<TRequest, TResponse>(string verb, string requestUrl, TRequest obj)
50 {
51 Type type = typeof (TRequest);
52
53 WebRequest request = WebRequest.Create(requestUrl);
54 request.Method = verb;
55 request.ContentType = "text/xml";
56
57 MemoryStream buffer = new MemoryStream();
58
59 XmlWriterSettings settings = new XmlWriterSettings();
60 settings.Encoding = Encoding.UTF8;
61
62 using (XmlWriter writer = XmlWriter.Create(buffer, settings))
63 {
64 XmlSerializer serializer = new XmlSerializer(type);
65 serializer.Serialize(writer, obj);
66 writer.Flush();
67 }
68
69 int length = (int) buffer.Length;
70 request.ContentLength = length;
71
72 Stream requestStream = request.GetRequestStream();
73 requestStream.Write(buffer.ToArray(), 0, length);
74 TResponse deserial = default(TResponse);
75 using (WebResponse resp = request.GetResponse())
76 {
77 XmlSerializer deserializer = new XmlSerializer(typeof (TResponse));
78 deserial = (TResponse) deserializer.Deserialize(resp.GetResponseStream());
79 }
80 return deserial;
81 }
82 }
83}
diff --git a/OpenSim/Framework/Servers/HttpServer/XmlRpcMethod.cs b/OpenSim/Framework/Servers/HttpServer/XmlRpcMethod.cs
new file mode 100644
index 0000000..843b3f7
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/XmlRpcMethod.cs
@@ -0,0 +1,33 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using Nwc.XmlRpc;
29
30namespace OpenSim.Framework.Servers.HttpServer
31{
32 public delegate XmlRpcResponse XmlRpcMethod(XmlRpcRequest request);
33}
diff --git a/OpenSim/Framework/Servers/HttpServer/bin/Debug/OpenSim.Framework.Servers.HttpServer.dll b/OpenSim/Framework/Servers/HttpServer/bin/Debug/OpenSim.Framework.Servers.HttpServer.dll
new file mode 100755
index 0000000..a191346
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/bin/Debug/OpenSim.Framework.Servers.HttpServer.dll
Binary files differ
diff --git a/OpenSim/Framework/Servers/HttpServer/bin/Debug/OpenSim.Framework.Servers.HttpServer.dll.mdb b/OpenSim/Framework/Servers/HttpServer/bin/Debug/OpenSim.Framework.Servers.HttpServer.dll.mdb
new file mode 100644
index 0000000..25a50b9
--- /dev/null
+++ b/OpenSim/Framework/Servers/HttpServer/bin/Debug/OpenSim.Framework.Servers.HttpServer.dll.mdb
Binary files differ