diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs index a476e91b5a..754f5a4bcf 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs @@ -62,11 +62,12 @@ namespace OpenSim.Capabilities.Handlers m_Scene = s; } - public void FetchInventoryDescendentsRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + public void FetchInventoryDescendentsRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, ExpiringKey BadRequests) { //m_log.DebugFormat("[XXX]: FetchInventoryDescendentsRequest in {0}, {1}", (m_Scene == null) ? "none" : m_Scene.Name, request); List folders = null; + List bad_folders = new List(); try { OSDArray foldersrequested = null; @@ -84,22 +85,30 @@ namespace OpenSim.Capabilities.Handlers folders = new List(foldersrequested.Count); for (int i = 0; i < foldersrequested.Count; i++) { - LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); - try + OSDMap mfolder = foldersrequested[i] as OSDMap; + UUID id = mfolder["folder_id"].AsUUID(); + if(BadRequests.ContainsKey(id)) { - OSDMap mfolder = (OSDMap)foldersrequested[i]; - llsdRequest.folder_id = mfolder["folder_id"].AsUUID(); - llsdRequest.owner_id = mfolder["owner_id"].AsUUID(); - llsdRequest.sort_order = mfolder["sort_order"].AsInteger(); - llsdRequest.fetch_folders = mfolder["fetch_folders"].AsBoolean(); - llsdRequest.fetch_items = mfolder["fetch_items"].AsBoolean(); + bad_folders.Add(id); } - catch (Exception e) + else { - m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e.Message); - continue; + LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); + try + { + llsdRequest.folder_id = id; + llsdRequest.owner_id = mfolder["owner_id"].AsUUID(); + llsdRequest.sort_order = mfolder["sort_order"].AsInteger(); + llsdRequest.fetch_folders = mfolder["fetch_folders"].AsBoolean(); + llsdRequest.fetch_items = mfolder["fetch_items"].AsBoolean(); + } + catch (Exception e) + { + m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e.Message); + continue; + } + folders.Add(llsdRequest); } - folders.Add(llsdRequest); } foldersrequested = null; tmp = null; @@ -113,12 +122,23 @@ namespace OpenSim.Capabilities.Handlers if (folders == null || folders.Count == 0) { - httpResponse.RawBuffer = EmptyResponse; - return; + if(bad_folders.Count == 0) + { + httpResponse.RawBuffer = EmptyResponse; + return; + } + StringBuilder sb = osStringBuilderCache.Acquire(); + sb.Append("foldersbad_folders"); + foreach (UUID bad in bad_folders) + { + sb.Append("folder_id"); + sb.Append(bad.ToString()); + sb.Append("errorUnknown"); + } + sb.Append(""); + httpResponse.RawBuffer = Util.UTF8NBGetbytes(osStringBuilderCache.GetStringAndRelease(sb)); } - List bad_folders = new List(); - int total_folders = 0; int total_items = 0; @@ -206,6 +226,7 @@ namespace OpenSim.Capabilities.Handlers lastresponse.Append("bad_folders"); foreach (UUID bad in bad_folders) { + BadRequests.Add(bad); lastresponse.Append("folder_id"); lastresponse.Append(bad.ToString()); lastresponse.Append("errorUnknown"); diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescServerConnector.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescServerConnector.cs index f537bfb9f4..593e60f548 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescServerConnector.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescServerConnector.cs @@ -29,9 +29,12 @@ using System; using Nini.Config; using OpenSim.Server.Base; using OpenSim.Services.Interfaces; +using OpenSim.Framework; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Server.Handlers.Base; using OpenMetaverse; +using OpenMetaverse.StructuredData; + namespace OpenSim.Capabilities.Handlers { @@ -67,9 +70,15 @@ namespace OpenSim.Capabilities.Handlers m_LibraryService = ServerUtils.LoadPlugin(libService, args); + ExpiringKey m_badRequests = new ExpiringKey(30000); + FetchInvDescHandler webFetchHandler = new FetchInvDescHandler(m_InventoryService, m_LibraryService, null); ISimpleStreamHandler reqHandler - = new SimpleStreamHandler( "/CAPS/WebFetchInvDesc/", webFetchHandler.FetchInventoryDescendentsRequest); + = new SimpleStreamHandler("/CAPS/WebFetchInvDesc/", delegate(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + { + webFetchHandler.FetchInventoryDescendentsRequest(httpRequest, httpResponse, m_badRequests); + }); + server.AddSimpleStreamHandler(reqHandler); } } diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs index 184d0b0182..7d5a59ff93 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs @@ -108,22 +108,31 @@ namespace OpenSim.Capabilities.Handlers return LLSDxmlEncode.End(lsl); } - public void FetchInventorySimpleRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap requestmap) + public void FetchInventorySimpleRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap requestmap, ExpiringKey BadRequests) { //m_log.DebugFormat("[FETCH INVENTORY HANDLER]: Received FetchInventory capability request {0}", request); + if(BadRequests == null) + { + httpResponse.StatusCode = (int)HttpStatusCode.NotFound; + return; + } + OSDArray itemsRequested = (OSDArray)requestmap["items"]; UUID[] itemIDs = new UUID[itemsRequested.Count]; int i = 0; foreach (OSDMap osdItemId in itemsRequested) { - itemIDs[i++] = osdItemId["item_id"].AsUUID(); + UUID id = osdItemId["item_id"].AsUUID(); + if(!BadRequests.ContainsKey(id)) + itemIDs[i++] = id; } InventoryItemBase[] items = null; try { + // badrequests still not filled items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs); } catch{ } diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs b/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs index b8ccf4b202..cef59b40d8 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs @@ -131,10 +131,11 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests { TestOSHttpRequest req = new TestOSHttpRequest(); TestOSHttpResponse resp = new TestOSHttpResponse(); + using(ExpiringKey bad = new ExpiringKey(5000)) // bad but this is test using (MemoryStream ms = new MemoryStream(Utils.StringToBytes(request), false)) { req.InputStream = ms; - handler.FetchInventoryDescendentsRequest(req, resp); + handler.FetchInventoryDescendentsRequest(req, resp, bad); } return Util.UTF8.GetString(resp.RawBuffer); } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs index 2c44cb18ec..b256d7ff8a 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs @@ -28,7 +28,9 @@ using Mono.Addins; using Nini.Config; using OpenMetaverse; +using OpenMetaverse.StructuredData; using OpenSim.Capabilities.Handlers; +using OpenSim.Framework; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -53,6 +55,7 @@ namespace OpenSim.Region.ClientStack.Linden private IInventoryService m_inventoryService = null; private ILibraryService m_LibraryService = null; private string m_fetchInventory2Url; + private ExpiringKey m_badRequests; #region ISharedRegionModule Members @@ -83,6 +86,8 @@ namespace OpenSim.Region.ClientStack.Linden { m_inventoryService = null; m_LibraryService = null; + m_badRequests.Dispose(); + m_badRequests = null; } } @@ -96,6 +101,9 @@ namespace OpenSim.Region.ClientStack.Linden if(m_LibraryService == null) m_LibraryService = s.LibraryService; + if(m_badRequests == null) + m_badRequests = new ExpiringKey(30000); + if (m_inventoryService != null) { s.EventManager.OnRegisterCaps += RegisterCaps; @@ -122,7 +130,11 @@ namespace OpenSim.Region.ClientStack.Linden { FetchInventory2Handler fetchHandler = new FetchInventory2Handler(m_inventoryService, agentID); caps.RegisterSimpleHandler("FetchInventory2", - new SimpleOSDMapHandler("POST", "/" + UUID.Random(), fetchHandler.FetchInventorySimpleRequest)); + new SimpleOSDMapHandler("POST", "/" + UUID.Random(), delegate (IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap map) + { + fetchHandler.FetchInventorySimpleRequest(httpRequest, httpResponse, map, m_badRequests); + } + )); } else { diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 15b65af1da..d158e179c6 100755 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -37,6 +37,7 @@ using log4net; using Nini.Config; using Mono.Addins; using OpenMetaverse; +using OpenSim.Framework; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -90,6 +91,7 @@ namespace OpenSim.Region.ClientStack.Linden private ILibraryService m_LibraryService; private bool m_Enabled; + private ExpiringKey m_badRequests; private string m_fetchInventoryDescendents2Url; // private string m_webFetchInventoryDescendentsUrl; @@ -193,6 +195,9 @@ namespace OpenSim.Region.ClientStack.Linden Scene.EventManager.OnRegisterCaps += RegisterCaps; + if(m_badRequests == null) + m_badRequests = new ExpiringKey(30000); + m_NumberScenes++; int nworkers = 2; // was 2 @@ -231,6 +236,8 @@ namespace OpenSim.Region.ClientStack.Linden Watchdog.AbortThread(t.ManagedThreadId); m_workerThreads = null; + m_badRequests.Dispose(); + m_badRequests = null; } } // m_queue.Dispose(); @@ -331,7 +338,7 @@ namespace OpenSim.Region.ClientStack.Linden } OSHttpResponse osresponse = new OSHttpResponse(requestinfo.request); - m_webFetchHandler.FetchInventoryDescendentsRequest(requestinfo.request, osresponse); + m_webFetchHandler.FetchInventoryDescendentsRequest(requestinfo.request, osresponse, m_module.m_badRequests); requestinfo.request.InputStream.Dispose(); lock (responses)