aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Servers
diff options
context:
space:
mode:
Diffstat (limited to 'Servers')
-rw-r--r--Servers/BaseHttpServer.cs201
-rw-r--r--Servers/IRestHandler.cs11
-rw-r--r--Servers/OpenSim.Servers.csproj2
-rw-r--r--Servers/OpenSim.Servers.dll.build2
-rw-r--r--Servers/XmlRpcMethod.cs7
5 files changed, 223 insertions, 0 deletions
diff --git a/Servers/BaseHttpServer.cs b/Servers/BaseHttpServer.cs
index 28849dc..bac7e86 100644
--- a/Servers/BaseHttpServer.cs
+++ b/Servers/BaseHttpServer.cs
@@ -1,10 +1,211 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using System.Net;
3using System.Text; 4using System.Text;
5using System.Text.RegularExpressions;
6using System.Threading;
7using OpenSim.CAPS;
8using Nwc.XmlRpc;
9using System.Collections;
4 10
5namespace OpenSim.Servers 11namespace OpenSim.Servers
6{ 12{
7 public class BaseHttpServer 13 public class BaseHttpServer
8 { 14 {
15 protected Thread m_workerThread;
16 protected HttpListener m_httpListener;
17 protected Dictionary<string, IRestHandler> m_restHandlers = new Dictionary<string, IRestHandler>();
18 protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>();
19 protected int m_port;
20
21 public BaseHttpServer(int port)
22 {
23 m_port = port;
24 }
25
26 public bool AddRestHandler(string path, IRestHandler handler)
27 {
28 if (!this.m_restHandlers.ContainsKey(path))
29 {
30 this.m_restHandlers.Add(path, handler);
31 return true;
32 }
33
34 //must already have a handler for that path so return false
35 return false;
36 }
37
38 public bool AddXmlRPCHandler(string method, XmlRpcMethod handler)
39 {
40 if (!this.m_rpcHandlers.ContainsKey(method))
41 {
42 this.m_rpcHandlers.Add(method, handler);
43 return true;
44 }
45
46 //must already have a handler for that path so return false
47 return false;
48 }
49
50 protected virtual string ProcessXMLRPCMethod(string methodName, XmlRpcRequest request)
51 {
52 XmlRpcResponse response;
53
54 XmlRpcMethod method;
55 if( this.m_rpcHandlers.TryGetValue( methodName, out method ) )
56 {
57 response = method(request);
58 }
59 else
60 {
61 response = new XmlRpcResponse();
62 Hashtable unknownMethodError = new Hashtable();
63 unknownMethodError["reason"] = "XmlRequest"; ;
64 unknownMethodError["message"] = "Unknown Rpc request";
65 unknownMethodError["login"] = "false";
66 response.Value = unknownMethodError;
67 }
68
69 return XmlRpcResponseSerializer.Singleton.Serialize(response);
70 }
71
72 protected virtual string ParseREST(string requestBody, string requestURL, string requestMethod)
73 {
74 string[] path;
75 string pathDelimStr = "/";
76 char[] pathDelimiter = pathDelimStr.ToCharArray();
77 path = requestURL.Split(pathDelimiter);
78
79 string responseString = "";
80
81 //path[0] should be empty so we are interested in path[1]
82 if (path.Length > 1)
83 {
84 if ((path[1] != "") && (this.m_restHandlers.ContainsKey(path[1])))
85 {
86 responseString = this.m_restHandlers[path[1]].HandleREST(requestBody, requestURL, requestMethod);
87 }
88 }
89
90 return responseString;
91 }
92
93 protected virtual string ParseLLSDXML(string requestBody)
94 {
95 // dummy function for now - IMPLEMENT ME!
96 return "";
97 }
98
99 protected virtual string ParseXMLRPC(string requestBody)
100 {
101 string responseString = String.Empty;
102
103 try
104 {
105 XmlRpcRequest request = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody);
106
107 string methodName = request.MethodName;
108
109 responseString = ProcessXMLRPCMethod(methodName, request );
110 }
111 catch (Exception e)
112 {
113 Console.WriteLine(e.ToString());
114 }
115 return responseString;
116 }
117
118 public virtual void HandleRequest(Object stateinfo)
119 {
120 HttpListenerContext context = (HttpListenerContext)stateinfo;
121
122 HttpListenerRequest request = context.Request;
123 HttpListenerResponse response = context.Response;
124
125 response.KeepAlive = false;
126 response.SendChunked = false;
127
128 System.IO.Stream body = request.InputStream;
129 System.Text.Encoding encoding = System.Text.Encoding.UTF8;
130 System.IO.StreamReader reader = new System.IO.StreamReader(body, encoding);
131
132 string requestBody = reader.ReadToEnd();
133 body.Close();
134 reader.Close();
135
136 //Console.WriteLine(request.HttpMethod + " " + request.RawUrl + " Http/" + request.ProtocolVersion.ToString() + " content type: " + request.ContentType);
137 //Console.WriteLine(requestBody);
138
139 string responseString = "";
140 switch (request.ContentType)
141 {
142 case "text/xml":
143 // must be XML-RPC, so pass to the XML-RPC parser
144
145 responseString = ParseXMLRPC(requestBody);
146 responseString = Regex.Replace(responseString, "utf-16", "utf-8");
147
148 response.AddHeader("Content-type", "text/xml");
149 break;
150
151 case "application/xml":
152 // probably LLSD we hope, otherwise it should be ignored by the parser
153 responseString = ParseLLSDXML(requestBody);
154 response.AddHeader("Content-type", "application/xml");
155 break;
156
157 case "application/x-www-form-urlencoded":
158 // a form data POST so send to the REST parser
159 responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
160 response.AddHeader("Content-type", "text/html");
161 break;
162
163 case null:
164 // must be REST or invalid crap, so pass to the REST parser
165 responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
166 response.AddHeader("Content-type", "text/html");
167 break;
168
169 }
170
171 byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
172 System.IO.Stream output = response.OutputStream;
173 response.SendChunked = false;
174 response.ContentLength64 = buffer.Length;
175 output.Write(buffer, 0, buffer.Length);
176 output.Close();
177 }
178
179 public void Start()
180 {
181 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("BaseHttpServer.cs: Starting up HTTP Server");
182
183 m_workerThread = new Thread(new ThreadStart(StartHTTP));
184 m_workerThread.IsBackground = true;
185 m_workerThread.Start();
186 }
187
188 private void StartHTTP()
189 {
190 try
191 {
192 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("BaseHttpServer.cs: StartHTTP() - Spawned main thread OK");
193 m_httpListener = new HttpListener();
194
195 m_httpListener.Prefixes.Add("http://+:" + m_port + "/");
196 m_httpListener.Start();
197
198 HttpListenerContext context;
199 while (true)
200 {
201 context = m_httpListener.GetContext();
202 ThreadPool.QueueUserWorkItem(new WaitCallback(HandleRequest), context);
203 }
204 }
205 catch (Exception e)
206 {
207 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(e.Message);
208 }
209 }
9 } 210 }
10} 211}
diff --git a/Servers/IRestHandler.cs b/Servers/IRestHandler.cs
new file mode 100644
index 0000000..f269600
--- /dev/null
+++ b/Servers/IRestHandler.cs
@@ -0,0 +1,11 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace OpenSim.CAPS
6{
7 public interface IRestHandler
8 {
9 string HandleREST(string requestBody, string requestURL, string requestMethod);
10 }
11}
diff --git a/Servers/OpenSim.Servers.csproj b/Servers/OpenSim.Servers.csproj
index c983fca..9710f47 100644
--- a/Servers/OpenSim.Servers.csproj
+++ b/Servers/OpenSim.Servers.csproj
@@ -96,6 +96,8 @@
96 <Compile Include="BaseHttpServer.cs"> 96 <Compile Include="BaseHttpServer.cs">
97 <SubType>Code</SubType> 97 <SubType>Code</SubType>
98 </Compile> 98 </Compile>
99 <Compile Include="IRestHandler.cs" />
100 <Compile Include="XmlRpcMethod.cs" />
99 </ItemGroup> 101 </ItemGroup>
100 <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" /> 102 <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
101 <PropertyGroup> 103 <PropertyGroup>
diff --git a/Servers/OpenSim.Servers.dll.build b/Servers/OpenSim.Servers.dll.build
index 8600ab5..48e8dec 100644
--- a/Servers/OpenSim.Servers.dll.build
+++ b/Servers/OpenSim.Servers.dll.build
@@ -12,6 +12,8 @@
12 </resources> 12 </resources>
13 <sources failonempty="true"> 13 <sources failonempty="true">
14 <include name="BaseHttpServer.cs" /> 14 <include name="BaseHttpServer.cs" />
15 <include name="IRestHandler.cs" />
16 <include name="XmlRpcMethod.cs" />
15 </sources> 17 </sources>
16 <references basedir="${project::get-base-directory()}"> 18 <references basedir="${project::get-base-directory()}">
17 <lib> 19 <lib>
diff --git a/Servers/XmlRpcMethod.cs b/Servers/XmlRpcMethod.cs
new file mode 100644
index 0000000..2295405
--- /dev/null
+++ b/Servers/XmlRpcMethod.cs
@@ -0,0 +1,7 @@
1using System;
2using Nwc.XmlRpc;
3
4namespace OpenSim.Servers
5{
6 public delegate XmlRpcResponse XmlRpcMethod( XmlRpcRequest request );
7}