aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Capabilities
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Capabilities')
-rw-r--r--OpenSim/Capabilities/Caps.cs4
-rw-r--r--OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs299
-rw-r--r--OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescServerConnector.cs76
3 files changed, 379 insertions, 0 deletions
diff --git a/OpenSim/Capabilities/Caps.cs b/OpenSim/Capabilities/Caps.cs
index 95bb465..e188896 100644
--- a/OpenSim/Capabilities/Caps.cs
+++ b/OpenSim/Capabilities/Caps.cs
@@ -106,6 +106,10 @@ namespace OpenSim.Framework.Capabilities
106 { 106 {
107 get { return m_capsHandlers; } 107 get { return m_capsHandlers; }
108 } 108 }
109 public Dictionary<string, string> ExternalCapsHandlers
110 {
111 get { return m_externalCapsHandlers; }
112 }
109 113
110 public Caps(IHttpServer httpServer, string httpListen, uint httpPort, string capsPath, 114 public Caps(IHttpServer httpServer, string httpListen, uint httpPort, string capsPath,
111 UUID agent, string regionName) 115 UUID agent, string regionName)
diff --git a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs
new file mode 100644
index 0000000..6fd7946
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs
@@ -0,0 +1,299 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Reflection;
32using log4net;
33using Nini.Config;
34using OpenMetaverse;
35using OpenMetaverse.StructuredData;
36using OpenSim.Framework;
37using OpenSim.Framework.Capabilities;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Framework.Servers.HttpServer;
40using OpenSim.Services.Interfaces;
41using Caps = OpenSim.Framework.Capabilities.Caps;
42
43namespace OpenSim.Capabilities.Handlers
44{
45
46 public class WebFetchInvDescHandler
47 {
48 private static readonly ILog m_log =
49 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 private IInventoryService m_InventoryService;
52 private ILibraryService m_LibraryService;
53 private object m_fetchLock = new Object();
54
55 public WebFetchInvDescHandler(IInventoryService invService, ILibraryService libService)
56 {
57 m_InventoryService = invService;
58 m_LibraryService = libService;
59 }
60
61 public string FetchInventoryDescendentsRequest(string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
62 {
63 // nasty temporary hack here, the linden client falsely
64 // identifies the uuid 00000000-0000-0000-0000-000000000000
65 // as a string which breaks us
66 //
67 // correctly mark it as a uuid
68 //
69 request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");
70
71 // another hack <integer>1</integer> results in a
72 // System.ArgumentException: Object type System.Int32 cannot
73 // be converted to target type: System.Boolean
74 //
75 request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
76 request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");
77
78 Hashtable hash = new Hashtable();
79 try
80 {
81 hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
82 }
83 catch (LLSD.LLSDParseException pe)
84 {
85 m_log.Error("[AGENT INVENTORY]: Fetch error: " + pe.Message);
86 m_log.Error("Request: " + request.ToString());
87 }
88
89 ArrayList foldersrequested = (ArrayList)hash["folders"];
90
91 string response = "";
92 lock (m_fetchLock)
93 {
94 for (int i = 0; i < foldersrequested.Count; i++)
95 {
96 string inventoryitemstr = "";
97 Hashtable inventoryhash = (Hashtable)foldersrequested[i];
98
99 LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
100
101 try
102 {
103 LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
104 }
105 catch (Exception e)
106 {
107 m_log.Debug("[CAPS]: caught exception doing OSD deserialize" + e);
108 }
109 LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
110
111 inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
112 inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
113 inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
114
115 response += inventoryitemstr;
116 }
117
118
119 if (response.Length == 0)
120 {
121 // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
122 // Therefore, I'm concluding that the client only has so many threads available to do requests
123 // and when a thread stalls.. is stays stalled.
124 // Therefore we need to return something valid
125 response = "<llsd><map><key>folders</key><array /></map></llsd>";
126 }
127 else
128 {
129 response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
130 }
131
132 //m_log.DebugFormat("[CAPS]: Replying to CAPS fetch inventory request with following xml");
133 //m_log.Debug("[CAPS] "+response);
134
135 }
136 return response;
137 }
138
139 /// <summary>
140 /// Construct an LLSD reply packet to a CAPS inventory request
141 /// </summary>
142 /// <param name="invFetch"></param>
143 /// <returns></returns>
144 private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch)
145 {
146 LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
147 LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
148 contents.agent_id = invFetch.owner_id;
149 contents.owner_id = invFetch.owner_id;
150 contents.folder_id = invFetch.folder_id;
151
152 reply.folders.Array.Add(contents);
153 InventoryCollection inv = new InventoryCollection();
154 inv.Folders = new List<InventoryFolderBase>();
155 inv.Items = new List<InventoryItemBase>();
156 int version = 0;
157
158 inv = Fetch(invFetch.owner_id, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version);
159
160 if (inv.Folders != null)
161 {
162 foreach (InventoryFolderBase invFolder in inv.Folders)
163 {
164 contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
165 }
166 }
167
168 if (inv.Items != null)
169 {
170 foreach (InventoryItemBase invItem in inv.Items)
171 {
172 contents.items.Array.Add(ConvertInventoryItem(invItem));
173 }
174 }
175
176 contents.descendents = contents.items.Array.Count + contents.categories.Array.Count;
177 contents.version = version;
178
179 return reply;
180 }
181
182 public InventoryCollection Fetch(UUID agentID, UUID folderID, UUID ownerID,
183 bool fetchFolders, bool fetchItems, int sortOrder, out int version)
184 {
185 m_log.DebugFormat(
186 "[WEBFETCHINVENTORYDESCENDANTS]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
187 fetchFolders, fetchItems, folderID, agentID);
188
189 version = 0;
190 InventoryFolderImpl fold;
191 if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner)
192 if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(folderID)) != null)
193 {
194 InventoryCollection ret = new InventoryCollection();
195 ret.Folders = new List<InventoryFolderBase>();
196 ret.Items = fold.RequestListOfItems();
197
198 return ret;
199 }
200
201 InventoryCollection contents = new InventoryCollection();
202
203 if (folderID != UUID.Zero)
204 {
205 contents = m_InventoryService.GetFolderContent(agentID, folderID);
206 InventoryFolderBase containingFolder = new InventoryFolderBase();
207 containingFolder.ID = folderID;
208 containingFolder.Owner = agentID;
209 containingFolder = m_InventoryService.GetFolder(containingFolder);
210 if (containingFolder != null)
211 version = containingFolder.Version;
212 }
213 else
214 {
215 // Lost itemsm don't really need a version
216 version = 1;
217 }
218
219 return contents;
220
221 }
222 /// <summary>
223 /// Convert an internal inventory folder object into an LLSD object.
224 /// </summary>
225 /// <param name="invFolder"></param>
226 /// <returns></returns>
227 private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder)
228 {
229 LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder();
230 llsdFolder.folder_id = invFolder.ID;
231 llsdFolder.parent_id = invFolder.ParentID;
232 llsdFolder.name = invFolder.Name;
233 if (invFolder.Type < 0 || invFolder.Type >= TaskInventoryItem.Types.Length)
234 llsdFolder.type = "-1";
235 else
236 llsdFolder.type = TaskInventoryItem.Types[invFolder.Type];
237 llsdFolder.preferred_type = "-1";
238
239 return llsdFolder;
240 }
241
242 /// <summary>
243 /// Convert an internal inventory item object into an LLSD object.
244 /// </summary>
245 /// <param name="invItem"></param>
246 /// <returns></returns>
247 private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem)
248 {
249 LLSDInventoryItem llsdItem = new LLSDInventoryItem();
250 llsdItem.asset_id = invItem.AssetID;
251 llsdItem.created_at = invItem.CreationDate;
252 llsdItem.desc = invItem.Description;
253 llsdItem.flags = (int)invItem.Flags;
254 llsdItem.item_id = invItem.ID;
255 llsdItem.name = invItem.Name;
256 llsdItem.parent_id = invItem.Folder;
257 try
258 {
259 // TODO reevaluate after upgrade to libomv >= r2566. Probably should use UtilsConversions.
260 llsdItem.type = TaskInventoryItem.Types[invItem.AssetType];
261 llsdItem.inv_type = TaskInventoryItem.InvTypes[invItem.InvType];
262 }
263 catch (Exception e)
264 {
265 m_log.ErrorFormat("[CAPS]: Problem setting asset {0} inventory {1} types while converting inventory item {2}: {3}", invItem.AssetType, invItem.InvType, invItem.Name, e.Message);
266 }
267 llsdItem.permissions = new LLSDPermissions();
268 llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
269 llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
270 llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
271 llsdItem.permissions.group_id = invItem.GroupID;
272 llsdItem.permissions.group_mask = (int)invItem.GroupPermissions;
273 llsdItem.permissions.is_owner_group = invItem.GroupOwned;
274 llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions;
275 llsdItem.permissions.owner_id = invItem.Owner;
276 llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
277 llsdItem.sale_info = new LLSDSaleInfo();
278 llsdItem.sale_info.sale_price = invItem.SalePrice;
279 switch (invItem.SaleType)
280 {
281 default:
282 llsdItem.sale_info.sale_type = "not";
283 break;
284 case 1:
285 llsdItem.sale_info.sale_type = "original";
286 break;
287 case 2:
288 llsdItem.sale_info.sale_type = "copy";
289 break;
290 case 3:
291 llsdItem.sale_info.sale_type = "contents";
292 break;
293 }
294
295 return llsdItem;
296 }
297
298 }
299}
diff --git a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescServerConnector.cs b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescServerConnector.cs
new file mode 100644
index 0000000..92eeb14
--- /dev/null
+++ b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescServerConnector.cs
@@ -0,0 +1,76 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using Nini.Config;
30using OpenSim.Server.Base;
31using OpenSim.Services.Interfaces;
32using OpenSim.Framework.Servers.HttpServer;
33using OpenSim.Server.Handlers.Base;
34using OpenMetaverse;
35
36namespace OpenSim.Capabilities.Handlers
37{
38 public class WebFetchInvDescServerConnector : ServiceConnector
39 {
40 private IInventoryService m_InventoryService;
41 private ILibraryService m_LibraryService;
42 private string m_ConfigName = "CapsService";
43
44 public WebFetchInvDescServerConnector(IConfigSource config, IHttpServer server, string configName) :
45 base(config, server, configName)
46 {
47 if (configName != String.Empty)
48 m_ConfigName = configName;
49
50 IConfig serverConfig = config.Configs[m_ConfigName];
51 if (serverConfig == null)
52 throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
53
54 string invService = serverConfig.GetString("InventoryService", String.Empty);
55
56 if (invService == String.Empty)
57 throw new Exception("No InventoryService in config file");
58
59 Object[] args = new Object[] { config };
60 m_InventoryService =
61 ServerUtils.LoadPlugin<IInventoryService>(invService, args);
62
63 if (m_InventoryService == null)
64 throw new Exception(String.Format("Failed to load InventoryService from {0}; config is {1}", invService, m_ConfigName));
65
66 string libService = serverConfig.GetString("LibraryService", String.Empty);
67 m_LibraryService =
68 ServerUtils.LoadPlugin<ILibraryService>(libService, args);
69
70 WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
71 IRequestHandler reqHandler = new RestStreamHandler("POST", "/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/, webFetchHandler.FetchInventoryDescendentsRequest);
72 server.AddStreamHandler(reqHandler);
73 }
74
75 }
76}