Exemple #1
0
        // FIXME: these all should probably go into the respective region
        // modules

        // multiple fetch-folder maps are allowed within the larger folders map.
        public string FetchInventoryRequest(string request, string path, string param)
        {
            m_log.Debug("[Caps]: Inventory Request in region: " + m_regionName);

            Hashtable hash = new Hashtable();

            try
            {
                hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
            }
            catch (LLSD.LLSDParseException pe)
            {
                m_log.Error("[Agent Inventory]: Fetch error: " + pe.Message);
                m_log.Error("Request: " + request.ToString());
            }

            ArrayList foldersrequested = (ArrayList)hash["folders"];

            string response = "";

            for (int i = 0; i < foldersrequested.Count; i++)
            {
                string    inventoryitemstr = "";
                Hashtable inventoryhash    = (Hashtable)foldersrequested[i];

                LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
                LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
                LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);

                inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
                inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
                inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");

                response += inventoryitemstr;
            }

            if (response.Length == 0)
            {
                // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
                // Therefore, I'm concluding that the client only has so many threads available to do requests
                // and when a thread stalls..   is stays stalled.
                // Therefore we need to return something valid
                response = "<llsd><map><key>folders</key><array /></map></llsd>";
            }
            else
            {
                response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
            }

            return(response);
        }
Exemple #2
0
        /// <summary>
        ///     Construct an LLSD reply packet to a CAPS inventory request
        /// </summary>
        /// <param name="invFetch"></param>
        /// <returns></returns>
        private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch)
        {
            LLSDInventoryDescendents    reply    = new LLSDInventoryDescendents();
            LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();

            contents.agent_id  = m_agentID;
            contents.owner_id  = invFetch.owner_id;
            contents.folder_id = invFetch.folder_id;

            reply.folders.Array.Add(contents);
            InventoryCollection inv = new InventoryCollection();

            inv.Folders = new List <InventoryFolderBase>();
            inv.Items   = new List <InventoryItemBase>();
            int version = 0;

            if (CAPSFetchInventoryDescendents != null)
            {
                inv = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version);
            }

            if (inv.Folders != null)
            {
                foreach (InventoryFolderBase invFolder in inv.Folders)
                {
                    contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
                }
            }

            if (inv.Items != null)
            {
                foreach (InventoryItemBase invItem in inv.Items)
                {
                    contents.items.Array.Add(ConvertInventoryItem(invItem));
                }
            }

            contents.descendents = contents.items.Array.Count + contents.categories.Array.Count;
            contents.version     = version;

            return(reply);
        }
Exemple #3
0
        /// <summary>
        /// Construct an LLSD reply packet to a CAPS inventory request
        /// </summary>
        /// <param name="invFetch"></param>
        /// <returns></returns>
        private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch)
        {
            LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
            LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
            contents.agent_id = m_agentID;
            contents.owner_id =  invFetch.owner_id;
            contents.folder_id = invFetch.folder_id;

            reply.folders.Array.Add(contents);
            InventoryCollection inv = new InventoryCollection();
            inv.Folders = new List<InventoryFolderBase>();
            inv.Items = new List<InventoryItemBase>();
            int version = 0;
            if (CAPSFetchInventoryDescendents != null)
            {
                inv = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version);
            }

            if (inv.Folders != null)
            {
                foreach (InventoryFolderBase invFolder in inv.Folders)
                {
                    contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
                }
            }

            if (inv.Items != null)
            {
                foreach (InventoryItemBase invItem in inv.Items)
                {
                    contents.items.Array.Add(ConvertInventoryItem(invItem));
                }
            }

            contents.descendents = contents.items.Array.Count + contents.categories.Array.Count;
            contents.version = version;

            return reply;
        }
Exemple #4
0
        public string FetchInventoryDescendentsRequest(string request, string path, string param,OSHttpRequest httpRequest, OSHttpResponse httpResponse)
        {
            // nasty temporary hack here, the linden client falsely
            // identifies the uuid 00000000-0000-0000-0000-000000000000
            // as a string which breaks us
            //
            // correctly mark it as a uuid
            //
            request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");
            
            // another hack <integer>1</integer> results in a
            // System.ArgumentException: Object type System.Int32 cannot
            // be converted to target type: System.Boolean
            //
            request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
            request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");

            Hashtable hash = new Hashtable();
            try
            {
                hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
            }
            catch (LLSD.LLSDParseException pe)
            {
                m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message);
                m_log.Error("Request: " + request.ToString());
            }

            ArrayList foldersrequested = (ArrayList)hash["folders"];

            string response = "";
            lock (m_fetchLock)
            {
                for (int i = 0; i < foldersrequested.Count; i++)
                {
                    string inventoryitemstr = "";
                    Hashtable inventoryhash = (Hashtable)foldersrequested[i];

                    LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
                    
                    try{
                        LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
                    }
                    catch(Exception e)
                    {
                        m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e);
                    }
                    LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);

                    inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
                    inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
                    inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");

                    response += inventoryitemstr;
                }
                
                
                if (response.Length == 0)
                {
                    // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
                    // Therefore, I'm concluding that the client only has so many threads available to do requests
                    // and when a thread stalls..   is stays stalled.
                    // Therefore we need to return something valid
                    response = "<llsd><map><key>folders</key><array /></map></llsd>";
                }
                else
                {
                    response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
                }

                //m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml");
                //m_log.Debug("[CAPS] "+response);

            }
            return response;
        }
Exemple #5
0
        // FIXME: these all should probably go into the respective region
        // modules

        /// <summary>
        /// Processes a fetch inventory request and sends the reply

        /// </summary>
        /// <param name="request"></param>
        /// <param name="path"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        // Request is like:
        //<llsd>
        //   <map><key>folders</key>
        //       <array>
        //            <map>
        //                <key>fetch-folders</key><boolean>1</boolean><key>fetch-items</key><boolean>1</boolean><key>folder-id</key><uuid>8e1e3a30-b9bf-11dc-95ff-0800200c9a66</uuid><key>owner-id</key><uuid>11111111-1111-0000-0000-000100bba000</uuid><key>sort-order</key><integer>1</integer>
        //            </map>
        //       </array>
        //   </map>
        //</llsd>
        //
        // multiple fetch-folder maps are allowed within the larger folders map.
        public string FetchInventoryRequest(string request, string path, string param)
        {
            // string unmodifiedRequest = request.ToString();

            //m_log.DebugFormat("[AGENT INVENTORY]: Received CAPS fetch inventory request {0}", unmodifiedRequest);
            m_log.Debug("[CAPS]: Inventory Request in region: " + m_regionName);

            Hashtable hash = new Hashtable();
            try
            {
                hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
            }
            catch (LLSD.LLSDParseException pe)
            {
                m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message);
                m_log.Error("Request: " + request.ToString());
            }

            ArrayList foldersrequested = (ArrayList)hash["folders"];

            string response = "";

            for (int i = 0; i < foldersrequested.Count; i++)
            {
                string inventoryitemstr = "";
                Hashtable inventoryhash = (Hashtable)foldersrequested[i];

                LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
                LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
                LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);

                inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
                inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
                inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");

                response += inventoryitemstr;
            }

            if (response.Length == 0)
            {
                // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
                // Therefore, I'm concluding that the client only has so many threads available to do requests
                // and when a thread stalls..   is stays stalled.
                // Therefore we need to return something valid
                response = "<llsd><map><key>folders</key><array /></map></llsd>";
            }
            else
            {
                response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
            }

            //m_log.DebugFormat("[AGENT INVENTORY]: Replying to CAPS fetch inventory request with following xml");
            //m_log.Debug(Util.GetFormattedXml(response));

            return response;
        }
Exemple #6
0
        /// <summary>
        /// Processes a fetch inventory request and sends the reply
        /// </summary>
        /// <param name="request"></param>
        /// <param name="path"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        // Request is like:
        //<llsd>
        //   <map><key>folders</key>
        //       <array>
        //            <map>
        //                <key>fetch-folders</key><boolean>1</boolean><key>fetch-items</key><boolean>1</boolean><key>folder-id</key><uuid>8e1e3a30-b9bf-11dc-95ff-0800200c9a66</uuid><key>owner-id</key><uuid>11111111-1111-0000-0000-000100bba000</uuid><key>sort-order</key><integer>1</integer>
        //            </map>
        //       </array>
        //   </map>
        //</llsd>
        //
        // multiple fetch-folder maps are allowed within the larger folders map.
        public Hashtable FetchInventoryRequest(Hashtable mDhttpMethod, UUID agentID)
        {
            m_log.DebugFormat("[AGENT INVENTORY]: Received CAPS fetch inventory request for {0}", agentID);

            Hashtable hash = new Hashtable();
            try
            {
                hash = (Hashtable)LLSD.LLSDDeserialize(OpenMetaverse.Utils.StringToBytes((string)mDhttpMethod["requestbody"]));
            }
            catch (LLSD.LLSDParseException pe)
            {
                m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message);
                //m_log.Error("Request: " + request.ToString());
            }

            ArrayList foldersrequested = (ArrayList)hash["folders"];

            string response = "";

            for (int i = 0; i < foldersrequested.Count; i++)
            {
                string inventoryitemstr = "";
                Hashtable inventoryhash = (Hashtable)foldersrequested[i];

                LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
                LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
                LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest, agentID, false);

                inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
                inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
                inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");

                response += inventoryitemstr;
            }

            if (response.Length == 0)
            {
                // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
                // Therefore, I'm concluding that the client only has so many threads available to do requests
                // and when a thread stalls..   is stays stalled.
                // Therefore we need to return something valid
                response = "<llsd><map><key>folders</key><array /></map></llsd>";
            }
            else
            {
                response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
            }

            //m_log.DebugFormat("[AGENT INVENTORY]: Replying to CAPS fetch inventory request with following xml");
            //m_log.Debug(Util.GetFormattedXml(response));
            Hashtable cancelresponsedata = new Hashtable();
            cancelresponsedata["int_response_code"] = 200; //501; //410; //404;
            cancelresponsedata["content_type"] = "text/plain";
            cancelresponsedata["keepalive"] = false;
            cancelresponsedata["str_response_string"] = response;
            return cancelresponsedata;
        }
        private void ProcessLinks(LLSDFetchInventoryDescendents freq, InventoryCollectionWithDescendents coll)
        {
            InventoryCollection contents = coll.Collection;

            if (freq.fetch_items && contents.Items != null)
            {
                List<InventoryItemBase> itemsToReturn = contents.Items;

                // descendents must only include the links, not the linked items we add
                coll.Descendents = itemsToReturn.Count;

                // Add target items for links in this folder before the links themselves.
                List<UUID> itemIDs = new List<UUID>();
                List<UUID> folderIDs = new List<UUID>();
                foreach (InventoryItemBase item in itemsToReturn)
                {
                    //m_log.DebugFormat("[XXX]:   {0} {1}", item.Name, item.AssetType);
                    if (item.AssetType == (int)AssetType.Link)
                        itemIDs.Add(item.AssetID);

//                    else if (item.AssetType == (int)AssetType.LinkFolder)
//                        folderIDs.Add(item.AssetID);
                }

                //m_log.DebugFormat("[XXX]: folder {0} has {1} links and {2} linkfolders", contents.FolderID, itemIDs.Count, folderIDs.Count);

                // Scan for folder links and insert the items they target and those links at the head of the return data
                if (folderIDs.Count > 0)
                {
                    InventoryCollection[] linkedFolders = m_InventoryService.GetMultipleFoldersContent(coll.Collection.OwnerID, folderIDs.ToArray());
                    foreach (InventoryCollection linkedFolderContents in linkedFolders)
                    {
                        if (linkedFolderContents == null)
                            continue;

                        List<InventoryItemBase> links = linkedFolderContents.Items;

                        itemsToReturn.InsertRange(0, links);

                    }
                }

                if (itemIDs.Count > 0)
                {
                    InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray());
                    if (linked == null)
                    {
                        // OMG!!! One by one!!! This is fallback code, in case the backend isn't updated
                        m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: GetMultipleItems failed. Falling back to fetching inventory items one by one.");
                        linked = new InventoryItemBase[itemIDs.Count];
                        int i = 0;
                        InventoryItemBase item = new InventoryItemBase();
                        item.Owner = freq.owner_id;
                        foreach (UUID id in itemIDs)
                        {
                            item.ID = id;
                            linked[i++] = m_InventoryService.GetItem(item);
                        }
                    }

                    //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Processing folder {0}. Existing items:", freq.folder_id);
                    //foreach (InventoryItemBase item in itemsToReturn)
                    //    m_log.DebugFormat("[XXX]: {0} {1} {2}", item.Name, item.AssetType, item.Folder);

                    if (linked != null)
                    {
                        foreach (InventoryItemBase linkedItem in linked)
                        {
                            // Take care of genuinely broken links where the target doesn't exist
                            // HACK: Also, don't follow up links that just point to other links.  In theory this is legitimate,
                            // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
                            // rather than having to keep track of every folder requested in the recursion.
                            if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
                            {
                                itemsToReturn.Insert(0, linkedItem);
                                //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Added {0} {1} {2}", linkedItem.Name, linkedItem.AssetType, linkedItem.Folder);
                            }
                        }
                    }
                }
            }

        }
        private bool BadFolder(LLSDFetchInventoryDescendents freq, InventoryCollection contents, List<UUID> bad_folders)
        {
            bool bad = false;
            if (contents == null)
            {
                bad_folders.Add(freq.folder_id);
                bad = true;
            }

            // The inventory server isn't sending FolderID in the collection...
            // Must fetch it individually
            else if (contents.FolderID == UUID.Zero)
            {
                InventoryFolderBase containingFolder = new InventoryFolderBase();
                containingFolder.ID = freq.folder_id;
                containingFolder.Owner = freq.owner_id;
                containingFolder = m_InventoryService.GetFolder(containingFolder);

                if (containingFolder != null)
                {
                    contents.FolderID = containingFolder.ID;
                    contents.OwnerID = containingFolder.Owner;
                    contents.Version = containingFolder.Version;
                }
                else
                {
                    // Was it really a request for folder Zero?
                    // This is an overkill, but Firestorm really asks for folder Zero.
                    // I'm leaving the code here for the time being, but commented.
                    if (freq.folder_id == UUID.Zero)
                    {
                        //coll.Collection.OwnerID = freq.owner_id;
                        //coll.Collection.FolderID = contents.FolderID;
                        //containingFolder = m_InventoryService.GetRootFolder(freq.owner_id);
                        //if (containingFolder != null)
                        //{
                        //    m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Request for parent of folder {0}", containingFolder.ID);
                        //    coll.Collection.Folders.Clear();
                        //    coll.Collection.Folders.Add(containingFolder);
                        //    if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null)
                        //    {
                        //        InventoryFolderBase lib = new InventoryFolderBase(m_LibraryService.LibraryRootFolder.ID, m_LibraryService.LibraryRootFolder.Owner);
                        //        lib.Name = m_LibraryService.LibraryRootFolder.Name;
                        //        lib.Type = m_LibraryService.LibraryRootFolder.Type;
                        //        lib.Version = m_LibraryService.LibraryRootFolder.Version;
                        //        coll.Collection.Folders.Add(lib);
                        //    }
                        //    coll.Collection.Items.Clear();
                        //}
                    }
                    else
                    {
                        m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Unable to fetch folder {0}", freq.folder_id);
                        bad_folders.Add(freq.folder_id);
                    }
                    bad = true;
                }
            }

            return bad;
        }
        public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
        {
            //m_log.DebugFormat("[XXX]: FetchInventoryDescendentsRequest in {0}, {1}", (m_Scene == null) ? "none" : m_Scene.Name, request);

            // nasty temporary hack here, the linden client falsely
            // identifies the uuid 00000000-0000-0000-0000-000000000000
            // as a string which breaks us
            //
            // correctly mark it as a uuid
            //
            request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");
    
            // another hack <integer>1</integer> results in a
            // System.ArgumentException: Object type System.Int32 cannot
            // be converted to target type: System.Boolean
            //
            request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
            request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");
    
            Hashtable hash = new Hashtable();
            try
            {
                hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
            }
            catch (LLSD.LLSDParseException e)
            {
                m_log.ErrorFormat("[WEB FETCH INV DESC HANDLER]: Fetch error: {0}{1}" + e.Message, e.StackTrace);
                m_log.Error("Request: " + request);
            }
    
            ArrayList foldersrequested = (ArrayList)hash["folders"];
    
            string response = "";
            string bad_folders_response = "";

            List<LLSDFetchInventoryDescendents> folders = new List<LLSDFetchInventoryDescendents>();
            for (int i = 0; i < foldersrequested.Count; i++)
            {
                Hashtable inventoryhash = (Hashtable)foldersrequested[i];

                LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();

                try
                {
                    LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
                }
                catch (Exception e)
                {
                    m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
                    continue;
                }

                // Filter duplicate folder ids that bad viewers may send
                if (folders.Find(f => f.folder_id == llsdRequest.folder_id) == null)
                    folders.Add(llsdRequest);

            }

            if (folders.Count > 0)
            {
                List<UUID> bad_folders = new List<UUID>();
                List<InventoryCollectionWithDescendents> invcollSet = Fetch(folders, bad_folders);
                //m_log.DebugFormat("[XXX]: Got {0} folders from a request of {1}", invcollSet.Count, folders.Count);

                if (invcollSet == null)
                {
                    m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Multiple folder fetch failed. Trying old protocol.");
#pragma warning disable 0612
                    return FetchInventoryDescendentsRequest(foldersrequested, httpRequest, httpResponse);
#pragma warning restore 0612
                }

                string inventoryitemstr = string.Empty;
                foreach (InventoryCollectionWithDescendents icoll in invcollSet)
                {
                    LLSDInventoryDescendents reply = ToLLSD(icoll.Collection, icoll.Descendents);

                    inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
                    inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
                    inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");

                    response += inventoryitemstr;
                }

                //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Bad folders {0}", string.Join(", ", bad_folders));
                foreach (UUID bad in bad_folders)
                    bad_folders_response += "<uuid>" + bad + "</uuid>";
            }

            if (response.Length == 0)
            {
                /* Viewers expect a bad_folders array when not available */
                if (bad_folders_response.Length != 0)
                {
                    response = "<llsd><map><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
                }
                else
                {
                    response = "<llsd><map><key>folders</key><array /></map></llsd>";
                }
            }
            else
            {
                if (bad_folders_response.Length != 0)
                {
                    response = "<llsd><map><key>folders</key><array>" + response + "</array><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
                }
                else
                {
                    response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
                }
            }

            //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request for {0} folders. Item count {1}", folders.Count, item_count);
            //m_log.Debug("[WEB FETCH INV DESC HANDLER] " + response);

            return response;

        }
        private string FetchInventoryDescendentsRequest(ArrayList foldersrequested, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
        {
            //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request for {0} folders", foldersrequested.Count);

            string response = "";
            string bad_folders_response = "";

            for (int i = 0; i < foldersrequested.Count; i++)
            {
                string inventoryitemstr = "";
                Hashtable inventoryhash = (Hashtable)foldersrequested[i];

                LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();

                try
                {
                    LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
                }
                catch (Exception e)
                {
                    m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
                }

                LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);

                if (null == reply)
                {
                    bad_folders_response += "<uuid>" + llsdRequest.folder_id.ToString() + "</uuid>";
                }
                else
                {
                    inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
                    inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
                    inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
                }

                response += inventoryitemstr;
            }

            if (response.Length == 0)
            {
                /* Viewers expect a bad_folders array when not available */
                if (bad_folders_response.Length != 0)
                {
                    response = "<llsd><map><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
                }
                else
                {
                    response = "<llsd><map><key>folders</key><array /></map></llsd>";
                }
            }
            else
            {
                if (bad_folders_response.Length != 0)
                {
                    response = "<llsd><map><key>folders</key><array>" + response + "</array><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
                }
                else
                {
                    response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
                }
            }

            //                m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request");
            //m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response);

            return response;

            //            }
        }
        /// <summary>
        /// Construct an LLSD reply packet to a CAPS inventory request
        /// </summary>
        /// <param name="invFetch"></param>
        /// <returns></returns>
        private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch)
        {
            LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
            LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
            contents.agent_id = invFetch.owner_id;
            contents.owner_id = invFetch.owner_id;
            contents.folder_id = invFetch.folder_id;

            reply.folders.Array.Add(contents);
            InventoryCollection inv = new InventoryCollection();
            inv.Folders = new List<InventoryFolderBase>();
            inv.Items = new List<InventoryItemBase>();
            int version = 0;
            int descendents = 0;

#pragma warning disable 0612
            inv = Fetch(
                    invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
                    invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version, out descendents);
#pragma warning restore 0612

            if (inv != null && inv.Folders != null)
            {
                foreach (InventoryFolderBase invFolder in inv.Folders)
                {
                    contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
                }

                descendents += inv.Folders.Count;
            }

            if (inv != null && inv.Items != null)
            {
                foreach (InventoryItemBase invItem in inv.Items)
                {
                    contents.items.Array.Add(ConvertInventoryItem(invItem));
                }
            }

            contents.descendents = descendents;
            contents.version = version;

            //m_log.DebugFormat(
            //    "[WEB FETCH INV DESC HANDLER]: Replying to request for folder {0} (fetch items {1}, fetch folders {2}) with {3} items and {4} folders for agent {5}",
            //    invFetch.folder_id,
            //    invFetch.fetch_items,
            //    invFetch.fetch_folders,
            //    contents.items.Array.Count,
            //    contents.categories.Array.Count,
            //    invFetch.owner_id);

            return reply;
        }
Exemple #12
0
        public string FetchInventoryDescendentsRequest(string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
        {
            // nasty temporary hack here, the linden client falsely
            // identifies the uuid 00000000-0000-0000-0000-000000000000
            // as a string which breaks us
            //
            // correctly mark it as a uuid
            request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");

            // another hack <integer>1</integer> results in a
            // System.ArgumentException: Object type System.Int32 cannot
            // be converted to target type: System.Boolean
            request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
            request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");

            Hashtable hash = new Hashtable();

            try
            {
                hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
            }
            catch (LLSD.LLSDParseException pe)
            {
                m_log.Error("[Agent Inventory]: Fetch error: " + pe.Message);
                m_log.Error("Request: " + request.ToString());
            }

            ArrayList foldersrequested = (ArrayList)hash["folders"];

            string response = "";

            lock (m_fetchLock)
            {
                for (int i = 0; i < foldersrequested.Count; i++)
                {
                    string    inventoryitemstr = "";
                    Hashtable inventoryhash    = (Hashtable)foldersrequested[i];

                    LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();

                    try
                    {
                        LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
                    }
                    catch (Exception e)
                    {
                        m_log.Debug("[Caps]: caught exception doing OSD deserialize" + e);
                    }

                    LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);

                    inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
                    inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
                    inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");

                    response += inventoryitemstr;
                }

                if (response.Length == 0)
                {
                    // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
                    // Therefore, I'm concluding that the client only has so many threads available to do requests
                    // and when a thread stalls..   is stays stalled.
                    // Therefore we need to return something valid
                    response = "<llsd><map><key>folders</key><array /></map></llsd>";
                }
                else
                {
                    response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
                }
            }

            return(response);
        }
Exemple #13
0
        /// <summary>
        /// Construct an LLSD reply packet to a CAPS inventory request
        /// </summary>
        /// <param name="invFetch"></param>
        /// <returns></returns>
        private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch)
        {
            LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
            LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
            contents.agent_id = m_agentID;
            contents.owner_id =  invFetch.owner_id;
            contents.folder_id = invFetch.folder_id;

            // The version number being sent back was originally 1.
            // Unfortunately, on 1.19.1.4, this means that we see a problem where on subsequent logins
            // without clearing client cache, objects in the root folder disappear until the cache is cleared,
            // at which point they reappear.
            //
            // Seeing the version to something other than 0 may be the right thing to do, but there is
            // a greater subtlety of the second life protocol that needs to be understood first.
            contents.version = 0;

            contents.descendents = 0;
            reply.folders.Array.Add(contents);
            List<InventoryItemBase> itemList = null;
            if (CAPSFetchInventoryDescendents != null)
            {
                itemList = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order);
            }

            if (itemList != null)
            {
                foreach (InventoryItemBase invItem in itemList)
                {
                    contents.items.Array.Add(ConvertInventoryItem(invItem));
                }
            }
            /* The following block is removed as it ALWAYS sends the error to the client because the RC 1.22.9 client tries to 
                find items that have become dissasociated with a paret folder and have parent of 00000000-0000-00000....
            else
            {
                IClientAPI client = GetClient(m_agentID);

                // We're going to both notify the client of inventory service failure and send back a 'no folder contents' response.
                // If we don't send back the response,
                // the client becomes unhappy (see Teravus' comment in FetchInventoryRequest())
                if (client != null)
                {
                    client.SendAgentAlertMessage(
                        "AGIN0001E: The inventory service has either failed or is not responding.  Your inventory will not function properly for the rest of this session.  Please clear your cache and relog.",
                        true);
                }
                else
                {
                    m_log.ErrorFormat(
                        "[AGENT INVENTORY]: Could not lookup controlling client for {0} in order to notify them of the inventory service failure",
                        m_agentID);
                }
            }*/

            contents.descendents = contents.items.Array.Count;
            return reply;
        }
        public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
        {
            // nasty temporary hack here, the linden client falsely
            // identifies the uuid 00000000-0000-0000-0000-000000000000
            // as a string which breaks us
            //
            // correctly mark it as a uuid
            //
            request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");
    
            // another hack <integer>1</integer> results in a
            // System.ArgumentException: Object type System.Int32 cannot
            // be converted to target type: System.Boolean
            //
            request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
            request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");
    
            Hashtable hash = new Hashtable();
            try
            {
                hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
            }
            catch (LLSD.LLSDParseException e)
            {
                m_log.ErrorFormat("[WEB FETCH INV DESC HANDLER]: Fetch error: {0}{1}" + e.Message, e.StackTrace);
                m_log.Error("Request: " + request);
                throw;
            }
    
            ArrayList foldersrequested = (ArrayList)hash["folders"];
    
            string response = "";
            string bad_folders_response = "";

            for (int i = 0; i < foldersrequested.Count; i++)
            {
                string inventoryitemstr = "";
                Hashtable inventoryhash = (Hashtable)foldersrequested[i];

                LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();

                try
                {
                    LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
                }
                catch (Exception e)
                {
                    m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
                }
                LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
                if (null == reply)
                {
                    bad_folders_response += "<uuid>" + llsdRequest.folder_id.ToString() + "</uuid>";
                }
                else
                {
                    inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
                    inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
                    inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");

                    response += inventoryitemstr;
                }
            }

            if (response.Length == 0)
            {
                /* Viewers expect a bad_folders array when not available */
                if (bad_folders_response.Length != 0)
                {
                    response = "<llsd><map><key>bad_folders</key><array>"+bad_folders_response+"</array></map></llsd>";
                }
                else
                {
                    response = "<llsd><map><key>folders</key><array /></map></llsd>";
                }
            }
            else
            {
                if (bad_folders_response.Length != 0)
                {
                    response = "<llsd><map><key>folders</key><array>" + response + "</array><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
                }
                else
                {
                    response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
                }
            }

            return response;
        }