RESTInterregionComms.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823
  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 OpenSimulator 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. using System;
  28. using System.Collections;
  29. using System.IO;
  30. using System.Net;
  31. using System.Reflection;
  32. using System.Text;
  33. using log4net;
  34. using Nini.Config;
  35. using OpenMetaverse;
  36. using OpenMetaverse.StructuredData;
  37. using OpenSim.Framework;
  38. using OpenSim.Framework.Communications;
  39. using OpenSim.Framework.Communications.Clients;
  40. using OpenSim.Region.Framework.Interfaces;
  41. using OpenSim.Region.Framework.Scenes;
  42. using OpenSim.Region.Framework.Scenes.Hypergrid;
  43. using OpenSim.Region.Framework.Scenes.Serialization;
  44. namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion
  45. {
  46. public class RESTInterregionComms : ISharedRegionModule, IInterregionCommsOut
  47. {
  48. private bool initialized = false;
  49. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  50. protected bool m_enabled = false;
  51. protected Scene m_aScene;
  52. // RESTInterregionComms does not care about local regions; it delegates that to the Local module
  53. protected LocalInterregionComms m_localBackend;
  54. protected CommunicationsManager m_commsManager;
  55. protected RegionToRegionClient m_regionClient;
  56. protected bool m_safemode;
  57. protected IPAddress m_thisIP;
  58. #region IRegionModule
  59. public virtual void Initialise(IConfigSource config)
  60. {
  61. IConfig startupConfig = config.Configs["Communications"];
  62. if ((startupConfig == null) || ((startupConfig != null)
  63. && (startupConfig.GetString("InterregionComms", "RESTComms") == "RESTComms")))
  64. {
  65. m_log.Info("[REST COMMS]: Enabling InterregionComms RESTComms module");
  66. m_enabled = true;
  67. if (config.Configs["Hypergrid"] != null)
  68. m_safemode = config.Configs["Hypergrid"].GetBoolean("safemode", false);
  69. }
  70. }
  71. public virtual void PostInitialise()
  72. {
  73. }
  74. public virtual void Close()
  75. {
  76. }
  77. public void AddRegion(Scene scene)
  78. {
  79. }
  80. public void RemoveRegion(Scene scene)
  81. {
  82. if (m_enabled)
  83. {
  84. m_localBackend.RemoveScene(scene);
  85. scene.UnregisterModuleInterface<IInterregionCommsOut>(this);
  86. }
  87. }
  88. public void RegionLoaded(Scene scene)
  89. {
  90. if (m_enabled)
  91. {
  92. if (!initialized)
  93. {
  94. InitOnce(scene);
  95. initialized = true;
  96. AddHTTPHandlers();
  97. }
  98. InitEach(scene);
  99. }
  100. }
  101. public Type ReplaceableInterface
  102. {
  103. get { return null; }
  104. }
  105. public virtual string Name
  106. {
  107. get { return "RESTInterregionCommsModule"; }
  108. }
  109. protected virtual void InitEach(Scene scene)
  110. {
  111. m_localBackend.Init(scene);
  112. scene.RegisterModuleInterface<IInterregionCommsOut>(this);
  113. }
  114. protected virtual void InitOnce(Scene scene)
  115. {
  116. m_localBackend = new LocalInterregionComms();
  117. m_commsManager = scene.CommsManager;
  118. m_aScene = scene;
  119. m_regionClient = new RegionToRegionClient(m_aScene);
  120. m_thisIP = Util.GetHostFromDNS(scene.RegionInfo.ExternalHostName);
  121. }
  122. protected virtual void AddHTTPHandlers()
  123. {
  124. MainServer.Instance.AddHTTPHandler("/agent/", AgentHandler);
  125. MainServer.Instance.AddHTTPHandler("/object/", ObjectHandler);
  126. }
  127. #endregion /* IRegionModule */
  128. #region IInterregionComms
  129. /**
  130. * Agent-related communications
  131. */
  132. public bool SendCreateChildAgent(ulong regionHandle, AgentCircuitData aCircuit, out string reason)
  133. {
  134. // Try local first
  135. if (m_localBackend.SendCreateChildAgent(regionHandle, aCircuit, out reason))
  136. return true;
  137. // else do the remote thing
  138. if (!m_localBackend.IsLocalRegion(regionHandle))
  139. {
  140. RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle);
  141. if (regInfo != null)
  142. {
  143. m_regionClient.SendUserInformation(regInfo, aCircuit);
  144. return m_regionClient.DoCreateChildAgentCall(regInfo, aCircuit, "None", out reason);
  145. }
  146. //else
  147. // m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
  148. }
  149. return false;
  150. }
  151. public bool SendChildAgentUpdate(ulong regionHandle, AgentData cAgentData)
  152. {
  153. // Try local first
  154. if (m_localBackend.SendChildAgentUpdate(regionHandle, cAgentData))
  155. return true;
  156. // else do the remote thing
  157. if (!m_localBackend.IsLocalRegion(regionHandle))
  158. {
  159. RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle);
  160. if (regInfo != null)
  161. {
  162. return m_regionClient.DoChildAgentUpdateCall(regInfo, cAgentData);
  163. }
  164. //else
  165. // m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
  166. }
  167. return false;
  168. }
  169. public bool SendChildAgentUpdate(ulong regionHandle, AgentPosition cAgentData)
  170. {
  171. // Try local first
  172. if (m_localBackend.SendChildAgentUpdate(regionHandle, cAgentData))
  173. return true;
  174. // else do the remote thing
  175. if (!m_localBackend.IsLocalRegion(regionHandle))
  176. {
  177. RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle);
  178. if (regInfo != null)
  179. {
  180. return m_regionClient.DoChildAgentUpdateCall(regInfo, cAgentData);
  181. }
  182. //else
  183. // m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
  184. }
  185. return false;
  186. }
  187. public bool SendRetrieveRootAgent(ulong regionHandle, UUID id, out IAgentData agent)
  188. {
  189. // Try local first
  190. if (m_localBackend.SendRetrieveRootAgent(regionHandle, id, out agent))
  191. return true;
  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.DoRetrieveRootAgentCall(regInfo, id, out agent);
  199. }
  200. //else
  201. // m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
  202. }
  203. return false;
  204. }
  205. public bool SendReleaseAgent(ulong regionHandle, UUID id, string uri)
  206. {
  207. // Try local first
  208. if (m_localBackend.SendReleaseAgent(regionHandle, id, uri))
  209. return true;
  210. // else do the remote thing
  211. return m_regionClient.DoReleaseAgentCall(regionHandle, id, uri);
  212. }
  213. public bool SendCloseAgent(ulong regionHandle, UUID id)
  214. {
  215. // Try local first
  216. if (m_localBackend.SendCloseAgent(regionHandle, id))
  217. return true;
  218. // else do the remote thing
  219. if (!m_localBackend.IsLocalRegion(regionHandle))
  220. {
  221. RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle);
  222. if (regInfo != null)
  223. {
  224. return m_regionClient.DoCloseAgentCall(regInfo, id);
  225. }
  226. //else
  227. // m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
  228. }
  229. return false;
  230. }
  231. /**
  232. * Object-related communications
  233. */
  234. public bool SendCreateObject(ulong regionHandle, SceneObjectGroup sog, bool isLocalCall)
  235. {
  236. // Try local first
  237. if (m_localBackend.SendCreateObject(regionHandle, sog, true))
  238. {
  239. //m_log.Debug("[REST COMMS]: LocalBackEnd SendCreateObject succeeded");
  240. return true;
  241. }
  242. // else do the remote thing
  243. if (!m_localBackend.IsLocalRegion(regionHandle))
  244. {
  245. RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle);
  246. if (regInfo != null)
  247. {
  248. return m_regionClient.DoCreateObjectCall(
  249. regInfo, sog, SceneObjectSerializer.ToXml2Format(sog), m_aScene.m_allowScriptCrossings);
  250. }
  251. //else
  252. // m_log.Warn("[REST COMMS]: Region not found " + regionHandle);
  253. }
  254. return false;
  255. }
  256. public bool SendCreateObject(ulong regionHandle, UUID userID, UUID itemID)
  257. {
  258. // Not Implemented
  259. return false;
  260. }
  261. #endregion /* IInterregionComms */
  262. #region Incoming calls from remote instances
  263. /**
  264. * Agent-related incoming calls
  265. */
  266. public Hashtable AgentHandler(Hashtable request)
  267. {
  268. //m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called");
  269. m_log.Debug("---------------------------");
  270. m_log.Debug(" >> uri=" + request["uri"]);
  271. m_log.Debug(" >> content-type=" + request["content-type"]);
  272. m_log.Debug(" >> http-method=" + request["http-method"]);
  273. m_log.Debug("---------------------------\n");
  274. Hashtable responsedata = new Hashtable();
  275. responsedata["content_type"] = "text/html";
  276. responsedata["keepalive"] = false;
  277. UUID agentID;
  278. string action;
  279. ulong regionHandle;
  280. if (!GetParams((string)request["uri"], out agentID, out regionHandle, out action))
  281. {
  282. m_log.InfoFormat("[REST COMMS]: Invalid parameters for agent message {0}", request["uri"]);
  283. responsedata["int_response_code"] = 404;
  284. responsedata["str_response_string"] = "false";
  285. return responsedata;
  286. }
  287. // Next, let's parse the verb
  288. string method = (string)request["http-method"];
  289. if (method.Equals("PUT"))
  290. {
  291. DoAgentPut(request, responsedata);
  292. return responsedata;
  293. }
  294. else if (method.Equals("POST"))
  295. {
  296. DoAgentPost(request, responsedata, agentID);
  297. return responsedata;
  298. }
  299. else if (method.Equals("GET"))
  300. {
  301. DoAgentGet(request, responsedata, agentID, regionHandle);
  302. return responsedata;
  303. }
  304. else if (method.Equals("DELETE"))
  305. {
  306. DoAgentDelete(request, responsedata, agentID, action, regionHandle);
  307. return responsedata;
  308. }
  309. else
  310. {
  311. m_log.InfoFormat("[REST COMMS]: method {0} not supported in agent message", method);
  312. responsedata["int_response_code"] = 404;
  313. responsedata["str_response_string"] = "false";
  314. return responsedata;
  315. }
  316. }
  317. protected virtual void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id)
  318. {
  319. if (m_safemode)
  320. {
  321. // Authentication
  322. string authority = string.Empty;
  323. string authToken = string.Empty;
  324. if (!GetAuthentication(request, out authority, out authToken))
  325. {
  326. m_log.InfoFormat("[REST COMMS]: Authentication failed for agent message {0}", request["uri"]);
  327. responsedata["int_response_code"] = 403;
  328. responsedata["str_response_string"] = "Forbidden";
  329. return ;
  330. }
  331. if (!VerifyKey(id, authority, authToken))
  332. {
  333. m_log.InfoFormat("[REST COMMS]: Authentication failed for agent message {0}", request["uri"]);
  334. responsedata["int_response_code"] = 403;
  335. responsedata["str_response_string"] = "Forbidden";
  336. return ;
  337. }
  338. m_log.DebugFormat("[REST COMMS]: Authentication succeeded for {0}", id);
  339. }
  340. OSDMap args = RegionClient.GetOSDMap((string)request["body"]);
  341. if (args == null)
  342. {
  343. responsedata["int_response_code"] = 400;
  344. responsedata["str_response_string"] = "false";
  345. return;
  346. }
  347. // retrieve the regionhandle
  348. ulong regionhandle = 0;
  349. if (args["destination_handle"] != null)
  350. UInt64.TryParse(args["destination_handle"].AsString(), out regionhandle);
  351. AgentCircuitData aCircuit = new AgentCircuitData();
  352. try
  353. {
  354. aCircuit.UnpackAgentCircuitData(args);
  355. }
  356. catch (Exception ex)
  357. {
  358. m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildCreate message {0}", ex.Message);
  359. return;
  360. }
  361. OSDMap resp = new OSDMap(2);
  362. string reason = String.Empty;
  363. // This is the meaning of POST agent
  364. m_regionClient.AdjustUserInformation(aCircuit);
  365. bool result = m_localBackend.SendCreateChildAgent(regionhandle, aCircuit, out reason);
  366. resp["reason"] = OSD.FromString(reason);
  367. resp["success"] = OSD.FromBoolean(result);
  368. // TODO: add reason if not String.Empty?
  369. responsedata["int_response_code"] = 200;
  370. responsedata["str_response_string"] = OSDParser.SerializeJsonString(resp);
  371. }
  372. protected virtual void DoAgentPut(Hashtable request, Hashtable responsedata)
  373. {
  374. OSDMap args = RegionClient.GetOSDMap((string)request["body"]);
  375. if (args == null)
  376. {
  377. responsedata["int_response_code"] = 400;
  378. responsedata["str_response_string"] = "false";
  379. return;
  380. }
  381. // retrieve the regionhandle
  382. ulong regionhandle = 0;
  383. if (args["destination_handle"] != null)
  384. UInt64.TryParse(args["destination_handle"].AsString(), out regionhandle);
  385. string messageType;
  386. if (args["message_type"] != null)
  387. messageType = args["message_type"].AsString();
  388. else
  389. {
  390. m_log.Warn("[REST COMMS]: Agent Put Message Type not found. ");
  391. messageType = "AgentData";
  392. }
  393. bool result = true;
  394. if ("AgentData".Equals(messageType))
  395. {
  396. AgentData agent = new AgentData();
  397. try
  398. {
  399. agent.Unpack(args);
  400. }
  401. catch (Exception ex)
  402. {
  403. m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildAgentUpdate message {0}", ex.Message);
  404. return;
  405. }
  406. //agent.Dump();
  407. // This is one of the meanings of PUT agent
  408. result = m_localBackend.SendChildAgentUpdate(regionhandle, agent);
  409. }
  410. else if ("AgentPosition".Equals(messageType))
  411. {
  412. AgentPosition agent = new AgentPosition();
  413. try
  414. {
  415. agent.Unpack(args);
  416. }
  417. catch (Exception ex)
  418. {
  419. m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildAgentUpdate message {0}", ex.Message);
  420. return;
  421. }
  422. //agent.Dump();
  423. // This is one of the meanings of PUT agent
  424. result = m_localBackend.SendChildAgentUpdate(regionhandle, agent);
  425. }
  426. responsedata["int_response_code"] = 200;
  427. responsedata["str_response_string"] = result.ToString();
  428. }
  429. protected virtual void DoAgentGet(Hashtable request, Hashtable responsedata, UUID id, ulong regionHandle)
  430. {
  431. IAgentData agent = null;
  432. bool result = m_localBackend.SendRetrieveRootAgent(regionHandle, id, out agent);
  433. OSDMap map = null;
  434. if (result)
  435. {
  436. if (agent != null) // just to make sure
  437. {
  438. map = agent.Pack();
  439. string strBuffer = "";
  440. try
  441. {
  442. strBuffer = OSDParser.SerializeJsonString(map);
  443. }
  444. catch (Exception e)
  445. {
  446. m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of CreateObject: {0}", e.Message);
  447. // ignore. buffer will be empty, caller should check.
  448. }
  449. responsedata["content_type"] = "application/json";
  450. responsedata["int_response_code"] = 200;
  451. responsedata["str_response_string"] = strBuffer;
  452. }
  453. else
  454. {
  455. responsedata["int_response_code"] = 500;
  456. responsedata["str_response_string"] = "Internal error";
  457. }
  458. }
  459. else
  460. {
  461. responsedata["int_response_code"] = 404;
  462. responsedata["str_response_string"] = "Not Found";
  463. }
  464. }
  465. protected virtual void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, ulong regionHandle)
  466. {
  467. //m_log.Debug(" >>> DoDelete action:" + action + "; regionHandle:" + regionHandle);
  468. if (action.Equals("release"))
  469. m_localBackend.SendReleaseAgent(regionHandle, id, "");
  470. else
  471. m_localBackend.SendCloseAgent(regionHandle, id);
  472. responsedata["int_response_code"] = 200;
  473. responsedata["str_response_string"] = "OpenSim agent " + id.ToString();
  474. m_log.Debug("[REST COMMS]: Agent Deleted.");
  475. }
  476. /**
  477. * Object-related incoming calls
  478. */
  479. public Hashtable ObjectHandler(Hashtable request)
  480. {
  481. m_log.Debug("[CONNECTION DEBUGGING]: ObjectHandler Called");
  482. m_log.Debug("---------------------------");
  483. m_log.Debug(" >> uri=" + request["uri"]);
  484. m_log.Debug(" >> content-type=" + request["content-type"]);
  485. m_log.Debug(" >> http-method=" + request["http-method"]);
  486. m_log.Debug("---------------------------\n");
  487. Hashtable responsedata = new Hashtable();
  488. responsedata["content_type"] = "text/html";
  489. UUID objectID;
  490. string action;
  491. ulong regionHandle;
  492. if (!GetParams((string)request["uri"], out objectID, out regionHandle, out action))
  493. {
  494. m_log.InfoFormat("[REST COMMS]: Invalid parameters for object message {0}", request["uri"]);
  495. responsedata["int_response_code"] = 404;
  496. responsedata["str_response_string"] = "false";
  497. return responsedata;
  498. }
  499. // Next, let's parse the verb
  500. string method = (string)request["http-method"];
  501. if (method.Equals("POST"))
  502. {
  503. DoObjectPost(request, responsedata, regionHandle);
  504. return responsedata;
  505. }
  506. else if (method.Equals("PUT"))
  507. {
  508. DoObjectPut(request, responsedata, regionHandle);
  509. return responsedata;
  510. }
  511. //else if (method.Equals("DELETE"))
  512. //{
  513. // DoObjectDelete(request, responsedata, agentID, action, regionHandle);
  514. // return responsedata;
  515. //}
  516. else
  517. {
  518. m_log.InfoFormat("[REST COMMS]: method {0} not supported in object message", method);
  519. responsedata["int_response_code"] = 404;
  520. responsedata["str_response_string"] = "false";
  521. return responsedata;
  522. }
  523. }
  524. protected virtual void DoObjectPost(Hashtable request, Hashtable responsedata, ulong regionhandle)
  525. {
  526. OSDMap args = RegionClient.GetOSDMap((string)request["body"]);
  527. if (args == null)
  528. {
  529. responsedata["int_response_code"] = 400;
  530. responsedata["str_response_string"] = "false";
  531. return;
  532. }
  533. string sogXmlStr = "", extraStr = "", stateXmlStr = "";
  534. if (args["sog"] != null)
  535. sogXmlStr = args["sog"].AsString();
  536. if (args["extra"] != null)
  537. extraStr = args["extra"].AsString();
  538. UUID regionID = m_localBackend.GetRegionID(regionhandle);
  539. SceneObjectGroup sog = null;
  540. try
  541. {
  542. sog = SceneObjectSerializer.FromXml2Format(sogXmlStr);
  543. sog.ExtraFromXmlString(extraStr);
  544. }
  545. catch (Exception ex)
  546. {
  547. m_log.InfoFormat("[REST COMMS]: exception on deserializing scene object {0}", ex.Message);
  548. responsedata["int_response_code"] = 400;
  549. responsedata["str_response_string"] = "false";
  550. return;
  551. }
  552. if ((args["state"] != null) && m_aScene.m_allowScriptCrossings)
  553. {
  554. stateXmlStr = args["state"].AsString();
  555. if (stateXmlStr != "")
  556. {
  557. try
  558. {
  559. sog.SetState(stateXmlStr, regionID);
  560. }
  561. catch (Exception ex)
  562. {
  563. m_log.InfoFormat("[REST COMMS]: exception on setting state for scene object {0}", ex.Message);
  564. }
  565. }
  566. }
  567. // This is the meaning of POST object
  568. bool result = m_localBackend.SendCreateObject(regionhandle, sog, false);
  569. responsedata["int_response_code"] = 200;
  570. responsedata["str_response_string"] = result.ToString();
  571. }
  572. protected virtual void DoObjectPut(Hashtable request, Hashtable responsedata, ulong regionhandle)
  573. {
  574. OSDMap args = RegionClient.GetOSDMap((string)request["body"]);
  575. if (args == null)
  576. {
  577. responsedata["int_response_code"] = 400;
  578. responsedata["str_response_string"] = "false";
  579. return;
  580. }
  581. UUID userID = UUID.Zero, itemID = UUID.Zero;
  582. if (args["userid"] != null)
  583. userID = args["userid"].AsUUID();
  584. if (args["itemid"] != null)
  585. itemID = args["itemid"].AsUUID();
  586. //UUID regionID = m_localBackend.GetRegionID(regionhandle);
  587. // This is the meaning of PUT object
  588. bool result = m_localBackend.SendCreateObject(regionhandle, userID, itemID);
  589. responsedata["int_response_code"] = 200;
  590. responsedata["str_response_string"] = result.ToString();
  591. }
  592. #endregion
  593. #region Misc
  594. /// <summary>
  595. /// Extract the param from an uri.
  596. /// </summary>
  597. /// <param name="uri">Something like this: /agent/uuid/ or /agent/uuid/handle/release</param>
  598. /// <param name="uri">uuid on uuid field</param>
  599. /// <param name="action">optional action</param>
  600. public static bool GetParams(string uri, out UUID uuid, out ulong regionHandle, out string action)
  601. {
  602. uuid = UUID.Zero;
  603. action = "";
  604. regionHandle = 0;
  605. uri = uri.Trim(new char[] { '/' });
  606. string[] parts = uri.Split('/');
  607. if (parts.Length <= 1)
  608. {
  609. return false;
  610. }
  611. else
  612. {
  613. if (!UUID.TryParse(parts[1], out uuid))
  614. return false;
  615. if (parts.Length >= 3)
  616. UInt64.TryParse(parts[2], out regionHandle);
  617. if (parts.Length >= 4)
  618. action = parts[3];
  619. return true;
  620. }
  621. }
  622. public static bool GetAuthentication(Hashtable request, out string authority, out string authKey)
  623. {
  624. authority = string.Empty;
  625. authKey = string.Empty;
  626. Uri authUri;
  627. Hashtable headers = (Hashtable)request["headers"];
  628. // Authorization keys look like this:
  629. // http://orgrid.org:8002/<uuid>
  630. if (headers.ContainsKey("authorization") && (string)headers["authorization"] != "None")
  631. {
  632. if (Uri.TryCreate((string)headers["authorization"], UriKind.Absolute, out authUri))
  633. {
  634. authority = authUri.Authority;
  635. authKey = authUri.PathAndQuery.Trim('/');
  636. m_log.DebugFormat("[REST COMMS]: Got authority {0} and key {1}", authority, authKey);
  637. return true;
  638. }
  639. else
  640. m_log.Debug("[REST COMMS]: Wrong format for Authorization header: " + (string)headers["authorization"]);
  641. }
  642. else
  643. m_log.Debug("[REST COMMS]: Authorization header not found");
  644. return false;
  645. }
  646. bool VerifyKey(UUID userID, string authority, string key)
  647. {
  648. string[] parts = authority.Split(':');
  649. IPAddress ipaddr = IPAddress.None;
  650. uint port = 0;
  651. if (parts.Length <= 2)
  652. ipaddr = Util.GetHostFromDNS(parts[0]);
  653. if (parts.Length == 2)
  654. UInt32.TryParse(parts[1], out port);
  655. // local authority (standalone), local call
  656. if (m_thisIP.Equals(ipaddr) && (m_aScene.RegionInfo.HttpPort == port))
  657. return ((IAuthentication)m_aScene.CommsManager.UserAdminService).VerifyKey(userID, key);
  658. // remote call
  659. else
  660. return AuthClient.VerifyKey("http://" + authority, userID, key);
  661. }
  662. #endregion Misc
  663. protected class RegionToRegionClient : RegionClient
  664. {
  665. Scene m_aScene = null;
  666. public RegionToRegionClient(Scene s)
  667. {
  668. m_aScene = s;
  669. }
  670. public override ulong GetRegionHandle(ulong handle)
  671. {
  672. if (m_aScene.SceneGridService is HGSceneCommunicationService)
  673. return ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.FindRegionHandle(handle);
  674. return handle;
  675. }
  676. public override bool IsHyperlink(ulong handle)
  677. {
  678. if (m_aScene.SceneGridService is HGSceneCommunicationService)
  679. return ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.IsHyperlinkRegion(handle);
  680. return false;
  681. }
  682. public override void SendUserInformation(RegionInfo regInfo, AgentCircuitData aCircuit)
  683. {
  684. try
  685. {
  686. if (m_aScene.SceneGridService is HGSceneCommunicationService)
  687. {
  688. ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.SendUserInformation(regInfo, aCircuit);
  689. }
  690. }
  691. catch // Bad cast
  692. { }
  693. }
  694. public override void AdjustUserInformation(AgentCircuitData aCircuit)
  695. {
  696. if (m_aScene.SceneGridService is HGSceneCommunicationService)
  697. ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.AdjustUserInformation(aCircuit);
  698. }
  699. }
  700. }
  701. }