diff options
Diffstat (limited to '')
4 files changed, 172 insertions, 24 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 | |||
29 | using System; | ||
30 | using System.Threading; | ||
31 | using System.Collections; | ||
32 | using System.Collections.Generic; | ||
33 | using System.IO; | ||
34 | using System.Net; | ||
35 | using System.Reflection; | ||
36 | using System.Text.RegularExpressions; | ||
37 | using System.Timers; | ||
38 | using System.Xml; | ||
39 | using System.Xml.Serialization; | ||
40 | using libsecondlife; | ||
41 | using Mono.Addins; | ||
42 | using Nwc.XmlRpc; | ||
43 | using Nini.Config; | ||
44 | using OpenSim.Framework; | ||
45 | using OpenSim.Framework.Console; | ||
46 | using OpenSim.Framework.Servers; | ||
47 | using OpenSim.Framework.Communications; | ||
48 | using OpenSim.Region.Environment.Scenes; | ||
49 | using OpenSim.ApplicationPlugins.Rest; | ||
50 | |||
51 | namespace 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 | ||