aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/ServiceConnectors/Interregion/RESTInterregionComms.cs
diff options
context:
space:
mode:
authorMelanie Thielker2009-05-03 23:13:33 +0000
committerMelanie Thielker2009-05-03 23:13:33 +0000
commit0ecd965b8c208e77a5f55bf7d1dd3cd71c2cbad7 (patch)
tree0d1b6c68eac9e0340c024f4e2828bad614634d30 /OpenSim/Region/CoreModules/ServiceConnectors/Interregion/RESTInterregionComms.cs
parentThank you kindly, Thomax, for a patch that: (diff)
downloadopensim-SC_OLD-0ecd965b8c208e77a5f55bf7d1dd3cd71c2cbad7.zip
opensim-SC_OLD-0ecd965b8c208e77a5f55bf7d1dd3cd71c2cbad7.tar.gz
opensim-SC_OLD-0ecd965b8c208e77a5f55bf7d1dd3cd71c2cbad7.tar.bz2
opensim-SC_OLD-0ecd965b8c208e77a5f55bf7d1dd3cd71c2cbad7.tar.xz
Some reorganization around service connectors. No functional change
Diffstat (limited to 'OpenSim/Region/CoreModules/ServiceConnectors/Interregion/RESTInterregionComms.cs')
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectors/Interregion/RESTInterregionComms.cs921
1 files changed, 921 insertions, 0 deletions
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}