aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs223
1 files changed, 180 insertions, 43 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
index 13415f8..24a0190 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
@@ -27,18 +27,13 @@
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Specialized; 30using System.Collections.Generic;
31using System.Drawing;
32using System.Drawing.Imaging;
33using System.Reflection; 31using System.Reflection;
34using System.IO; 32using System.Threading;
35using System.Web;
36using log4net; 33using log4net;
37using Nini.Config; 34using Nini.Config;
38using Mono.Addins; 35using Mono.Addins;
39using OpenMetaverse; 36using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41using OpenMetaverse.Imaging;
42using OpenSim.Framework; 37using OpenSim.Framework;
43using OpenSim.Framework.Servers; 38using OpenSim.Framework.Servers;
44using OpenSim.Framework.Servers.HttpServer; 39using OpenSim.Framework.Servers.HttpServer;
@@ -47,6 +42,7 @@ using OpenSim.Region.Framework.Scenes;
47using OpenSim.Services.Interfaces; 42using OpenSim.Services.Interfaces;
48using Caps = OpenSim.Framework.Capabilities.Caps; 43using Caps = OpenSim.Framework.Capabilities.Caps;
49using OpenSim.Capabilities.Handlers; 44using OpenSim.Capabilities.Handlers;
45using OpenSim.Framework.Monitoring;
50 46
51namespace OpenSim.Region.ClientStack.Linden 47namespace OpenSim.Region.ClientStack.Linden
52{ 48{
@@ -54,57 +50,70 @@ namespace OpenSim.Region.ClientStack.Linden
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")] 50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")]
55 public class GetTextureModule : INonSharedRegionModule 51 public class GetTextureModule : INonSharedRegionModule
56 { 52 {
57// private static readonly ILog m_log = 53
58// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 struct aPollRequest
59 55 {
56 public PollServiceTextureEventArgs thepoll;
57 public UUID reqID;
58 public Hashtable request;
59 }
60
61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
62
60 private Scene m_scene; 63 private Scene m_scene;
61 private IAssetService m_assetService;
62 64
63 private bool m_Enabled = false; 65 private static GetTextureHandler m_getTextureHandler;
66
67 private IAssetService m_assetService = null;
64 68
65 // TODO: Change this to a config option 69 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
66 const string REDIRECT_URL = null; 70 private static Thread[] m_workerThreads = null;
67 71
68 private string m_URL; 72 private static OpenMetaverse.BlockingQueue<aPollRequest> m_queue =
73 new OpenMetaverse.BlockingQueue<aPollRequest>();
69 74
70 #region ISharedRegionModule Members 75 #region ISharedRegionModule Members
71 76
72 public void Initialise(IConfigSource source) 77 public void Initialise(IConfigSource source)
73 { 78 {
74 IConfig config = source.Configs["ClientStack.LindenCaps"];
75 if (config == null)
76 return;
77
78 m_URL = config.GetString("Cap_GetTexture", string.Empty);
79 // Cap doesn't exist
80 if (m_URL != string.Empty)
81 m_Enabled = true;
82 } 79 }
83 80
84 public void AddRegion(Scene s) 81 public void AddRegion(Scene s)
85 { 82 {
86 if (!m_Enabled)
87 return;
88
89 m_scene = s; 83 m_scene = s;
84 m_assetService = s.AssetService;
90 } 85 }
91 86
92 public void RemoveRegion(Scene s) 87 public void RemoveRegion(Scene s)
93 { 88 {
94 if (!m_Enabled)
95 return;
96
97 m_scene.EventManager.OnRegisterCaps -= RegisterCaps; 89 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
90 m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
98 m_scene = null; 91 m_scene = null;
99 } 92 }
100 93
101 public void RegionLoaded(Scene s) 94 public void RegionLoaded(Scene s)
102 { 95 {
103 if (!m_Enabled) 96 // We'll reuse the same handler for all requests.
104 return; 97 m_getTextureHandler = new GetTextureHandler(m_assetService);
105 98
106 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
107 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 99 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
100 m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
101
102 if (m_workerThreads == null)
103 {
104 m_workerThreads = new Thread[2];
105
106 for (uint i = 0; i < 2; i++)
107 {
108 m_workerThreads[i] = Watchdog.StartThread(DoTextureRequests,
109 String.Format("TextureWorkerThread{0}", i),
110 ThreadPriority.Normal,
111 false,
112 false,
113 null,
114 int.MaxValue);
115 }
116 }
108 } 117 }
109 118
110 public void PostInitialise() 119 public void PostInitialise()
@@ -122,24 +131,152 @@ namespace OpenSim.Region.ClientStack.Linden
122 131
123 #endregion 132 #endregion
124 133
125 public void RegisterCaps(UUID agentID, Caps caps) 134 ~GetTextureModule()
135 {
136 foreach (Thread t in m_workerThreads)
137 Watchdog.AbortThread(t.ManagedThreadId);
138
139 }
140
141 private class PollServiceTextureEventArgs : PollServiceEventArgs
142 {
143 private List<Hashtable> requests =
144 new List<Hashtable>();
145 private Dictionary<UUID, Hashtable> responses =
146 new Dictionary<UUID, Hashtable>();
147
148 private Scene m_scene;
149
150 public PollServiceTextureEventArgs(UUID pId, Scene scene) :
151 base(null, null, null, null, pId, int.MaxValue)
152 {
153 m_scene = scene;
154
155 HasEvents = (x, y) =>
156 {
157 lock (responses)
158 return responses.ContainsKey(x);
159 };
160 GetEvents = (x, y) =>
161 {
162 lock (responses)
163 {
164 try
165 {
166 return responses[x];
167 }
168 finally
169 {
170 responses.Remove(x);
171 }
172 }
173 };
174
175 Request = (x, y) =>
176 {
177 aPollRequest reqinfo = new aPollRequest();
178 reqinfo.thepoll = this;
179 reqinfo.reqID = x;
180 reqinfo.request = y;
181
182 m_queue.Enqueue(reqinfo);
183 };
184
185 // this should never happen except possible on shutdown
186 NoEvents = (x, y) =>
187 {
188/*
189 lock (requests)
190 {
191 Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
192 requests.Remove(request);
193 }
194*/
195 Hashtable response = new Hashtable();
196
197 response["int_response_code"] = 500;
198 response["str_response_string"] = "Script timeout";
199 response["content_type"] = "text/plain";
200 response["keepalive"] = false;
201 response["reusecontext"] = false;
202
203 return response;
204 };
205 }
206
207 public void Process(aPollRequest requestinfo)
208 {
209 Hashtable response;
210
211 UUID requestID = requestinfo.reqID;
212
213 // If the avatar is gone, don't bother to get the texture
214 if (m_scene.GetScenePresence(Id) == null)
215 {
216 response = new Hashtable();
217
218 response["int_response_code"] = 500;
219 response["str_response_string"] = "Script timeout";
220 response["content_type"] = "text/plain";
221 response["keepalive"] = false;
222 response["reusecontext"] = false;
223
224 lock (responses)
225 responses[requestID] = response;
226
227 return;
228 }
229
230 response = m_getTextureHandler.Handle(requestinfo.request);
231 lock (responses)
232 responses[requestID] = response;
233 }
234 }
235
236 private void RegisterCaps(UUID agentID, Caps caps)
126 { 237 {
127 UUID capID = UUID.Random(); 238 string capUrl = "/CAPS/" + UUID.Random() + "/";
239
240 // Register this as a poll service
241 PollServiceTextureEventArgs args = new PollServiceTextureEventArgs(agentID, m_scene);
242
243 args.Type = PollServiceEventArgs.EventType.Texture;
244 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
128 245
129 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); 246 string hostName = m_scene.RegionInfo.ExternalHostName;
130 if (m_URL == "localhost") 247 uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
248 string protocol = "http";
249
250 if (MainServer.Instance.UseSSL)
131 { 251 {
132// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); 252 hostName = MainServer.Instance.SSLCommonName;
133 caps.RegisterHandler( 253 port = MainServer.Instance.SSLPort;
134 "GetTexture", 254 protocol = "https";
135 new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString()));
136 } 255 }
137 else 256 caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
257
258 m_capsDict[agentID] = capUrl;
259 }
260
261 private void DeregisterCaps(UUID agentID, Caps caps)
262 {
263 string capUrl;
264
265 if (m_capsDict.TryGetValue(agentID, out capUrl))
138 { 266 {
139// m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); 267 MainServer.Instance.RemoveHTTPHandler("", capUrl);
140 caps.RegisterHandler("GetTexture", m_URL); 268 m_capsDict.Remove(agentID);
141 } 269 }
142 } 270 }
143 271
272 private void DoTextureRequests()
273 {
274 while (true)
275 {
276 aPollRequest poolreq = m_queue.Dequeue();
277
278 poolreq.thepoll.Process(poolreq);
279 }
280 }
144 } 281 }
145} 282}