From f49ba0cbfeee5a9e3c48358551ab5ce9e2ac1bf5 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Wed, 1 Oct 2008 04:16:41 +0000 Subject: [PATCH] * Fixed a mangled Seed caps handler definition on login to region in standalone where port wasn't the http port. * Removed spurious warning message * More debug in EventQueueGet Module to figure out why we're loosing the handlers. --- OpenSim/Framework/Servers/BaseHttpServer.cs | 6 +- .../Communications/Local/LocalLoginService.cs | 23 +++- .../Modules/Framework/EventQueueGetModule.cs | 117 ++++++++++++++++-- 3 files changed, 130 insertions(+), 16 deletions(-) diff --git a/OpenSim/Framework/Servers/BaseHttpServer.cs b/OpenSim/Framework/Servers/BaseHttpServer.cs index 6090d1f3fa..b6776f29ab 100644 --- a/OpenSim/Framework/Servers/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/BaseHttpServer.cs @@ -594,8 +594,8 @@ namespace OpenSim.Framework.Servers case "application/xml": default: if (DoWeHaveALLSDHandler(request.RawUrl)) - { - m_log.ErrorFormat("[BASE HTTP SERVER]: Potentially incorrect content type on Registered LLSD CAP: Content Type:{0}", request.ContentType); + { + // Check if we have a LLSD handler here for the EXACT path. HandleLLSDRequests(request, response); return; @@ -822,7 +822,7 @@ namespace OpenSim.Framework.Servers if (TryGetLLSDHandler(request.RawUrl, out llsdhandler) && !LegacyLLSDLoginLibOMV) { // we found a registered llsd handler to service this request - llsdResponse = llsdhandler(request.RawUrl, llsdRequest, request.RemoteIPEndPoint.ToString()); + llsdResponse = llsdhandler(request.RawUrl, llsdRequest, (request.RemoteIPEndPoint == null)? "" : request.RemoteIPEndPoint.ToString()); } else { diff --git a/OpenSim/Region/Communications/Local/LocalLoginService.cs b/OpenSim/Region/Communications/Local/LocalLoginService.cs index 2d5c92e30d..70be635311 100644 --- a/OpenSim/Region/Communications/Local/LocalLoginService.cs +++ b/OpenSim/Region/Communications/Local/LocalLoginService.cs @@ -300,7 +300,28 @@ namespace OpenSim.Region.Communications.Local response.RegionY = regionInfo.RegionLocY; string capsPath = Util.GetRandomCapsPath(); - response.SeedCapability = regionInfo.ServerURI + "/CAPS/" + capsPath + "0000/"; + + // Don't use the following! It Fails for logging into any region not on the same port as the http server! + // Kept here so it doesn't happen again! + // response.SeedCapability = regionInfo.ServerURI + "/CAPS/" + capsPath + "0000/"; + + string seedcap = "http://"; + + + if (serversInfo.HttpUsesSSL) + { + seedcap = "https://" + serversInfo.HttpSSLCN + ":" + serversInfo.httpSSLPort + "/CAPS/" + capsPath + "0000/"; + + } + else + { + seedcap = "http://" + regionInfo.ExternalEndPoint.Address.ToString() + ":" + serversInfo.HttpListenerPort + "/CAPS/" + capsPath + "0000/"; + } + + + + + response.SeedCapability = seedcap; //regionInfo.ExternalEndPoint.Address.ToString() + ":" + regionInfo.HttpPort + "/CAPS/" + capsPath + "0000/"; // Notify the target of an incoming user m_log.InfoFormat( diff --git a/OpenSim/Region/Environment/Modules/Framework/EventQueueGetModule.cs b/OpenSim/Region/Environment/Modules/Framework/EventQueueGetModule.cs index c11a4dbbf3..1726ea2d37 100644 --- a/OpenSim/Region/Environment/Modules/Framework/EventQueueGetModule.cs +++ b/OpenSim/Region/Environment/Modules/Framework/EventQueueGetModule.cs @@ -68,6 +68,8 @@ namespace OpenSim.Region.Environment.Modules.Framework private Dictionary m_ids = new Dictionary(); private Dictionary queues = new Dictionary(); + private Dictionary m_QueueUUIDAvatarMapping = new Dictionary(); + private Dictionary m_AvatarQueueUUIDMapping = new Dictionary(); #region IRegionModule methods @@ -85,6 +87,10 @@ namespace OpenSim.Region.Environment.Modules.Framework { m_scene = scene; scene.RegisterModuleInterface(this); + + // Register fallback handler + // Why does EQG Fail on region crossings! + scene.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack); scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnClientClosed += ClientClosed; @@ -185,9 +191,39 @@ namespace OpenSim.Region.Environment.Modules.Framework public void OnRegisterCaps(UUID agentID, Caps caps) { m_log.DebugFormat("[EVENTQUEUE] OnRegisterCaps: agentID {0} caps {1} region {2}", agentID, caps, m_scene.RegionInfo.RegionName); - string capsBase = "/CAPS/"; + string capsBase = "/CAPS/EQG/"; + UUID EventQueueGetUUID = UUID.Zero; + + lock (m_AvatarQueueUUIDMapping) + { + // Reuse open queues. The client does! + if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) + { + m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); + EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; + } + else + { + EventQueueGetUUID = UUID.Random(); + m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); + } + } + + lock (m_QueueUUIDAvatarMapping) + { + if (!m_QueueUUIDAvatarMapping.ContainsKey(EventQueueGetUUID)) + m_QueueUUIDAvatarMapping.Add(EventQueueGetUUID, agentID); + } + + lock (m_AvatarQueueUUIDMapping) + { + if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID)) + m_AvatarQueueUUIDMapping.Add(agentID, EventQueueGetUUID); + } + + m_log.DebugFormat("[EVENTQUEUE]: CAPS URL: {0}", capsBase + EventQueueGetUUID.ToString() + "/"); caps.RegisterHandler("EventQueueGet", - new RestHTTPHandler("POST", capsBase + UUID.Random().ToString(), + new RestHTTPHandler("POST", capsBase + EventQueueGetUUID.ToString(), delegate(Hashtable m_dhttpMethod) { return ProcessQueue(m_dhttpMethod,agentID, caps); @@ -235,15 +271,7 @@ namespace OpenSim.Region.Environment.Modules.Framework return responsedata; } - if (thisID == -1) // close-request - { - responsedata["int_response_code"] = 502; - responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["str_response_string"] = ""; - return responsedata; - } - + LLSDArray array = new LLSDArray(); if (element == null) // didn't have an event in 15s { @@ -272,11 +300,76 @@ namespace OpenSim.Region.Environment.Modules.Framework responsedata["int_response_code"] = 200; responsedata["content_type"] = "application/xml"; - responsedata["keepalive"] = true; + responsedata["keepalive"] = false; responsedata["str_response_string"] = LLSDParser.SerializeXmlString(events); m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]); return responsedata; } + public LLSD EventQueueFallBack(string path, LLSD request, string endpoint) + { + // This is a fallback element to keep the client from loosing EventQueueGet + // Why does CAPS fail sometimes!? + m_log.Warn("[EVENTQUEUE]: In the Fallback handler! We lost the Queue in the rest handler!"); + string capuuid = path.Replace("/CAPS/EQG/",""); + capuuid = capuuid.Substring(0, capuuid.Length - 1); + + UUID AvatarID = UUID.Zero; + UUID capUUID = UUID.Zero; + if (UUID.TryParse(capuuid, out capUUID)) + { + + lock (m_QueueUUIDAvatarMapping) + { + if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID)) + { + AvatarID = m_QueueUUIDAvatarMapping[capUUID]; + } + } + if (AvatarID != UUID.Zero) + { + int thisID = 0; + lock (m_ids) + thisID = m_ids[AvatarID]; + + BlockingLLSDQueue queue = GetQueue(AvatarID); + LLSDArray array = new LLSDArray(); + LLSD element = queue.Dequeue(15000); // 15s timeout + if (element == null) + { + + array.Add(EventQueueHelper.KeepAliveEvent()); + } + else + { + array.Add(element); + while (queue.Count() > 0) + { + array.Add(queue.Dequeue(1)); + thisID++; + } + } + LLSDMap events = new LLSDMap(); + events.Add("events", array); + + events.Add("id", new LLSDInteger(thisID)); + + lock (m_ids) + { + m_ids[AvatarID] = thisID + 1; + } + + return events; + } + else + { + return new LLSD(); + } + } + else + { + return new LLSD(); + } + } } }