aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/Servers/BaseHttpServer.cs129
-rw-r--r--OpenSim/Framework/Servers/IHttpAgentHandler.cs39
2 files changed, 142 insertions, 26 deletions
diff --git a/OpenSim/Framework/Servers/BaseHttpServer.cs b/OpenSim/Framework/Servers/BaseHttpServer.cs
index eeb63e1..51cb36e 100644
--- a/OpenSim/Framework/Servers/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/BaseHttpServer.cs
@@ -49,8 +49,9 @@ namespace OpenSim.Framework.Servers
49 protected HttpListener m_httpListener; 49 protected HttpListener m_httpListener;
50 protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>(); 50 protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>();
51 protected LLSDMethod m_llsdHandler = null; 51 protected LLSDMethod m_llsdHandler = null;
52 protected Dictionary<string, IRequestHandler> m_streamHandlers = new Dictionary<string, IRequestHandler>(); 52 protected Dictionary<string, IRequestHandler> m_streamHandlers = new Dictionary<string, IRequestHandler>();
53 protected Dictionary<string, GenericHTTPMethod> m_HTTPHandlers = new Dictionary<string, GenericHTTPMethod>(); 53 protected Dictionary<string, GenericHTTPMethod> m_HTTPHandlers = new Dictionary<string, GenericHTTPMethod>();
54 protected Dictionary<string, IHttpAgentHandler> m_agentHandlers = new Dictionary<string, IHttpAgentHandler>();
54 55
55 protected uint m_port; 56 protected uint m_port;
56 protected bool m_ssl = false; 57 protected bool m_ssl = false;
@@ -119,6 +120,18 @@ namespace OpenSim.Framework.Servers
119 return false; 120 return false;
120 } 121 }
121 122
123 public bool AddAgentHandler(string agent, IHttpAgentHandler handler)
124 {
125 if (!m_agentHandlers.ContainsKey(agent))
126 {
127 m_agentHandlers.Add(agent, handler);
128 return true;
129 }
130
131 //must already have a handler for that path so return false
132 return false;
133 }
134
122 public bool SetLLSDHandler(LLSDMethod handler) 135 public bool SetLLSDHandler(LLSDMethod handler)
123 { 136 {
124 m_llsdHandler = handler; 137 m_llsdHandler = handler;
@@ -139,30 +152,43 @@ namespace OpenSim.Framework.Servers
139 OSHttpRequest request = new OSHttpRequest(context.Request); 152 OSHttpRequest request = new OSHttpRequest(context.Request);
140 OSHttpResponse response = new OSHttpResponse(context.Response); 153 OSHttpResponse response = new OSHttpResponse(context.Response);
141 154
142 response.KeepAlive = false; 155 if (request.UserAgent != null)
156 {
157
158 IHttpAgentHandler agentHandler;
159
160 if (TryGetAgentHandler(request.UserAgent, out agentHandler))
161 {
162 m_log.DebugFormat("[HTTP-AGENT] Handler located for {0}", request.UserAgent);
163 HandleAgentRequest(agentHandler, request, response);
164 }
165 return;
166 }
167
168 IRequestHandler requestHandler;
169 response.KeepAlive = false;
143 response.SendChunked = false; 170 response.SendChunked = false;
144 171
145 string path = request.RawUrl; 172 string path = request.RawUrl;
146 string handlerKey = GetHandlerKey(request.HttpMethod, path); 173 string handlerKey = GetHandlerKey(request.HttpMethod, path);
147 174
148 //m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path); 175 //m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
149 176
150 IRequestHandler requestHandler;
151
152 if (TryGetStreamHandler(handlerKey, out requestHandler)) 177 if (TryGetStreamHandler(handlerKey, out requestHandler))
153 { 178 {
179
154 // Okay, so this is bad, but should be considered temporary until everything is IStreamHandler. 180 // Okay, so this is bad, but should be considered temporary until everything is IStreamHandler.
155 byte[] buffer; 181 byte[] buffer;
156 if (requestHandler is IStreamedRequestHandler) 182 if (requestHandler is IStreamedRequestHandler)
157 { 183 {
158 IStreamedRequestHandler streamedRequestHandler = requestHandler as IStreamedRequestHandler; 184 IStreamedRequestHandler streamedRequestHandler = requestHandler as IStreamedRequestHandler;
159 185
160 buffer = streamedRequestHandler.Handle(path, request.InputStream, request, response); 186 buffer = streamedRequestHandler.Handle(path, request.InputStream, request, response);
161 } 187 }
162 else 188 else
163 { 189 {
164 IStreamHandler streamHandler = (IStreamHandler) requestHandler; 190 IStreamHandler streamHandler = (IStreamHandler) requestHandler;
165 191
166 using (MemoryStream memoryStream = new MemoryStream()) 192 using (MemoryStream memoryStream = new MemoryStream())
167 { 193 {
168 streamHandler.Handle(path, request.InputStream, memoryStream, request, response); 194 streamHandler.Handle(path, request.InputStream, memoryStream, request, response);
@@ -170,11 +196,11 @@ namespace OpenSim.Framework.Servers
170 buffer = memoryStream.ToArray(); 196 buffer = memoryStream.ToArray();
171 } 197 }
172 } 198 }
173 199
174 request.InputStream.Close(); 200 request.InputStream.Close();
175 if (!response.IsContentTypeSet) response.ContentType = requestHandler.ContentType; 201 if (!response.IsContentTypeSet) response.ContentType = requestHandler.ContentType;
176 response.ContentLength64 = buffer.LongLength; 202 response.ContentLength64 = buffer.LongLength;
177 203
178 try 204 try
179 { 205 {
180 response.OutputStream.Write(buffer, 0, buffer.Length); 206 response.OutputStream.Write(buffer, 0, buffer.Length);
@@ -184,24 +210,25 @@ namespace OpenSim.Framework.Servers
184 { 210 {
185 m_log.WarnFormat("[BASE HTTP SERVER]: HTTP request abnormally terminated."); 211 m_log.WarnFormat("[BASE HTTP SERVER]: HTTP request abnormally terminated.");
186 } 212 }
213 return;
187 } 214 }
188 else 215
216 switch (request.ContentType)
189 { 217 {
190 switch (request.ContentType) 218 case null:
191 { 219 case "text/html":
192 case null: 220 HandleHTTPRequest(request, response);
193 case "text/html": 221 return;
194 HandleHTTPRequest(request, response); 222
195 break; 223 case "application/xml+llsd":
196 case "application/xml+llsd": 224 HandleLLSDRequests(request, response);
197 HandleLLSDRequests(request, response); 225 return;
198 break; 226
199 case "text/xml": 227 case "text/xml":
200 case "application/xml": 228 case "application/xml":
201 default: 229 default:
202 HandleXmlRpcRequests(request, response); 230 HandleXmlRpcRequests(request, response);
203 break; 231 return;
204 }
205 } 232 }
206 } 233 }
207 catch (SocketException) 234 catch (SocketException)
@@ -274,6 +301,26 @@ namespace OpenSim.Framework.Servers
274 } 301 }
275 } 302 }
276 303
304 private bool TryGetAgentHandler(string agent, out IHttpAgentHandler agentHandler)
305 {
306 agentHandler = null;
307 try
308 {
309 foreach(IHttpAgentHandler handler in m_agentHandlers.Values)
310 {
311 if(handler.Match(agent))
312 {
313 agentHandler = handler;
314 return true;
315 }
316 }
317 }
318 catch(KeyNotFoundException) {}
319
320 return false;
321
322 }
323
277 /// <summary> 324 /// <summary>
278 /// Try all the registered xmlrpc handlers when an xmlrpc request is received. 325 /// Try all the registered xmlrpc handlers when an xmlrpc request is received.
279 /// Sends back an XMLRPC unknown request response if no handler is registered for the requested method. 326 /// Sends back an XMLRPC unknown request response if no handler is registered for the requested method.
@@ -416,6 +463,36 @@ namespace OpenSim.Framework.Servers
416 } 463 }
417 } 464 }
418 465
466 /// <summary>
467 /// A specific agent handler was provided. Such a handler is expecetd to have an
468 /// intimate, and highly specific relationship with the client. Consequently,
469 /// nothing is done here.
470 /// </summary>
471 /// <param name="handler"></param>
472 /// <param name="request"></param>
473 /// <param name="response"></param>
474
475 private void HandleAgentRequest(IHttpAgentHandler handler, OSHttpRequest request, OSHttpResponse response)
476 {
477
478 // In the case of REST, then handler is responsible for ALL aspects of
479 // the request/response handling. Nothing is done here, not even encoding.
480
481 try
482 {
483 handler.Handle(request, response);
484 }
485 catch (Exception e)
486 {
487 m_log.Warn("[HTTP-AGENT]: Error - " + e.Message);
488 response.SendChunked = false;
489 response.KeepAlive = false;
490 response.StatusCode = 500;
491 response.OutputStream.Close();
492 }
493
494 }
495
419 public void HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response) 496 public void HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response)
420 { 497 {
421 switch (request.HttpMethod) 498 switch (request.HttpMethod)
diff --git a/OpenSim/Framework/Servers/IHttpAgentHandler.cs b/OpenSim/Framework/Servers/IHttpAgentHandler.cs
new file mode 100644
index 0000000..9bca150
--- /dev/null
+++ b/OpenSim/Framework/Servers/IHttpAgentHandler.cs
@@ -0,0 +1,39 @@
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;
30using System.Net;
31
32namespace OpenSim.Framework.Servers
33{
34 public interface IHttpAgentHandler
35 {
36 void Handle(OSHttpRequest req, OSHttpResponse resp);
37 bool Match(string agent);
38 }
39}