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