aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/ServiceConnectors/Interregion
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/ServiceConnectors/Interregion')
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectors/Interregion/LocalInterregionComms.cs302
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectors/Interregion/RESTInterregionComms.cs921
2 files changed, 1223 insertions, 0 deletions
diff --git a/OpenSim/Region/CoreModules/ServiceConnectors/Interregion/LocalInterregionComms.cs b/OpenSim/Region/CoreModules/ServiceConnectors/Interregion/LocalInterregionComms.cs
new file mode 100644
index 0000000..b94efa7
--- /dev/null
+++ b/OpenSim/Region/CoreModules/ServiceConnectors/Interregion/LocalInterregionComms.cs
@@ -0,0 +1,302 @@
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 */
27using System.Collections.Generic;
28using System.Reflection;
29using log4net;
30using Nini.Config;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes;
35
36namespace OpenSim.Region.CoreModules.ServiceConnectors.Interregion
37{
38 public class LocalInterregionComms : IRegionModule, IInterregionCommsOut, IInterregionCommsIn
39 {
40 private bool m_enabled = false;
41
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43 private List<Scene> m_sceneList = new List<Scene>();
44
45 #region Events
46 public event ChildAgentUpdateReceived OnChildAgentUpdate;
47
48 #endregion /* Events */
49
50 #region IRegionModule
51
52 public void Initialise(Scene scene, IConfigSource config)
53 {
54 if (m_sceneList.Count == 0)
55 {
56 IConfig startupConfig = config.Configs["Communications"];
57
58 if ((startupConfig != null) && (startupConfig.GetString("InterregionComms", "RESTComms") == "LocalComms"))
59 {
60 m_log.Debug("[LOCAL COMMS]: Enabling InterregionComms LocalComms module");
61 m_enabled = true;
62 }
63 }
64
65 if (!m_enabled)
66 return;
67
68 Init(scene);
69 }
70
71 public void PostInitialise()
72 {
73 }
74
75 public void Close()
76 {
77 }
78
79 public string Name
80 {
81 get { return "LocalInterregionCommsModule"; }
82 }
83
84 public bool IsSharedModule
85 {
86 get { return true; }
87 }
88 /// <summary>
89 /// Can be called from other modules.
90 /// </summary>
91 /// <param name="scene"></param>
92 public void Init(Scene scene)
93 {
94 if (!m_sceneList.Contains(scene))
95 {
96 lock (m_sceneList)
97 {
98 m_sceneList.Add(scene);
99 if (m_enabled)
100 scene.RegisterModuleInterface<IInterregionCommsOut>(this);
101 scene.RegisterModuleInterface<IInterregionCommsIn>(this);
102 }
103
104 }
105 }
106
107 #endregion /* IRegionModule */
108
109 #region IInterregionComms
110
111 /**
112 * Agent-related communications
113 */
114
115 public bool SendCreateChildAgent(ulong regionHandle, AgentCircuitData aCircuit)
116 {
117 foreach (Scene s in m_sceneList)
118 {
119 if (s.RegionInfo.RegionHandle == regionHandle)
120 {
121// m_log.DebugFormat("[LOCAL COMMS]: Found region {0} to send SendCreateChildAgent", regionHandle);
122 s.NewUserConnection(aCircuit);
123 return true;
124 }
125 }
126
127// m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for SendCreateChildAgent", regionHandle);
128 return false;
129 }
130
131 public bool SendChildAgentUpdate(ulong regionHandle, AgentData cAgentData)
132 {
133 foreach (Scene s in m_sceneList)
134 {
135 if (s.RegionInfo.RegionHandle == regionHandle)
136 {
137 //m_log.DebugFormat(
138 // "[LOCAL COMMS]: Found region {0} {1} to send ChildAgentUpdate",
139 // s.RegionInfo.RegionName, regionHandle);
140
141 s.IncomingChildAgentDataUpdate(cAgentData);
142 return true;
143 }
144 }
145
146// m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for ChildAgentUpdate", regionHandle);
147 return false;
148 }
149
150 public bool SendChildAgentUpdate(ulong regionHandle, AgentPosition cAgentData)
151 {
152 foreach (Scene s in m_sceneList)
153 {
154 if (s.RegionInfo.RegionHandle == regionHandle)
155 {
156 //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
157 s.IncomingChildAgentDataUpdate(cAgentData);
158 return true;
159 }
160 }
161 //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate");
162 return false;
163 }
164
165 public bool SendRetrieveRootAgent(ulong regionHandle, UUID id, out IAgentData agent)
166 {
167 agent = null;
168 foreach (Scene s in m_sceneList)
169 {
170 if (s.RegionInfo.RegionHandle == regionHandle)
171 {
172 //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate");
173 return s.IncomingRetrieveRootAgent(id, out agent);
174 }
175 }
176 //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate");
177 return false;
178 }
179
180 public bool SendReleaseAgent(ulong regionHandle, UUID id, string uri)
181 {
182 //uint x, y;
183 //Utils.LongToUInts(regionHandle, out x, out y);
184 //x = x / Constants.RegionSize;
185 //y = y / Constants.RegionSize;
186 //m_log.Debug("\n >>> Local SendReleaseAgent " + x + "-" + y);
187 foreach (Scene s in m_sceneList)
188 {
189 if (s.RegionInfo.RegionHandle == regionHandle)
190 {
191 //m_log.Debug("[LOCAL COMMS]: Found region to SendReleaseAgent");
192 return s.IncomingReleaseAgent(id);
193 }
194 }
195 //m_log.Debug("[LOCAL COMMS]: region not found in SendReleaseAgent");
196 return false;
197 }
198
199 public bool SendCloseAgent(ulong regionHandle, UUID id)
200 {
201 //uint x, y;
202 //Utils.LongToUInts(regionHandle, out x, out y);
203 //x = x / Constants.RegionSize;
204 //y = y / Constants.RegionSize;
205 //m_log.Debug("\n >>> Local SendCloseAgent " + x + "-" + y);
206 foreach (Scene s in m_sceneList)
207 {
208 if (s.RegionInfo.RegionHandle == regionHandle)
209 {
210 //m_log.Debug("[LOCAL COMMS]: Found region to SendCloseAgent");
211 return s.IncomingCloseAgent(id);
212 }
213 }
214 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
215 return false;
216 }
217
218 /**
219 * Object-related communications
220 */
221
222 public bool SendCreateObject(ulong regionHandle, ISceneObject sog, bool isLocalCall)
223 {
224 foreach (Scene s in m_sceneList)
225 {
226 if (s.RegionInfo.RegionHandle == regionHandle)
227 {
228 //m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject");
229 if (isLocalCall)
230 {
231 // We need to make a local copy of the object
232 ISceneObject sogClone = sog.CloneForNewScene();
233 sogClone.SetState(sog.GetStateSnapshot(),
234 s.RegionInfo.RegionID);
235 return s.IncomingCreateObject(sogClone);
236 }
237 else
238 {
239 // Use the object as it came through the wire
240 return s.IncomingCreateObject(sog);
241 }
242 }
243 }
244 return false;
245 }
246
247 public bool SendCreateObject(ulong regionHandle, UUID userID, UUID itemID)
248 {
249 foreach (Scene s in m_sceneList)
250 {
251 if (s.RegionInfo.RegionHandle == regionHandle)
252 {
253 return s.IncomingCreateObject(userID, itemID);
254 }
255 }
256 return false;
257 }
258
259
260 /**
261 * Region-related communications
262 */
263
264 public bool SendHelloNeighbour(ulong regionHandle, RegionInfo thisRegion)
265 {
266 foreach (Scene s in m_sceneList)
267 {
268 if (s.RegionInfo.RegionHandle == regionHandle)
269 {
270 //m_log.Debug("[LOCAL COMMS]: Found region to SendHelloNeighbour");
271 return s.IncomingHelloNeighbour(thisRegion);
272 }
273 }
274 return false;
275 }
276
277 #endregion /* IInterregionComms */
278
279 #region Misc
280
281 public UUID GetRegionID(ulong regionhandle)
282 {
283 foreach (Scene s in m_sceneList)
284 {
285 if (s.RegionInfo.RegionHandle == regionhandle)
286 return s.RegionInfo.RegionID;
287 }
288 // ? weird. should not happen
289 return m_sceneList[0].RegionInfo.RegionID;
290 }
291
292 public bool IsLocalRegion(ulong regionhandle)
293 {
294 foreach (Scene s in m_sceneList)
295 if (s.RegionInfo.RegionHandle == regionhandle)
296 return true;
297 return false;
298 }
299
300 #endregion
301 }
302}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectors/Interregion/RESTInterregionComms.cs b/OpenSim/Region/CoreModules/ServiceConnectors/Interregion/RESTInterregionComms.cs
new file mode 100644
index 0000000..7fafb6e
--- /dev/null
+++ b/OpenSim/Region/CoreModules/ServiceConnectors/Interregion/RESTInterregionComms.cs
@@ -0,0 +1,921 @@
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;
29using System.Collections;
30using System.IO;
31using System.Net;
32using System.Reflection;
33using System.Text;
34using log4net;
35using Nini.Config;
36using OpenMetaverse;
37using OpenMetaverse.StructuredData;
38using OpenSim.Framework;
39using OpenSim.Framework.Communications;
40using OpenSim.Framework.Communications.Clients;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Hypergrid;
44
45namespace OpenSim.Region.CoreModules.ServiceConnectors.Interregion
46{
47 public class RESTInterregionComms : IRegionModule, IInterregionCommsOut
48 {
49 private bool initialized = false;
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 protected bool m_enabled = false;
53 protected Scene m_aScene;
54 // RESTInterregionComms does not care about local regions; it delegates that to the Local module
55 protected LocalInterregionComms m_localBackend;
56
57 protected CommunicationsManager m_commsManager;
58
59 protected RegionToRegionClient m_regionClient;
60
61 protected bool m_safemode;
62 protected IPAddress m_thisIP;
63
64 #region IRegionModule
65
66 public virtual void Initialise(Scene scene, IConfigSource config)
67 {
68 if (!initialized)
69 {
70 initialized = true;
71 IConfig startupConfig = config.Configs["Communications"];
72
73 if ((startupConfig == null)
74 || (startupConfig != null)
75 && (startupConfig.GetString("InterregionComms", "RESTComms") == "RESTComms"))
76 {
77 m_log.Info("[REST COMMS]: Enabling InterregionComms RESTComms module");
78 m_enabled = true;
79 if (config.Configs["Hypergrid"] != null)
80 m_safemode = config.Configs["Hypergrid"].GetBoolean("safemode", false);
81
82 InitOnce(scene);
83 }
84 }
85
86 if (!m_enabled)
87 return;
88
89 InitEach(scene);
90
91 }
92
93 public virtual void PostInitialise()
94 {
95 if (m_enabled)
96 AddHTTPHandlers();
97 }
98
99 public virtual void Close()
100 {
101 }
102
103 public virtual string Name
104 {
105 get { return "RESTInterregionCommsModule"; }
106 }
107
108 public virtual bool IsSharedModule
109 {
110 get { return true; }
111 }
112
113 protected virtual void InitEach(Scene scene)
114 {
115 m_localBackend.Init(scene);
116 scene.RegisterModuleInterface<IInterregionCommsOut>(this);
117 }
118
119 protected virtual void InitOnce(Scene scene)
120 {
121 m_localBackend = new LocalInterregionComms();
122 m_commsManager = scene.CommsManager;
123 m_aScene = scene;
124 m_regionClient = new RegionToRegionClient(m_aScene);
125 m_thisIP = Util.GetHostFromDNS(scene.RegionInfo.ExternalHostName);
126 }
127
128 protected virtual void AddHTTPHandlers()
129 {
130 m_aScene.CommsManager.HttpServer.AddHTTPHandler("/agent/", AgentHandler);
131 m_aScene.CommsManager.HttpServer.AddHTTPHandler("/object/", ObjectHandler);
132 m_aScene.CommsManager.HttpServer.AddHTTPHandler("/region/", RegionHandler);
133 }
134
135 #endregion /* IRegionModule */
136
137 #region IInterregionComms
138
139 /**
140 * Agent-related communications
141 */
142
143 public bool SendCreateChildAgent(ulong regionHandle, AgentCircuitData aCircuit)
144 {
145 // Try local first
146 if (m_localBackend.SendCreateChildAgent(regionHandle, aCircuit))
147 return true;
148
149 // else do the remote thing
150 if (!m_localBackend.IsLocalRegion(regionHandle))
151 {
152 RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle);
153 if (regInfo != null)
154 {
155 m_regionClient.SendUserInformation(regInfo, aCircuit);
156
157 return m_regionClient.DoCreateChildAgentCall(regInfo, aCircuit, "None");
158 }
159 //else
160 // m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
161 }
162 return false;
163 }
164
165 public bool SendChildAgentUpdate(ulong regionHandle, AgentData cAgentData)
166 {
167 // Try local first
168 if (m_localBackend.SendChildAgentUpdate(regionHandle, cAgentData))
169 return true;
170
171 // else do the remote thing
172 if (!m_localBackend.IsLocalRegion(regionHandle))
173 {
174 RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle);
175 if (regInfo != null)
176 {
177 return m_regionClient.DoChildAgentUpdateCall(regInfo, cAgentData);
178 }
179 //else
180 // m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
181 }
182 return false;
183
184 }
185
186 public bool SendChildAgentUpdate(ulong regionHandle, AgentPosition cAgentData)
187 {
188 // Try local first
189 if (m_localBackend.SendChildAgentUpdate(regionHandle, cAgentData))
190 return true;
191
192 // else do the remote thing
193 if (!m_localBackend.IsLocalRegion(regionHandle))
194 {
195 RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle);
196 if (regInfo != null)
197 {
198 return m_regionClient.DoChildAgentUpdateCall(regInfo, cAgentData);
199 }
200 //else
201 // m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
202 }
203 return false;
204
205 }
206
207 public bool SendRetrieveRootAgent(ulong regionHandle, UUID id, out IAgentData agent)
208 {
209 // Try local first
210 if (m_localBackend.SendRetrieveRootAgent(regionHandle, id, out agent))
211 return true;
212
213 // else do the remote thing
214 if (!m_localBackend.IsLocalRegion(regionHandle))
215 {
216 RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle);
217 if (regInfo != null)
218 {
219 return m_regionClient.DoRetrieveRootAgentCall(regInfo, id, out agent);
220 }
221 //else
222 // m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
223 }
224 return false;
225
226 }
227
228 public bool SendReleaseAgent(ulong regionHandle, UUID id, string uri)
229 {
230 // Try local first
231 if (m_localBackend.SendReleaseAgent(regionHandle, id, uri))
232 return true;
233
234 // else do the remote thing
235 return m_regionClient.DoReleaseAgentCall(regionHandle, id, uri);
236 }
237
238
239 public bool SendCloseAgent(ulong regionHandle, UUID id)
240 {
241 // Try local first
242 if (m_localBackend.SendCloseAgent(regionHandle, id))
243 return true;
244
245 // else do the remote thing
246 if (!m_localBackend.IsLocalRegion(regionHandle))
247 {
248 RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle);
249 if (regInfo != null)
250 {
251 return m_regionClient.DoCloseAgentCall(regInfo, id);
252 }
253 //else
254 // m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
255 }
256 return false;
257 }
258
259 /**
260 * Object-related communications
261 */
262
263 public bool SendCreateObject(ulong regionHandle, ISceneObject sog, bool isLocalCall)
264 {
265 // Try local first
266 if (m_localBackend.SendCreateObject(regionHandle, sog, true))
267 {
268 //m_log.Debug("[REST COMMS]: LocalBackEnd SendCreateObject succeeded");
269 return true;
270 }
271
272 // else do the remote thing
273 if (!m_localBackend.IsLocalRegion(regionHandle))
274 {
275 RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle);
276 if (regInfo != null)
277 {
278 return m_regionClient.DoCreateObjectCall(regInfo, sog, m_aScene.m_allowScriptCrossings);
279 }
280 //else
281 // m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
282 }
283 return false;
284 }
285
286 public bool SendCreateObject(ulong regionHandle, UUID userID, UUID itemID)
287 {
288 // Not Implemented
289 return false;
290 }
291
292 /**
293 * Region-related communications
294 */
295
296 public bool SendHelloNeighbour(ulong regionHandle, RegionInfo thisRegion)
297 {
298 // Try local first
299 if (m_localBackend.SendHelloNeighbour(regionHandle, thisRegion))
300 {
301 //m_log.Debug("[REST COMMS]: LocalBackEnd SendHelloNeighbour succeeded");
302 return true;
303 }
304
305 // else do the remote thing
306 RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle);
307 if ((regInfo != null) &&
308 // Don't remote-call this instance; that's a startup hickup
309 !((regInfo.ExternalHostName == thisRegion.ExternalHostName) && (regInfo.HttpPort == thisRegion.HttpPort)))
310 {
311 return m_regionClient.DoHelloNeighbourCall(regInfo, thisRegion);
312 }
313 //else
314 // m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
315 return false;
316 }
317
318 #endregion /* IInterregionComms */
319
320 #region Incoming calls from remote instances
321
322 /**
323 * Agent-related incoming calls
324 */
325
326 public Hashtable AgentHandler(Hashtable request)
327 {
328 //m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called");
329
330 m_log.Debug("---------------------------");
331 m_log.Debug(" >> uri=" + request["uri"]);
332 m_log.Debug(" >> content-type=" + request["content-type"]);
333 m_log.Debug(" >> http-method=" + request["http-method"]);
334 m_log.Debug("---------------------------\n");
335
336 Hashtable responsedata = new Hashtable();
337 responsedata["content_type"] = "text/html";
338 responsedata["keepalive"] = false;
339
340
341 UUID agentID;
342 string action;
343 ulong regionHandle;
344 if (!GetParams((string)request["uri"], out agentID, out regionHandle, out action))
345 {
346 m_log.InfoFormat("[REST COMMS]: Invalid parameters for agent message {0}", request["uri"]);
347 responsedata["int_response_code"] = 404;
348 responsedata["str_response_string"] = "false";
349
350 return responsedata;
351 }
352
353 // Next, let's parse the verb
354 string method = (string)request["http-method"];
355 if (method.Equals("PUT"))
356 {
357 DoAgentPut(request, responsedata);
358 return responsedata;
359 }
360 else if (method.Equals("POST"))
361 {
362 DoAgentPost(request, responsedata, agentID);
363 return responsedata;
364 }
365 else if (method.Equals("GET"))
366 {
367 DoAgentGet(request, responsedata, agentID, regionHandle);
368 return responsedata;
369 }
370 else if (method.Equals("DELETE"))
371 {
372 DoAgentDelete(request, responsedata, agentID, action, regionHandle);
373 return responsedata;
374 }
375 else
376 {
377 m_log.InfoFormat("[REST COMMS]: method {0} not supported in agent message", method);
378 responsedata["int_response_code"] = 404;
379 responsedata["str_response_string"] = "false";
380
381 return responsedata;
382 }
383
384 }
385
386 protected virtual void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id)
387 {
388 if (m_safemode)
389 {
390 // Authentication
391 string authority = string.Empty;
392 string authToken = string.Empty;
393 if (!GetAuthentication(request, out authority, out authToken))
394 {
395 m_log.InfoFormat("[REST COMMS]: Authentication failed for agent message {0}", request["uri"]);
396 responsedata["int_response_code"] = 403;
397 responsedata["str_response_string"] = "Forbidden";
398 return ;
399 }
400 if (!VerifyKey(id, authority, authToken))
401 {
402 m_log.InfoFormat("[REST COMMS]: Authentication failed for agent message {0}", request["uri"]);
403 responsedata["int_response_code"] = 403;
404 responsedata["str_response_string"] = "Forbidden";
405 return ;
406 }
407 m_log.DebugFormat("[REST COMMS]: Authentication succeeded for {0}", id);
408 }
409
410 OSDMap args = RegionClient.GetOSDMap((string)request["body"]);
411 if (args == null)
412 {
413 responsedata["int_response_code"] = 400;
414 responsedata["str_response_string"] = "false";
415 return;
416 }
417
418 // retrieve the regionhandle
419 ulong regionhandle = 0;
420 if (args["destination_handle"] != null)
421 UInt64.TryParse(args["destination_handle"].AsString(), out regionhandle);
422
423 AgentCircuitData aCircuit = new AgentCircuitData();
424 try
425 {
426 aCircuit.UnpackAgentCircuitData(args);
427 }
428 catch (Exception ex)
429 {
430 m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildCreate message {0}", ex.Message);
431 return;
432 }
433
434 // This is the meaning of POST agent
435 m_regionClient.AdjustUserInformation(aCircuit);
436 bool result = m_localBackend.SendCreateChildAgent(regionhandle, aCircuit);
437
438 responsedata["int_response_code"] = 200;
439 responsedata["str_response_string"] = result.ToString();
440 }
441
442 protected virtual void DoAgentPut(Hashtable request, Hashtable responsedata)
443 {
444 OSDMap args = RegionClient.GetOSDMap((string)request["body"]);
445 if (args == null)
446 {
447 responsedata["int_response_code"] = 400;
448 responsedata["str_response_string"] = "false";
449 return;
450 }
451
452 // retrieve the regionhandle
453 ulong regionhandle = 0;
454 if (args["destination_handle"] != null)
455 UInt64.TryParse(args["destination_handle"].AsString(), out regionhandle);
456
457 string messageType;
458 if (args["message_type"] != null)
459 messageType = args["message_type"].AsString();
460 else
461 {
462 m_log.Warn("[REST COMMS]: Agent Put Message Type not found. ");
463 messageType = "AgentData";
464 }
465
466 bool result = true;
467 if ("AgentData".Equals(messageType))
468 {
469 AgentData agent = new AgentData();
470 try
471 {
472 agent.Unpack(args);
473 }
474 catch (Exception ex)
475 {
476 m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildAgentUpdate message {0}", ex.Message);
477 return;
478 }
479
480 //agent.Dump();
481 // This is one of the meanings of PUT agent
482 result = m_localBackend.SendChildAgentUpdate(regionhandle, agent);
483
484 }
485 else if ("AgentPosition".Equals(messageType))
486 {
487 AgentPosition agent = new AgentPosition();
488 try
489 {
490 agent.Unpack(args);
491 }
492 catch (Exception ex)
493 {
494 m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildAgentUpdate message {0}", ex.Message);
495 return;
496 }
497 //agent.Dump();
498 // This is one of the meanings of PUT agent
499 result = m_localBackend.SendChildAgentUpdate(regionhandle, agent);
500
501 }
502
503 responsedata["int_response_code"] = 200;
504 responsedata["str_response_string"] = result.ToString();
505 }
506
507 protected virtual void DoAgentGet(Hashtable request, Hashtable responsedata, UUID id, ulong regionHandle)
508 {
509 IAgentData agent = null;
510 bool result = m_localBackend.SendRetrieveRootAgent(regionHandle, id, out agent);
511 OSDMap map = null;
512 if (result)
513 {
514 if (agent != null) // just to make sure
515 {
516 map = agent.Pack();
517 string strBuffer = "";
518 try
519 {
520 strBuffer = OSDParser.SerializeJsonString(map);
521 }
522 catch (Exception e)
523 {
524 m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of CreateObject: {0}", e.Message);
525 // ignore. buffer will be empty, caller should check.
526 }
527
528 responsedata["content_type"] = "application/json";
529 responsedata["int_response_code"] = 200;
530 responsedata["str_response_string"] = strBuffer;
531 }
532 else
533 {
534 responsedata["int_response_code"] = 500;
535 responsedata["str_response_string"] = "Internal error";
536 }
537 }
538 else
539 {
540 responsedata["int_response_code"] = 404;
541 responsedata["str_response_string"] = "Not Found";
542 }
543 }
544
545 protected virtual void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, ulong regionHandle)
546 {
547 //m_log.Debug(" >>> DoDelete action:" + action + "; regionHandle:" + regionHandle);
548
549 if (action.Equals("release"))
550 m_localBackend.SendReleaseAgent(regionHandle, id, "");
551 else
552 m_localBackend.SendCloseAgent(regionHandle, id);
553
554 responsedata["int_response_code"] = 200;
555 responsedata["str_response_string"] = "OpenSim agent " + id.ToString();
556
557 m_log.Debug("[REST COMMS]: Agent Deleted.");
558 }
559
560 /**
561 * Object-related incoming calls
562 */
563
564 public Hashtable ObjectHandler(Hashtable request)
565 {
566 m_log.Debug("[CONNECTION DEBUGGING]: ObjectHandler Called");
567
568 m_log.Debug("---------------------------");
569 m_log.Debug(" >> uri=" + request["uri"]);
570 m_log.Debug(" >> content-type=" + request["content-type"]);
571 m_log.Debug(" >> http-method=" + request["http-method"]);
572 m_log.Debug("---------------------------\n");
573
574 Hashtable responsedata = new Hashtable();
575 responsedata["content_type"] = "text/html";
576
577 UUID objectID;
578 string action;
579 ulong regionHandle;
580 if (!GetParams((string)request["uri"], out objectID, out regionHandle, out action))
581 {
582 m_log.InfoFormat("[REST COMMS]: Invalid parameters for object message {0}", request["uri"]);
583 responsedata["int_response_code"] = 404;
584 responsedata["str_response_string"] = "false";
585
586 return responsedata;
587 }
588
589 // Next, let's parse the verb
590 string method = (string)request["http-method"];
591 if (method.Equals("POST"))
592 {
593 DoObjectPost(request, responsedata, regionHandle);
594 return responsedata;
595 }
596 else if (method.Equals("PUT"))
597 {
598 DoObjectPut(request, responsedata, regionHandle);
599 return responsedata;
600 }
601 //else if (method.Equals("DELETE"))
602 //{
603 // DoObjectDelete(request, responsedata, agentID, action, regionHandle);
604 // return responsedata;
605 //}
606 else
607 {
608 m_log.InfoFormat("[REST COMMS]: method {0} not supported in object message", method);
609 responsedata["int_response_code"] = 404;
610 responsedata["str_response_string"] = "false";
611
612 return responsedata;
613 }
614
615 }
616
617 protected virtual void DoObjectPost(Hashtable request, Hashtable responsedata, ulong regionhandle)
618 {
619 OSDMap args = RegionClient.GetOSDMap((string)request["body"]);
620 if (args == null)
621 {
622 responsedata["int_response_code"] = 400;
623 responsedata["str_response_string"] = "false";
624 return;
625 }
626
627 string sogXmlStr = "", extraStr = "", stateXmlStr = "";
628 if (args["sog"] != null)
629 sogXmlStr = args["sog"].AsString();
630 if (args["extra"] != null)
631 extraStr = args["extra"].AsString();
632
633 UUID regionID = m_localBackend.GetRegionID(regionhandle);
634 SceneObjectGroup sog = null;
635 try
636 {
637 sog = new SceneObjectGroup(sogXmlStr);
638 sog.ExtraFromXmlString(extraStr);
639 }
640 catch (Exception ex)
641 {
642 m_log.InfoFormat("[REST COMMS]: exception on deserializing scene object {0}", ex.Message);
643 responsedata["int_response_code"] = 400;
644 responsedata["str_response_string"] = "false";
645 return;
646 }
647
648 if ((args["state"] != null) && m_aScene.m_allowScriptCrossings)
649 {
650 stateXmlStr = args["state"].AsString();
651 if (stateXmlStr != "")
652 {
653 try
654 {
655 sog.SetState(stateXmlStr, regionID);
656 }
657 catch (Exception ex)
658 {
659 m_log.InfoFormat("[REST COMMS]: exception on setting state for scene object {0}", ex.Message);
660
661 }
662 }
663 }
664 // This is the meaning of POST object
665 bool result = m_localBackend.SendCreateObject(regionhandle, sog, false);
666
667 responsedata["int_response_code"] = 200;
668 responsedata["str_response_string"] = result.ToString();
669 }
670
671 protected virtual void DoObjectPut(Hashtable request, Hashtable responsedata, ulong regionhandle)
672 {
673 OSDMap args = RegionClient.GetOSDMap((string)request["body"]);
674 if (args == null)
675 {
676 responsedata["int_response_code"] = 400;
677 responsedata["str_response_string"] = "false";
678 return;
679 }
680
681 UUID userID = UUID.Zero, itemID = UUID.Zero;
682 if (args["userid"] != null)
683 userID = args["userid"].AsUUID();
684 if (args["itemid"] != null)
685 itemID = args["itemid"].AsUUID();
686
687 //UUID regionID = m_localBackend.GetRegionID(regionhandle);
688
689 // This is the meaning of PUT object
690 bool result = m_localBackend.SendCreateObject(regionhandle, userID, itemID);
691
692 responsedata["int_response_code"] = 200;
693 responsedata["str_response_string"] = result.ToString();
694 }
695
696 /*
697 * Region-related incoming calls
698 *
699 */
700
701 public Hashtable RegionHandler(Hashtable request)
702 {
703 //m_log.Debug("[CONNECTION DEBUGGING]: RegionHandler Called");
704
705 //m_log.Debug("---------------------------");
706 //m_log.Debug(" >> uri=" + request["uri"]);
707 //m_log.Debug(" >> content-type=" + request["content-type"]);
708 //m_log.Debug(" >> http-method=" + request["http-method"]);
709 //m_log.Debug("---------------------------\n");
710
711 Hashtable responsedata = new Hashtable();
712 responsedata["content_type"] = "text/html";
713
714 UUID regionID;
715 string action;
716 ulong regionHandle;
717 if (!GetParams((string)request["uri"], out regionID, out regionHandle, out action))
718 {
719 m_log.InfoFormat("[REST COMMS]: Invalid parameters for object message {0}", request["uri"]);
720 responsedata["int_response_code"] = 404;
721 responsedata["str_response_string"] = "false";
722
723 return responsedata;
724 }
725
726 // Next, let's parse the verb
727 string method = (string)request["http-method"];
728 if (method.Equals("POST"))
729 {
730 DoRegionPost(request, responsedata, regionID);
731 return responsedata;
732 }
733 //else if (method.Equals("PUT"))
734 //{
735 // DoRegionPut(request, responsedata, regionID);
736 // return responsedata;
737 //}
738 //else if (method.Equals("DELETE"))
739 //{
740 // DoRegionDelete(request, responsedata, regiontID);
741 // return responsedata;
742 //}
743 else
744 {
745 m_log.InfoFormat("[REST COMMS]: method {0} not supported in region message", method);
746 responsedata["int_response_code"] = 404;
747 responsedata["str_response_string"] = "false";
748
749 return responsedata;
750 }
751
752 }
753
754 protected virtual void DoRegionPost(Hashtable request, Hashtable responsedata, UUID id)
755 {
756 OSDMap args = RegionClient.GetOSDMap((string)request["body"]);
757 if (args == null)
758 {
759 responsedata["int_response_code"] = 400;
760 responsedata["str_response_string"] = "false";
761 return;
762 }
763
764 // retrieve the regionhandle
765 ulong regionhandle = 0;
766 if (args["destination_handle"] != null)
767 UInt64.TryParse(args["destination_handle"].AsString(), out regionhandle);
768
769 RegionInfo aRegion = new RegionInfo();
770 try
771 {
772 aRegion.UnpackRegionInfoData(args);
773 }
774 catch (Exception ex)
775 {
776 m_log.InfoFormat("[REST COMMS]: exception on unpacking HelloNeighbour message {0}", ex.Message);
777 return;
778 }
779
780 // This is the meaning of POST region
781 bool result = m_localBackend.SendHelloNeighbour(regionhandle, aRegion);
782
783 responsedata["int_response_code"] = 200;
784 responsedata["str_response_string"] = result.ToString();
785 }
786
787
788 #endregion
789
790 #region Misc
791
792
793 /// <summary>
794 /// Extract the param from an uri.
795 /// </summary>
796 /// <param name="uri">Something like this: /agent/uuid/ or /agent/uuid/handle/release</param>
797 /// <param name="uri">uuid on uuid field</param>
798 /// <param name="action">optional action</param>
799 public static bool GetParams(string uri, out UUID uuid, out ulong regionHandle, out string action)
800 {
801 uuid = UUID.Zero;
802 action = "";
803 regionHandle = 0;
804
805 uri = uri.Trim(new char[] { '/' });
806 string[] parts = uri.Split('/');
807 if (parts.Length <= 1)
808 {
809 return false;
810 }
811 else
812 {
813 if (!UUID.TryParse(parts[1], out uuid))
814 return false;
815
816 if (parts.Length >= 3)
817 UInt64.TryParse(parts[2], out regionHandle);
818 if (parts.Length >= 4)
819 action = parts[3];
820
821 return true;
822 }
823 }
824
825 public static bool GetAuthentication(Hashtable request, out string authority, out string authKey)
826 {
827 authority = string.Empty;
828 authKey = string.Empty;
829
830 Uri authUri;
831 Hashtable headers = (Hashtable)request["headers"];
832
833 // Authorization keys look like this:
834 // http://orgrid.org:8002/<uuid>
835 if (headers.ContainsKey("authorization") && (string)headers["authorization"] != "None")
836 {
837 if (Uri.TryCreate((string)headers["authorization"], UriKind.Absolute, out authUri))
838 {
839 authority = authUri.Authority;
840 authKey = authUri.PathAndQuery.Trim('/');
841 m_log.DebugFormat("[REST COMMS]: Got authority {0} and key {1}", authority, authKey);
842 return true;
843 }
844 else
845 m_log.Debug("[REST COMMS]: Wrong format for Authorization header: " + (string)headers["authorization"]);
846 }
847 else
848 m_log.Debug("[REST COMMS]: Authorization header not found");
849
850 return false;
851 }
852
853 bool VerifyKey(UUID userID, string authority, string key)
854 {
855 string[] parts = authority.Split(':');
856 IPAddress ipaddr = IPAddress.None;
857 uint port = 0;
858 if (parts.Length <= 2)
859 ipaddr = Util.GetHostFromDNS(parts[0]);
860 if (parts.Length == 2)
861 UInt32.TryParse(parts[1], out port);
862
863 // local authority (standalone), local call
864 if (m_thisIP.Equals(ipaddr) && (m_aScene.RegionInfo.HttpPort == port))
865 return ((IAuthentication)m_aScene.CommsManager.UserAdminService).VerifyKey(userID, key);
866 // remote call
867 else
868 return AuthClient.VerifyKey("http://" + authority, userID, key);
869 }
870
871
872 #endregion Misc
873
874 protected class RegionToRegionClient : RegionClient
875 {
876 Scene m_aScene = null;
877
878 public RegionToRegionClient(Scene s)
879 {
880 m_aScene = s;
881 }
882
883 public override ulong GetRegionHandle(ulong handle)
884 {
885 if (m_aScene.SceneGridService is HGSceneCommunicationService)
886 return ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.FindRegionHandle(handle);
887
888 return handle;
889 }
890
891 public override bool IsHyperlink(ulong handle)
892 {
893 if (m_aScene.SceneGridService is HGSceneCommunicationService)
894 return ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.IsHyperlinkRegion(handle);
895
896 return false;
897 }
898
899 public override void SendUserInformation(RegionInfo regInfo, AgentCircuitData aCircuit)
900 {
901 try
902 {
903 if (m_aScene.SceneGridService is HGSceneCommunicationService)
904 {
905 ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.SendUserInformation(regInfo, aCircuit);
906 }
907 }
908 catch // Bad cast
909 { }
910
911 }
912
913 public override void AdjustUserInformation(AgentCircuitData aCircuit)
914 {
915 if (m_aScene.SceneGridService is HGSceneCommunicationService)
916 ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.AdjustUserInformation(aCircuit);
917 }
918 }
919
920 }
921}