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