aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs34
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Regions/POSTHandler.cs101
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Regions/RestRegionPlugin.cs1
-rw-r--r--OpenSim/ApplicationPlugins/Rest/RestPlugin.cs60
-rw-r--r--OpenSim/Framework/Servers/BaseHttpServer.cs69
-rw-r--r--OpenSim/Framework/Servers/IHttpAgentHandler.cs4
-rw-r--r--OpenSim/Framework/Servers/OSHttpStatusCodes.cs168
7 files changed, 392 insertions, 45 deletions
diff --git a/OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs b/OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs
index a319a8b..b89976f 100644
--- a/OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs
+++ b/OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs
@@ -67,18 +67,18 @@ namespace OpenSim.ApplicationPlugins.Rest.Regions
67 try 67 try
68 { 68 {
69 // param empty: regions list 69 // param empty: regions list
70 if (String.IsNullOrEmpty(param)) return GetHandlerRegions(); 70 if (String.IsNullOrEmpty(param)) return GetHandlerRegions(httpResponse);
71 71
72 // param not empty: specific region 72 // param not empty: specific region
73 return GetHandlerRegion(param); 73 return GetHandlerRegion(httpResponse, param);
74 } 74 }
75 catch (Exception e) 75 catch (Exception e)
76 { 76 {
77 return Failure("GET", e); 77 return Failure(httpResponse, OSHttpStatusCode.ServerErrorInternalError, "GET", e);
78 } 78 }
79 } 79 }
80 80
81 public string GetHandlerRegions() 81 public string GetHandlerRegions(OSHttpResponse httpResponse)
82 { 82 {
83 XmlWriter.WriteStartElement(String.Empty, "regions", String.Empty); 83 XmlWriter.WriteStartElement(String.Empty, "regions", String.Empty);
84 foreach (Scene s in App.SceneManager.Scenes) 84 foreach (Scene s in App.SceneManager.Scenes)
@@ -105,7 +105,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Regions
105 return XmlWriterResult; 105 return XmlWriterResult;
106 } 106 }
107 107
108 public string GetHandlerRegion(string param) 108 public string GetHandlerRegion(OSHttpResponse httpResponse, string param)
109 { 109 {
110 // be resilient and don't get confused by a terminating '/' 110 // be resilient and don't get confused by a terminating '/'
111 param = param.TrimEnd(new char[]{'/'}); 111 param = param.TrimEnd(new char[]{'/'});
@@ -118,7 +118,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Regions
118 118
119 Scene scene = null; 119 Scene scene = null;
120 App.SceneManager.TryGetScene(regionID, out scene); 120 App.SceneManager.TryGetScene(regionID, out scene);
121 if (null == scene) return Failure("GET", "cannot find region"); 121 if (null == scene) return Failure(httpResponse, OSHttpStatusCode.ClientErrorNotFound,
122 "GET", "cannot find region {0}", regionID.ToString());
122 123
123 RegionDetails details = new RegionDetails(scene.RegionInfo); 124 RegionDetails details = new RegionDetails(scene.RegionInfo);
124 125
@@ -143,25 +144,27 @@ namespace OpenSim.ApplicationPlugins.Rest.Regions
143 switch (comps[1].ToLower()) 144 switch (comps[1].ToLower())
144 { 145 {
145 case "terrain": 146 case "terrain":
146 return RegionTerrain(scene); 147 return RegionTerrain(httpResponse, scene);
147 148
148 case "stats": 149 case "stats":
149 return RegionStats(scene); 150 return RegionStats(httpResponse, scene);
150 151
151 case "prims": 152 case "prims":
152 return RegionPrims(scene); 153 return RegionPrims(httpResponse, scene);
153 } 154 }
154 } 155 }
155 return Failure("GET", "too many parameters"); 156 return Failure(httpResponse, OSHttpStatusCode.ClientErrorBadRequest,
157 "GET", "too many parameters {0}", param);
156 } 158 }
157 #endregion GET methods 159 #endregion GET methods
158 160
159 protected string RegionTerrain(Scene scene) 161 protected string RegionTerrain(OSHttpResponse httpResponse, Scene scene)
160 { 162 {
161 return Failure("GET", "terrain not implemented"); 163 return Failure(httpResponse, OSHttpStatusCode.ServerErrorNotImplemented,
164 "GET", "terrain not implemented");
162 } 165 }
163 166
164 protected string RegionStats(Scene scene) 167 protected string RegionStats(OSHttpResponse httpResponse, Scene scene)
165 { 168 {
166 int users = scene.GetAvatars().Count; 169 int users = scene.GetAvatars().Count;
167 int objects = scene.Entities.Count - users; 170 int objects = scene.Entities.Count - users;
@@ -182,9 +185,10 @@ namespace OpenSim.ApplicationPlugins.Rest.Regions
182 return XmlWriterResult; 185 return XmlWriterResult;
183 } 186 }
184 187
185 protected string RegionPrims(Scene scene) 188 protected string RegionPrims(OSHttpResponse httpResponse, Scene scene)
186 { 189 {
187 return Failure("GET", "prims not implemented"); 190 return Failure(httpResponse, OSHttpStatusCode.ServerErrorNotImplemented,
191 "GET", "prims not implemented");
188 } 192 }
189 } 193 }
190} 194}
diff --git a/OpenSim/ApplicationPlugins/Rest/Regions/POSTHandler.cs b/OpenSim/ApplicationPlugins/Rest/Regions/POSTHandler.cs
new file mode 100644
index 0000000..00fe0d2
--- /dev/null
+++ b/OpenSim/ApplicationPlugins/Rest/Regions/POSTHandler.cs
@@ -0,0 +1,101 @@
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
29using System;
30using System.Threading;
31using System.Collections;
32using System.Collections.Generic;
33using System.IO;
34using System.Net;
35using System.Reflection;
36using System.Text.RegularExpressions;
37using System.Timers;
38using System.Xml;
39using System.Xml.Serialization;
40using libsecondlife;
41using Mono.Addins;
42using Nwc.XmlRpc;
43using Nini.Config;
44using OpenSim.Framework;
45using OpenSim.Framework.Console;
46using OpenSim.Framework.Servers;
47using OpenSim.Framework.Communications;
48using OpenSim.Region.Environment.Scenes;
49using OpenSim.ApplicationPlugins.Rest;
50
51namespace OpenSim.ApplicationPlugins.Rest.Regions
52{
53
54 public partial class RestRegionPlugin : RestPlugin
55 {
56 #region POST methods
57 public string PostHandler(string request, string path, string param,
58 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
59 {
60 // foreach (string h in httpRequest.Headers.AllKeys)
61 // foreach (string v in httpRequest.Headers.GetValues(h))
62 // m_log.DebugFormat("{0} IsGod: {1} -> {2}", MsgID, h, v);
63
64 MsgID = RequestID;
65 m_log.DebugFormat("{0} POST path {1} param {2}", MsgID, path, param);
66
67 try
68 {
69 // param empty: new region post
70 if (!IsGod(httpRequest))
71 // XXX: this needs to be turned into a FailureUnauthorized(...)
72 return Failure(httpResponse, OSHttpStatusCode.ClientErrorUnauthorized,
73 "GET", "you are not god");
74
75 if (String.IsNullOrEmpty(param)) return CreateRegion(httpRequest, httpResponse);
76
77 return Failure(httpResponse, OSHttpStatusCode.ClientErrorNotFound,
78 "POST", "url {0} not supported", param);
79 }
80 catch (Exception e)
81 {
82 return Failure(httpResponse, OSHttpStatusCode.ServerErrorInternalError, "POST", e);
83 }
84 }
85
86 public string CreateRegion(OSHttpRequest request, OSHttpResponse response)
87 {
88 XmlWriter.WriteStartElement(String.Empty, "regions", String.Empty);
89 foreach (Scene s in App.SceneManager.Scenes)
90 {
91 XmlWriter.WriteStartElement(String.Empty, "uuid", String.Empty);
92 XmlWriter.WriteString(s.RegionInfo.RegionID.ToString());
93 XmlWriter.WriteEndElement();
94 }
95 XmlWriter.WriteEndElement();
96
97 return XmlWriterResult;
98 }
99 #endregion POST methods
100 }
101}
diff --git a/OpenSim/ApplicationPlugins/Rest/Regions/RestRegionPlugin.cs b/OpenSim/ApplicationPlugins/Rest/Regions/RestRegionPlugin.cs
index 9b888fa..6d585a4 100644
--- a/OpenSim/ApplicationPlugins/Rest/Regions/RestRegionPlugin.cs
+++ b/OpenSim/ApplicationPlugins/Rest/Regions/RestRegionPlugin.cs
@@ -92,6 +92,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Regions
92 92
93 // add REST method handlers 93 // add REST method handlers
94 AddRestStreamHandler("GET", "/regions/", GetHandler); 94 AddRestStreamHandler("GET", "/regions/", GetHandler);
95 AddRestStreamHandler("POST", "/regions/", PostHandler);
95 } 96 }
96 catch (Exception e) 97 catch (Exception e)
97 { 98 {
diff --git a/OpenSim/ApplicationPlugins/Rest/RestPlugin.cs b/OpenSim/ApplicationPlugins/Rest/RestPlugin.cs
index 4b8cdc1..f1ca83d 100644
--- a/OpenSim/ApplicationPlugins/Rest/RestPlugin.cs
+++ b/OpenSim/ApplicationPlugins/Rest/RestPlugin.cs
@@ -66,7 +66,7 @@ namespace OpenSim.ApplicationPlugins.Rest
66 private string _prefix; // URL prefix below 66 private string _prefix; // URL prefix below
67 // which all REST URLs 67 // which all REST URLs
68 // are living 68 // are living
69 private StringWriter _sw = null; 69 private StringWriter _sw = null;
70 private XmlTextWriter _xw = null; 70 private XmlTextWriter _xw = null;
71 71
72 private string _godkey; 72 private string _godkey;
@@ -240,7 +240,8 @@ namespace OpenSim.ApplicationPlugins.Rest
240 } 240 }
241 } 241 }
242 242
243 private List<RestStreamHandler> _handlers = new List<RestStreamHandler>(); 243 private List<RestStreamHandler> _handlers = new List<RestStreamHandler>();
244 private Dictionary<string, IHttpAgentHandler> _agents = new Dictionary<string, IHttpAgentHandler>();
244 245
245 /// <summary> 246 /// <summary>
246 /// Add a REST stream handler to the underlying HTTP server. 247 /// Add a REST stream handler to the underlying HTTP server.
@@ -271,15 +272,39 @@ namespace OpenSim.ApplicationPlugins.Rest
271 /// </summary> 272 /// </summary>
272 /// <param name="agentName">name of agent handler</param> 273 /// <param name="agentName">name of agent handler</param>
273 /// <param name="handler">agent handler method</param> 274 /// <param name="handler">agent handler method</param>
274 /// <returns>true when the plugin is disabled or the agent 275 /// <returns>false when the plugin is disabled or the agent
275 /// handler could not be added..</returns> 276 /// handler could not be added. Any generated exceptions are
277 /// allowed to drop through to the caller, i.e. ArgumentException.
278 /// </returns>
276 public bool AddAgentHandler(string agentName, IHttpAgentHandler handler) 279 public bool AddAgentHandler(string agentName, IHttpAgentHandler handler)
277 { 280 {
278 if (!IsEnabled) return false; 281 if (!IsEnabled) return false;
282 _agents.Add(agentName, handler);
279 return _httpd.AddAgentHandler(agentName, handler); 283 return _httpd.AddAgentHandler(agentName, handler);
280 } 284 }
281 285
282 /// <summary> 286 /// <summary>
287 /// Remove a powerful Agent handler from the underlying HTTP
288 /// server.
289 /// </summary>
290 /// <param name="agentName">name of agent handler</param>
291 /// <param name="handler">agent handler method</param>
292 /// <returns>false when the plugin is disabled or the agent
293 /// handler could not be removed. Any generated exceptions are
294 /// allowed to drop through to the caller, i.e. KeyNotFound.
295 /// </returns>
296 public bool RemoveAgentHandler(string agentName, IHttpAgentHandler handler)
297 {
298 if (!IsEnabled) return false;
299 if(_agents[agentName] == handler)
300 {
301 _agents.Remove(agentName);
302 return _httpd.RemoveAgentHandler(agentName, handler);
303 }
304 return false;
305 }
306
307 /// <summary>
283 /// Check whether the HTTP request came from god; that is, is 308 /// Check whether the HTTP request came from god; that is, is
284 /// the god_key as configured in the config section supplied 309 /// the god_key as configured in the config section supplied
285 /// via X-OpenSim-Godkey? 310 /// via X-OpenSim-Godkey?
@@ -316,19 +341,30 @@ namespace OpenSim.ApplicationPlugins.Rest
316 _httpd.RemoveStreamHandler(h.HttpMethod, h.Path); 341 _httpd.RemoveStreamHandler(h.HttpMethod, h.Path);
317 } 342 }
318 _handlers = null; 343 _handlers = null;
344 foreach (KeyValuePair<string,IHttpAgentHandler> h in _agents)
345 {
346 _httpd.RemoveAgentHandler(h.Key,h.Value);
347 }
348 _agents = null;
319 } 349 }
320 350
321 /// <summary> 351 /// <summary>
322 /// Return a failure message. 352 /// Return a failure message.
323 /// </summary> 353 /// </summary>
324 /// <param name="method">origin of the failure message</param> 354 /// <param name="method">origin of the failure message</param>
325 /// <param name="message>failure message</param> 355 /// <param name="message">failure message</param>
326 /// <remarks>This should probably set a return code as 356 /// <remarks>This should probably set a return code as
327 /// well. (?)</remarks> 357 /// well. (?)</remarks>
328 protected string Failure(string method, string message) 358 protected string Failure(OSHttpResponse response, OSHttpStatusCode status,
359 string method, string format, params string[] msg)
329 { 360 {
330 m_log.ErrorFormat("{0} {1} failed: {2}", MsgID, method, message); 361 string m = String.Format(format, msg);
331 return String.Format("<error>{0}</error>", message); 362
363 response.StatusCode = (int)status;
364 response.StatusDescription = m;
365
366 m_log.ErrorFormat("{0} {1} failed: {2}", MsgID, method, m);
367 return String.Format("<error>{0}</error>", m);
332 } 368 }
333 369
334 /// <summary> 370 /// <summary>
@@ -338,8 +374,14 @@ namespace OpenSim.ApplicationPlugins.Rest
338 /// <param name="e">exception causing the failure message</param> 374 /// <param name="e">exception causing the failure message</param>
339 /// <remarks>This should probably set a return code as 375 /// <remarks>This should probably set a return code as
340 /// well. (?)</remarks> 376 /// well. (?)</remarks>
341 public string Failure(string method, Exception e) 377 public string Failure(OSHttpResponse response, OSHttpStatusCode status,
378 string method, Exception e)
342 { 379 {
380 string m = String.Format("exception occurred: {0}", e.Message);
381
382 response.StatusCode = (int)status;
383 response.StatusDescription = m;
384
343 m_log.DebugFormat("{0} {1} failed: {2}", MsgID, method, e.ToString()); 385 m_log.DebugFormat("{0} {1} failed: {2}", MsgID, method, e.ToString());
344 m_log.ErrorFormat("{0} {1} failed: {2}", MsgID, method, e.Message); 386 m_log.ErrorFormat("{0} {1} failed: {2}", MsgID, method, e.Message);
345 387
diff --git a/OpenSim/Framework/Servers/BaseHttpServer.cs b/OpenSim/Framework/Servers/BaseHttpServer.cs
index a5e256b..91b5718 100644
--- a/OpenSim/Framework/Servers/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/BaseHttpServer.cs
@@ -120,6 +120,10 @@ namespace OpenSim.Framework.Servers
120 return false; 120 return false;
121 } 121 }
122 122
123 // Note that the agent string is provided simply to differentiate
124 // the handlers - it is NOT required to be an actual agent header
125 // value.
126
123 public bool AddAgentHandler(string agent, IHttpAgentHandler handler) 127 public bool AddAgentHandler(string agent, IHttpAgentHandler handler)
124 { 128 {
125 if (!m_agentHandlers.ContainsKey(agent)) 129 if (!m_agentHandlers.ContainsKey(agent))
@@ -149,7 +153,7 @@ namespace OpenSim.Framework.Servers
149 { 153 {
150 HttpListenerContext context = (HttpListenerContext) stateinfo; 154 HttpListenerContext context = (HttpListenerContext) stateinfo;
151 155
152 OSHttpRequest request = new OSHttpRequest(context.Request); 156 OSHttpRequest request = new OSHttpRequest(context.Request);
153 OSHttpResponse response = new OSHttpResponse(context.Response); 157 OSHttpResponse response = new OSHttpResponse(context.Response);
154 158
155 if (request.UserAgent != null) 159 if (request.UserAgent != null)
@@ -157,11 +161,11 @@ namespace OpenSim.Framework.Servers
157 161
158 IHttpAgentHandler agentHandler; 162 IHttpAgentHandler agentHandler;
159 163
160 if (TryGetAgentHandler(request.UserAgent, out agentHandler)) 164 if (TryGetAgentHandler(request, response, out agentHandler))
161 { 165 {
162 m_log.DebugFormat("[HTTP-AGENT] Handler located for {0}", request.UserAgent); 166 // m_log.DebugFormat("[HTTP-AGENT] Handler located for {0}", request.UserAgent);
163 HandleAgentRequest(agentHandler, request, response); 167 if(HandleAgentRequest(agentHandler, request, response))
164 return; 168 return;
165 } 169 }
166 } 170 }
167 171
@@ -301,14 +305,14 @@ namespace OpenSim.Framework.Servers
301 } 305 }
302 } 306 }
303 307
304 private bool TryGetAgentHandler(string agent, out IHttpAgentHandler agentHandler) 308 private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler)
305 { 309 {
306 agentHandler = null; 310 agentHandler = null;
307 try 311 try
308 { 312 {
309 foreach(IHttpAgentHandler handler in m_agentHandlers.Values) 313 foreach(IHttpAgentHandler handler in m_agentHandlers.Values)
310 { 314 {
311 if(handler.Match(agent)) 315 if(handler.Match(request, response))
312 { 316 {
313 agentHandler = handler; 317 agentHandler = handler;
314 return true; 318 return true;
@@ -472,7 +476,7 @@ namespace OpenSim.Framework.Servers
472 /// <param name="request"></param> 476 /// <param name="request"></param>
473 /// <param name="response"></param> 477 /// <param name="response"></param>
474 478
475 private void HandleAgentRequest(IHttpAgentHandler handler, OSHttpRequest request, OSHttpResponse response) 479 private bool HandleAgentRequest(IHttpAgentHandler handler, OSHttpRequest request, OSHttpResponse response)
476 { 480 {
477 481
478 // In the case of REST, then handler is responsible for ALL aspects of 482 // In the case of REST, then handler is responsible for ALL aspects of
@@ -480,17 +484,27 @@ namespace OpenSim.Framework.Servers
480 484
481 try 485 try
482 { 486 {
483 handler.Handle(request, response); 487 return handler.Handle(request, response);
484 } 488 }
485 catch (Exception e) 489 catch (Exception e)
486 { 490 {
487 m_log.Warn("[HTTP-AGENT]: Error - " + e.Message); 491 // If the handler did in fact close the stream, then this will blow
488 response.SendChunked = false; 492 // chunks, so that that doesn;t disturb anybody we throw away any
489 response.KeepAlive = false; 493 // and all exceptions raised. We've done our best to release the
490 response.StatusCode = 500; 494 // client.
491 response.OutputStream.Close(); 495 try
496 {
497 m_log.Warn("[HTTP-AGENT]: Error - " + e.Message);
498 response.SendChunked = false;
499 response.KeepAlive = false;
500 response.StatusCode = (int)OSHttpStatusCode.ServerErrorInternalError;
501 response.OutputStream.Close();
502 }
503 catch(Exception){}
492 } 504 }
493 505
506 return true;
507
494 } 508 }
495 509
496 public void HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response) 510 public void HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response)
@@ -498,7 +512,7 @@ namespace OpenSim.Framework.Servers
498 switch (request.HttpMethod) 512 switch (request.HttpMethod)
499 { 513 {
500 case "OPTIONS": 514 case "OPTIONS":
501 response.StatusCode = 200; 515 response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
502 return; 516 return;
503 517
504 default: 518 default:
@@ -599,9 +613,9 @@ namespace OpenSim.Framework.Servers
599 // We're forgoing the usual error status codes here because the client 613 // We're forgoing the usual error status codes here because the client
600 // ignores anything but 200 and 301 614 // ignores anything but 200 and 301
601 615
602 response.StatusCode = 200; 616 response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
603 617
604 if (responsecode == 301) 618 if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently)
605 { 619 {
606 response.RedirectLocation = (string)responsedata["str_redirect_location"]; 620 response.RedirectLocation = (string)responsedata["str_redirect_location"];
607 response.StatusCode = responsecode; 621 response.StatusCode = responsecode;
@@ -632,7 +646,7 @@ namespace OpenSim.Framework.Servers
632 public void SendHTML404(OSHttpResponse response, string host) 646 public void SendHTML404(OSHttpResponse response, string host)
633 { 647 {
634 // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s 648 // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
635 response.StatusCode = 200; 649 response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
636 response.AddHeader("Content-type", "text/html"); 650 response.AddHeader("Content-type", "text/html");
637 651
638 string responseString = GetHTTP404(host); 652 string responseString = GetHTTP404(host);
@@ -659,7 +673,7 @@ namespace OpenSim.Framework.Servers
659 public void SendHTML500(OSHttpResponse response) 673 public void SendHTML500(OSHttpResponse response)
660 { 674 {
661 // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s 675 // I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
662 response.StatusCode = 200; 676 response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
663 response.AddHeader("Content-type", "text/html"); 677 response.AddHeader("Content-type", "text/html");
664 678
665 string responseString = GetHTTP500(); 679 string responseString = GetHTTP500();
@@ -738,6 +752,23 @@ namespace OpenSim.Framework.Servers
738 m_HTTPHandlers.Remove(GetHandlerKey(httpMethod, path)); 752 m_HTTPHandlers.Remove(GetHandlerKey(httpMethod, path));
739 } 753 }
740 754
755 // Remove the agent IF it is registered. Intercept the possible
756 // exception.
757
758 public bool RemoveAgentHandler(string agent, IHttpAgentHandler handler)
759 {
760 try
761 {
762 if(handler == m_agentHandlers[agent])
763 {
764 m_agentHandlers.Remove(agent);
765 return true;
766 }
767 }
768 catch(KeyNotFoundException) {}
769 return false;
770 }
771
741 public string GetHTTP404(string host) 772 public string GetHTTP404(string host)
742 { 773 {
743 string file = Path.Combine(Util.configDir(), "http_404.html"); 774 string file = Path.Combine(Util.configDir(), "http_404.html");
diff --git a/OpenSim/Framework/Servers/IHttpAgentHandler.cs b/OpenSim/Framework/Servers/IHttpAgentHandler.cs
index 9bca150..ff3a5b9 100644
--- a/OpenSim/Framework/Servers/IHttpAgentHandler.cs
+++ b/OpenSim/Framework/Servers/IHttpAgentHandler.cs
@@ -33,7 +33,7 @@ namespace OpenSim.Framework.Servers
33{ 33{
34 public interface IHttpAgentHandler 34 public interface IHttpAgentHandler
35 { 35 {
36 void Handle(OSHttpRequest req, OSHttpResponse resp); 36 bool Handle(OSHttpRequest req, OSHttpResponse resp);
37 bool Match(string agent); 37 bool Match(OSHttpRequest req, OSHttpResponse resp);
38 } 38 }
39} 39}
diff --git a/OpenSim/Framework/Servers/OSHttpStatusCodes.cs b/OpenSim/Framework/Servers/OSHttpStatusCodes.cs
new file mode 100644
index 0000000..2e001cf
--- /dev/null
+++ b/OpenSim/Framework/Servers/OSHttpStatusCodes.cs
@@ -0,0 +1,168 @@
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
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
142 // 5xx Server errors (rare)
143 // 500 Server error: something really strange and unexpected
144 // happened
145 ServerErrorInternalError = 500,
146 // 501 Server error: The server does not do the functionality
147 // required to carry out the client request. not at
148 // all. certainly not before breakfast. but also not after
149 // breakfast.
150 ServerErrorNotImplemented = 501,
151 // 502 Server error: While acting as a proxy or a gateway, the
152 // server got ditched by the upstream server and as a
153 // consequence regretfully cannot fulfill the client's request
154 ServerErrorBadGateway = 502,
155 // 503 Server error: Due to unforseen circumstances the server
156 // cannot currently deliver the service requested. Retry-After
157 // header might indicate when to try again.
158 ServerErrorServiceUnavailable = 503,
159 // 504 Server error: The server blames the upstream server
160 // for not being able to deliver the service requested and
161 // claims that the upstream server is too slow delivering the
162 // goods.
163 ServerErrorGatewayTimeout = 504,
164 // 505 Server error: The server does not support the HTTP
165 // version conveyed in the client's request.
166 ServerErrorHttpVersionNotSupported = 505,
167 }
168}