aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs204
1 files changed, 152 insertions, 52 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
index 2359bd6..4908c2c 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -27,18 +27,22 @@
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic;
30using System.Reflection; 31using System.Reflection;
32using System.Threading;
31using log4net; 33using log4net;
32using Nini.Config; 34using Nini.Config;
33using Mono.Addins; 35using Mono.Addins;
34using OpenMetaverse; 36using OpenMetaverse;
35using OpenSim.Framework; 37using OpenSim.Framework;
38using OpenSim.Framework.Servers;
36using OpenSim.Framework.Servers.HttpServer; 39using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Region.Framework.Interfaces; 40using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
39using OpenSim.Services.Interfaces; 42using OpenSim.Services.Interfaces;
40using Caps = OpenSim.Framework.Capabilities.Caps; 43using Caps = OpenSim.Framework.Capabilities.Caps;
41using OpenSim.Capabilities.Handlers; 44using OpenSim.Capabilities.Handlers;
45using OpenSim.Framework.Monitoring;
42 46
43namespace OpenSim.Region.ClientStack.Linden 47namespace OpenSim.Region.ClientStack.Linden
44{ 48{
@@ -48,67 +52,65 @@ namespace OpenSim.Region.ClientStack.Linden
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 52 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
49 public class WebFetchInvDescModule : INonSharedRegionModule 53 public class WebFetchInvDescModule : INonSharedRegionModule
50 { 54 {
51// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 56
53 private Scene m_scene; 57 private Scene m_scene;
54 58
55 private IInventoryService m_InventoryService; 59 private IInventoryService m_InventoryService;
56 private ILibraryService m_LibraryService; 60 private ILibraryService m_LibraryService;
57 61
58 private bool m_Enabled; 62 private static WebFetchInvDescHandler m_webFetchHandler;
59 63
60 private string m_fetchInventoryDescendents2Url; 64 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
61 private string m_webFetchInventoryDescendentsUrl; 65 private static Thread[] m_workerThreads = null;
62 66
63 private WebFetchInvDescHandler m_webFetchHandler; 67 private static OpenMetaverse.BlockingQueue<PollServiceInventoryEventArgs> m_queue =
68 new OpenMetaverse.BlockingQueue<PollServiceInventoryEventArgs>();
64 69
65 #region ISharedRegionModule Members 70 #region ISharedRegionModule Members
66 71
67 public void Initialise(IConfigSource source) 72 public void Initialise(IConfigSource source)
68 { 73 {
69 IConfig config = source.Configs["ClientStack.LindenCaps"];
70 if (config == null)
71 return;
72
73 m_fetchInventoryDescendents2Url = config.GetString("Cap_FetchInventoryDescendents2", string.Empty);
74 m_webFetchInventoryDescendentsUrl = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty);
75
76 if (m_fetchInventoryDescendents2Url != string.Empty || m_webFetchInventoryDescendentsUrl != string.Empty)
77 {
78 m_Enabled = true;
79 }
80 } 74 }
81 75
82 public void AddRegion(Scene s) 76 public void AddRegion(Scene s)
83 { 77 {
84 if (!m_Enabled)
85 return;
86
87 m_scene = s; 78 m_scene = s;
88 } 79 }
89 80
90 public void RemoveRegion(Scene s) 81 public void RemoveRegion(Scene s)
91 { 82 {
92 if (!m_Enabled)
93 return;
94
95 m_scene.EventManager.OnRegisterCaps -= RegisterCaps; 83 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
84 m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
96 m_scene = null; 85 m_scene = null;
97 } 86 }
98 87
99 public void RegionLoaded(Scene s) 88 public void RegionLoaded(Scene s)
100 { 89 {
101 if (!m_Enabled)
102 return;
103
104 m_InventoryService = m_scene.InventoryService; 90 m_InventoryService = m_scene.InventoryService;
105 m_LibraryService = m_scene.LibraryService; 91 m_LibraryService = m_scene.LibraryService;
106 92
107 // We'll reuse the same handler for all requests. 93 // We'll reuse the same handler for all requests.
108 if (m_fetchInventoryDescendents2Url == "localhost" || m_webFetchInventoryDescendentsUrl == "localhost") 94 m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
109 m_webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
110 95
111 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 96 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
97 m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
98
99 if (m_workerThreads == null)
100 {
101 m_workerThreads = new Thread[2];
102
103 for (uint i = 0; i < 2; i++)
104 {
105 m_workerThreads[i] = Watchdog.StartThread(DoInventoryRequests,
106 String.Format("InventoryWorkerThread{0}", i),
107 ThreadPriority.Normal,
108 false,
109 true,
110 null,
111 int.MaxValue);
112 }
113 }
112 } 114 }
113 115
114 public void PostInitialise() 116 public void PostInitialise()
@@ -126,43 +128,141 @@ namespace OpenSim.Region.ClientStack.Linden
126 128
127 #endregion 129 #endregion
128 130
129 private void RegisterCaps(UUID agentID, Caps caps) 131 ~WebFetchInvDescModule()
130 { 132 {
131 if (m_webFetchInventoryDescendentsUrl != "") 133 foreach (Thread t in m_workerThreads)
132 RegisterFetchCap(agentID, caps, "WebFetchInventoryDescendents", m_webFetchInventoryDescendentsUrl); 134 t.Abort();
133
134 if (m_fetchInventoryDescendents2Url != "")
135 RegisterFetchCap(agentID, caps, "FetchInventoryDescendents2", m_fetchInventoryDescendents2Url);
136 } 135 }
137 136
138 private void RegisterFetchCap(UUID agentID, Caps caps, string capName, string url) 137 private class PollServiceInventoryEventArgs : PollServiceEventArgs
139 { 138 {
140 string capUrl; 139 private List<Hashtable> requests =
140 new List<Hashtable>();
141 private Dictionary<UUID, Hashtable> responses =
142 new Dictionary<UUID, Hashtable>();
141 143
142 if (url == "localhost") 144 public PollServiceInventoryEventArgs(UUID pId) :
145 base(null, null, null, null, pId, 30000)
143 { 146 {
144 capUrl = "/CAPS/" + UUID.Random(); 147 HasEvents = (x, y) => { return this.responses.ContainsKey(x); };
148 GetEvents = (x, y, s) =>
149 {
150 try
151 {
152 return this.responses[x];
153 }
154 finally
155 {
156 responses.Remove(x);
157 }
158 };
159
160 Request = (x, y) =>
161 {
162 y["RequestID"] = x.ToString();
163 lock (this.requests)
164 this.requests.Add(y);
165
166 m_queue.Enqueue(this);
167 };
168
169 NoEvents = (x, y) =>
170 {
171 lock (this.requests)
172 {
173 Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
174 requests.Remove(request);
175 }
176
177 Hashtable response = new Hashtable();
178
179 response["int_response_code"] = 500;
180 response["str_response_string"] = "Script timeout";
181 response["content_type"] = "text/plain";
182 response["keepalive"] = false;
183 response["reusecontext"] = false;
184
185 return response;
186 };
187 }
188
189 public void Process()
190 {
191 Hashtable request = null;
192
193 try
194 {
195 lock (this.requests)
196 {
197 request = requests[0];
198 requests.RemoveAt(0);
199 }
200 }
201 catch
202 {
203 return;
204 }
205
206 UUID requestID = new UUID(request["RequestID"].ToString());
145 207
146 IRequestHandler reqHandler 208 Hashtable response = new Hashtable();
147 = new RestStreamHandler(
148 "POST",
149 capUrl,
150 m_webFetchHandler.FetchInventoryDescendentsRequest,
151 "FetchInventoryDescendents2",
152 agentID.ToString());
153 209
154 caps.RegisterHandler(capName, reqHandler); 210 response["int_response_code"] = 200;
211 response["content_type"] = "text/plain";
212 response["keepalive"] = false;
213 response["reusecontext"] = false;
214
215 response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest(request["body"].ToString(), String.Empty, String.Empty, null, null);
216
217 responses[requestID] = response;
155 } 218 }
156 else 219 }
220
221 private void RegisterCaps(UUID agentID, Caps caps)
222 {
223 string capUrl = "/CAPS/" + UUID.Random() + "/";
224
225 // Register this as a poll service
226 // absurd large timeout to tune later to make a bit less than viewer
227 PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(agentID);
228
229 args.Type = PollServiceEventArgs.EventType.Inventory;
230 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
231
232 string hostName = m_scene.RegionInfo.ExternalHostName;
233 uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
234 string protocol = "http";
235
236 if (MainServer.Instance.UseSSL)
157 { 237 {
158 capUrl = url; 238 hostName = MainServer.Instance.SSLCommonName;
239 port = MainServer.Instance.SSLPort;
240 protocol = "https";
241 }
242 caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
243
244 m_capsDict[agentID] = capUrl;
245 }
159 246
160 caps.RegisterHandler(capName, capUrl); 247 private void DeregisterCaps(UUID agentID, Caps caps)
248 {
249 string capUrl;
250
251 if (m_capsDict.TryGetValue(agentID, out capUrl))
252 {
253 MainServer.Instance.RemoveHTTPHandler("", capUrl);
254 m_capsDict.Remove(agentID);
161 } 255 }
256 }
162 257
163// m_log.DebugFormat( 258 private void DoInventoryRequests()
164// "[WEB FETCH INV DESC MODULE]: Registered capability {0} at {1} in region {2} for {3}", 259 {
165// capName, capUrl, m_scene.RegionInfo.RegionName, agentID); 260 while (true)
261 {
262 PollServiceInventoryEventArgs args = m_queue.Dequeue();
263
264 args.Process();
265 }
166 } 266 }
167 } 267 }
168} \ No newline at end of file 268}