RESTInterregionComms.cs 30 KB

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