From c1beb85315aad09197ca7ffaa8ec194346af82cb Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Thu, 20 Mar 2008 20:04:45 +0000 Subject: * First draft resolution of mantis 777, 734, 389 - scripts do not save in non-home regions * Should work in multi-region standalone and grid modes * This should also solve other non-home region caps issues (map requests, RC client inventory requests, etc) * We now pass CAPS information on to the destination region on region crossing, and set up a CAPS object when an agent becomes a master * Current limitation is that this will only work if your http_listener_port is 9000 * This is a very early code cut (lots of bad practice, hard coding and inefficiency). However, I wanted to get this out there for feedback and my own sanity. Next few patches will clean up the mess. --- .../Framework/Communications/Capabilities/Caps.cs | 11 ++- OpenSim/Framework/IScene.cs | 2 + OpenSim/Framework/Servers/BaseHttpServer.cs | 19 +++- OpenSim/Framework/Util.cs | 22 ----- OpenSim/Region/ClientStack/ClientView.cs | 2 +- OpenSim/Region/Environment/Scenes/Scene.cs | 100 +++++++++++---------- OpenSim/Region/Environment/Scenes/SceneBase.cs | 15 ++++ .../Scenes/SceneCommunicationService.cs | 8 +- OpenSim/Region/Environment/Scenes/ScenePresence.cs | 11 ++- 9 files changed, 114 insertions(+), 76 deletions(-) diff --git a/OpenSim/Framework/Communications/Capabilities/Caps.cs b/OpenSim/Framework/Communications/Capabilities/Caps.cs index 878b0cc..fad4741 100644 --- a/OpenSim/Framework/Communications/Capabilities/Caps.cs +++ b/OpenSim/Framework/Communications/Capabilities/Caps.cs @@ -62,7 +62,12 @@ namespace OpenSim.Region.Capabilities private string m_httpListenerHostName; private uint m_httpListenPort; - private string m_capsObjectPath = "00001-"; + /// + /// This is the uuid portion of every CAPS path. It is used to make capability urls private to the requester. + /// + private string m_capsObjectPath; + public string CapsObjectPath { get { return m_capsObjectPath; } } + private string m_requestPath = "0000/"; private string m_mapLayerPath = "0001/"; private string m_newInventory = "0002/"; @@ -109,9 +114,12 @@ namespace OpenSim.Region.Capabilities try { + m_httpListener.RemoveStreamHandler("POST", capsBase + m_mapLayerPath); m_httpListener.AddStreamHandler( new LLSDStreamhandler("POST", capsBase + m_mapLayerPath, GetMapLayer)); + + m_httpListener.RemoveStreamHandler("POST", capsBase + m_newInventory); m_httpListener.AddStreamHandler( new LLSDStreamhandler("POST", capsBase + m_newInventory, @@ -142,6 +150,7 @@ namespace OpenSim.Region.Capabilities private void AddLegacyCapsHandler(BaseHttpServer httpListener, string path, RestMethod restMethod) { string capsBase = "/CAPS/" + m_capsObjectPath; + httpListener.RemoveStreamHandler("POST", capsBase + path); httpListener.AddStreamHandler(new RestStreamHandler("POST", capsBase + path, restMethod)); } diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs index 869ca60..cdf6257 100644 --- a/OpenSim/Framework/IScene.cs +++ b/OpenSim/Framework/IScene.cs @@ -63,5 +63,7 @@ namespace OpenSim.Framework RegionStatus Region_Status { get; set; } ClientManager ClientManager { get; } + + string GetCapsPath(LLUUID agentId); } } diff --git a/OpenSim/Framework/Servers/BaseHttpServer.cs b/OpenSim/Framework/Servers/BaseHttpServer.cs index 0fb8314..0f6d79b 100644 --- a/OpenSim/Framework/Servers/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/BaseHttpServer.cs @@ -70,13 +70,22 @@ namespace OpenSim.Framework.Servers m_port = port; } + /// + /// Add a stream handler to the http server. If the handler already exists, then nothing happens. + /// + /// public void AddStreamHandler(IRequestHandler handler) { string httpMethod = handler.HttpMethod; string path = handler.Path; string handlerKey = GetHandlerKey(httpMethod, path); - m_streamHandlers.Add(handlerKey, handler); + + if (!m_streamHandlers.ContainsKey(handlerKey)) + { + //m_log.DebugFormat("[BASE HTTP SERVER]: Adding handler key {0}", handlerKey); + m_streamHandlers.Add(handlerKey, handler); + } } private static string GetHandlerKey(string httpMethod, string path) @@ -289,7 +298,7 @@ namespace OpenSim.Framework.Servers } else { - System.Console.WriteLine("Handler not found for http request " + request.RawUrl); + m_log.ErrorFormat("[BASE HTTP SERVER] Handler not found for http request {0}", request.RawUrl); responseString = "Error"; } } @@ -589,7 +598,11 @@ namespace OpenSim.Framework.Servers public void RemoveStreamHandler(string httpMethod, string path) { - m_streamHandlers.Remove(GetHandlerKey(httpMethod, path)); + string handlerKey = GetHandlerKey(httpMethod, path); + + //m_log.DebugFormat("[BASE HTTP SERVER]: Removing handler key {0}", handlerKey); + + m_streamHandlers.Remove(handlerKey); } public void RemoveHTTPHandler(string httpMethod, string path) diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index e16d15e..6c95c88 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -45,7 +45,6 @@ namespace OpenSim.Framework private static Random randomClass = new Random(); private static uint nextXferID = 5000; private static object XferLock = new object(); - private static Dictionary capsURLS = new Dictionary(); // Get a list of invalid path characters (OS dependent) private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]"; @@ -422,27 +421,6 @@ namespace OpenSim.Framework return "."; } - public static string GetCapsURL(LLUUID userID) - { - if (capsURLS.ContainsKey(userID)) - { - return capsURLS[userID]; - } - return String.Empty; - } - - public static void SetCapsURL(LLUUID userID, string url) - { - if (capsURLS.ContainsKey(userID)) - { - capsURLS[userID] = url; - } - else - { - capsURLS.Add(userID, url); - } - } - // Nini (config) related Methods public static IConfigSource ConvertDataRowToXMLConfig(DataRow row, string fileName) { diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 3a763c8..f1ecc8a 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -984,7 +984,7 @@ namespace OpenSim.Region.ClientStack agentData.child = false; agentData.firstname = m_firstName; agentData.lastname = m_lastName; - agentData.CapsPath = String.Empty; + agentData.CapsPath = m_scene.GetCapsPath(m_agentId); return agentData; } diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index e036a3a..7948a6f 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -1649,53 +1649,11 @@ namespace OpenSim.Region.Environment.Scenes { if (regionHandle == m_regInfo.RegionHandle) { - if (agent.CapsPath != String.Empty) - { - m_log.DebugFormat( - "[CONNECTION DEBUGGING]: Setting up CAPS handler for avatar {0} at {1} in {2}", - agent.AgentID, agent.CapsPath, RegionInfo.RegionName); + capsPaths[agent.AgentID] = agent.CapsPath; - Caps cap = - new Caps(AssetCache, m_httpListener, m_regInfo.ExternalHostName, m_httpListener.Port, - agent.CapsPath, agent.AgentID, m_dumpAssetsToFile); - - Util.SetCapsURL(agent.AgentID, - "http://" + m_regInfo.ExternalHostName + ":" + m_httpListener.Port.ToString() + - "/CAPS/" + agent.CapsPath + "0000/"); - cap.RegisterHandlers(); - if (agent.child) - { - - } - cap.AddNewInventoryItem = AddInventoryItem; - cap.ItemUpdatedCall = CapsUpdateInventoryItemAsset; - cap.TaskScriptUpdatedCall = CapsUpdateTaskInventoryScriptAsset; - cap.CAPSFetchInventoryDescendents = CommsManager.UserProfileCacheService.HandleFetchInventoryDescendentsCAPS; - - if (m_capsHandlers.ContainsKey(agent.AgentID)) - { - m_log.DebugFormat( - "[CONNECTION DEBUGGING]: Caps path already in use for avatar {0} in region {1}", - agent.AgentID, RegionInfo.RegionName); - - try - { - m_capsHandlers[agent.AgentID] = cap; - } - catch (KeyNotFoundException) - { - m_log.DebugFormat( - "[CONNECTION DEBUGGING]: Caught exception adding handler for avatar {0} at {1}", - agent.AgentID, RegionInfo.RegionName); - - // Fix for a potential race condition. - m_capsHandlers.Add(agent.AgentID, cap); - } - } - else - { - m_capsHandlers.Add(agent.AgentID, cap); - } + if (!agent.child) + { + AddCapsHandler(agent.AgentID); } else { @@ -1716,6 +1674,56 @@ namespace OpenSim.Region.Environment.Scenes "[CONNECTION DEBUGGING]: Skipping this region for welcoming avatar {0} [{1}] at {2}", agent.AgentID, regionHandle, RegionInfo.RegionName); } + } + + /// + /// Add a caps handler for the given agent. + /// + /// + /// + public void AddCapsHandler(LLUUID agentId) + { + String capsObjectPath = GetCapsPath(agentId); + + m_log.DebugFormat( + "[CONNECTION DEBUGGING]: Setting up CAPS handler for avatar {0} at {1} in {2}", + agentId, capsObjectPath, RegionInfo.RegionName); + + Caps cap = + new Caps(AssetCache, m_httpListener, m_regInfo.ExternalHostName, m_httpListener.Port, + capsObjectPath, agentId, m_dumpAssetsToFile); + + cap.RegisterHandlers(); + + cap.AddNewInventoryItem = AddInventoryItem; + cap.ItemUpdatedCall = CapsUpdateInventoryItemAsset; + cap.TaskScriptUpdatedCall = CapsUpdateTaskInventoryScriptAsset; + cap.CAPSFetchInventoryDescendents = CommsManager.UserProfileCacheService.HandleFetchInventoryDescendentsCAPS; + + if (m_capsHandlers.ContainsKey(agentId)) + { + m_log.DebugFormat( + "[CONNECTION DEBUGGING]: Caps path already in use for avatar {0} in region {1}", + agentId, RegionInfo.RegionName); + + try + { + m_capsHandlers[agentId] = cap; + } + catch (KeyNotFoundException) + { + m_log.DebugFormat( + "[CONNECTION DEBUGGING]: Caught exception adding handler for avatar {0} at {1}", + agentId, RegionInfo.RegionName); + + // Fix for a potential race condition. + m_capsHandlers.Add(agentId, cap); + } + } + else + { + m_capsHandlers.Add(agentId, cap); + } } /// diff --git a/OpenSim/Region/Environment/Scenes/SceneBase.cs b/OpenSim/Region/Environment/Scenes/SceneBase.cs index 2cc5c4f..4002aaf 100644 --- a/OpenSim/Region/Environment/Scenes/SceneBase.cs +++ b/OpenSim/Region/Environment/Scenes/SceneBase.cs @@ -26,6 +26,7 @@ */ using System; +using System.Collections.Generic; using libsecondlife; using OpenSim.Framework; using OpenSim.Framework.Communications.Cache; @@ -196,5 +197,19 @@ namespace OpenSim.Region.Environment.Scenes } #endregion + + /// + /// XXX These two methods are very temporary + /// + protected Dictionary capsPaths = new Dictionary(); + public string GetCapsPath(LLUUID agentId) + { + if (capsPaths.ContainsKey(agentId)) + { + return capsPaths[agentId]; + } + + return null; + } } } diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs index e51c58d..d9c34e4 100644 --- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs @@ -483,7 +483,7 @@ namespace OpenSim.Region.Environment.Scenes } /// - /// + /// Try to teleport an agent to a new region. /// /// /// @@ -530,7 +530,11 @@ namespace OpenSim.Region.Environment.Scenes m_commsProvider.InterRegion.ExpectAvatarCrossing(regionHandle, avatar.ControllingClient.AgentId, position, false); AgentCircuitData circuitdata = avatar.ControllingClient.RequestClientInfo(); - string capsPath = Util.GetCapsURL(avatar.ControllingClient.AgentId); + + // TODO Should construct this behind a method + string capsPath = + "http://" + reg.ExternalHostName + ":" + 9000 + "/CAPS/" + circuitdata.CapsPath + "0000/"; + avatar.ControllingClient.SendRegionTeleport(regionHandle, 13, reg.ExternalEndPoint, 4, (1 << 4), capsPath); avatar.MakeChildAgent(); diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index 050bf95..67a4b97 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -545,6 +545,7 @@ namespace OpenSim.Region.Environment.Scenes m_scene.SwapRootAgentCount(false); m_scene.CommsManager.UserProfileCacheService.UpdateUserInventory(m_uuid); + m_scene.AddCapsHandler(m_uuid); //if (!m_gotAllObjectsInScene) //{ m_scene.SendAllSceneObjectsToClient(this); @@ -1616,7 +1617,15 @@ namespace OpenSim.Region.Environment.Scenes if (res) { AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); - string capsPath = Util.GetCapsURL(m_controllingClient.AgentId); + + // TODO Should construct this behind a method + string capsPath = + "http://" + neighbourRegion.ExternalHostName + ":" + 9000 + + "/CAPS/" + circuitdata.CapsPath + "0000/"; + + m_log.DebugFormat( + "[CONNECTION DEBUGGING]: Sending new CAPS seed url {0} to avatar {1}", capsPath, m_uuid); + m_controllingClient.CrossRegion(neighbourHandle, newpos, vel, neighbourRegion.ExternalEndPoint, capsPath); MakeChildAgent(); -- cgit v1.1