123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- using System;
- using System.Collections.Generic;
- using System.Net;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading;
- //using OpenSim.CAPS;
- using Nwc.XmlRpc;
- using System.Collections;
- namespace OpenSim.Servers
- {
- public class BaseHttpServer
- {
- protected Thread m_workerThread;
- protected HttpListener m_httpListener;
- protected Dictionary<string, RestMethod> m_restHandlers = new Dictionary<string, RestMethod>();
- protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>();
- protected int m_port;
- public BaseHttpServer(int port)
- {
- m_port = port;
- }
- public bool AddRestHandler(string method, string path, RestMethod handler)
- {
- string methodKey = String.Format("{0}: {1}", method, path);
-
- if (!this.m_restHandlers.ContainsKey(methodKey))
- {
- this.m_restHandlers.Add(methodKey, handler);
- return true;
- }
- //must already have a handler for that path so return false
- return false;
- }
- public bool AddXmlRPCHandler(string method, XmlRpcMethod handler)
- {
- if (!this.m_rpcHandlers.ContainsKey(method))
- {
- this.m_rpcHandlers.Add(method, handler);
- return true;
- }
- //must already have a handler for that path so return false
- return false;
- }
- protected virtual string ProcessXMLRPCMethod(string methodName, XmlRpcRequest request)
- {
- XmlRpcResponse response;
-
- XmlRpcMethod method;
- if( this.m_rpcHandlers.TryGetValue( methodName, out method ) )
- {
- response = method(request);
- }
- else
- {
- response = new XmlRpcResponse();
- Hashtable unknownMethodError = new Hashtable();
- unknownMethodError["reason"] = "XmlRequest"; ;
- unknownMethodError["message"] = "Unknown Rpc request";
- unknownMethodError["login"] = "false";
- response.Value = unknownMethodError;
- }
- return XmlRpcResponseSerializer.Singleton.Serialize(response);
- }
- protected virtual string ParseREST(string request, string path, string method)
- {
- string response;
- RestMethod handler;
-
- string requestKey = String.Format("{0}: {1}", method, path);
-
- string bestMatch = String.Empty;
- foreach( string currentKey in m_restHandlers.Keys )
- {
- if( requestKey.StartsWith( currentKey ))
- {
- if(currentKey.Length > bestMatch.Length )
- {
- bestMatch = currentKey;
- }
- }
- }
-
- if (m_restHandlers.TryGetValue(bestMatch, out handler))
- {
- response = handler(request, path);
-
- }
- else
- {
- response = String.Empty;
- }
- return response;
- }
- protected virtual string ParseLLSDXML(string requestBody)
- {
- // dummy function for now - IMPLEMENT ME!
- return "";
- }
- protected virtual string ParseXMLRPC(string requestBody)
- {
- string responseString = String.Empty;
- try
- {
- XmlRpcRequest request = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody);
- string methodName = request.MethodName;
- responseString = ProcessXMLRPCMethod(methodName, request );
- }
- catch (Exception e)
- {
- Console.WriteLine(e.ToString());
- }
- return responseString;
- }
- public virtual void HandleRequest(Object stateinfo)
- {
- HttpListenerContext context = (HttpListenerContext)stateinfo;
- HttpListenerRequest request = context.Request;
- HttpListenerResponse response = context.Response;
- response.KeepAlive = false;
- response.SendChunked = false;
- System.IO.Stream body = request.InputStream;
- System.Text.Encoding encoding = System.Text.Encoding.UTF8;
- System.IO.StreamReader reader = new System.IO.StreamReader(body, encoding);
- string requestBody = reader.ReadToEnd();
- body.Close();
- reader.Close();
- //Console.WriteLine(request.HttpMethod + " " + request.RawUrl + " Http/" + request.ProtocolVersion.ToString() + " content type: " + request.ContentType);
- //Console.WriteLine(requestBody);
- string responseString = "";
- switch (request.ContentType)
- {
- case "text/xml":
- // must be XML-RPC, so pass to the XML-RPC parser
- responseString = ParseXMLRPC(requestBody);
- responseString = Regex.Replace(responseString, "utf-16", "utf-8");
-
- response.AddHeader("Content-type", "text/xml");
- break;
- case "application/xml":
- // probably LLSD we hope, otherwise it should be ignored by the parser
- responseString = ParseLLSDXML(requestBody);
- response.AddHeader("Content-type", "application/xml");
- break;
- case "application/x-www-form-urlencoded":
- // a form data POST so send to the REST parser
- responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
- response.AddHeader("Content-type", "text/html");
- break;
- case null:
- // must be REST or invalid crap, so pass to the REST parser
- responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
- response.AddHeader("Content-type", "text/html");
- break;
- }
- byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
- System.IO.Stream output = response.OutputStream;
- response.SendChunked = false;
- response.ContentLength64 = buffer.Length;
- output.Write(buffer, 0, buffer.Length);
- output.Close();
- }
- public void Start()
- {
- OpenSim.Framework.Console.MainConsole.Instance.WriteLine("BaseHttpServer.cs: Starting up HTTP Server");
- m_workerThread = new Thread(new ThreadStart(StartHTTP));
- m_workerThread.IsBackground = true;
- m_workerThread.Start();
- }
- private void StartHTTP()
- {
- try
- {
- OpenSim.Framework.Console.MainConsole.Instance.WriteLine("BaseHttpServer.cs: StartHTTP() - Spawned main thread OK");
- m_httpListener = new HttpListener();
- m_httpListener.Prefixes.Add("http://+:" + m_port + "/");
- m_httpListener.Start();
- HttpListenerContext context;
- while (true)
- {
- context = m_httpListener.GetContext();
- ThreadPool.QueueUserWorkItem(new WaitCallback(HandleRequest), context);
- }
- }
- catch (Exception e)
- {
- OpenSim.Framework.Console.MainConsole.Instance.WriteLine(e.Message);
- }
- }
- }
- }
|