RESTInterregionComms.cs 29 KB

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