aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorMelanie2012-09-16 04:21:18 +0100
committerMelanie2012-09-16 04:21:18 +0100
commit66bf1376b5f9a0c9b5a3bdb58ac7eca09b6389ba (patch)
treef5ce10e917fa3ab24ed98cc10ca5a87057da71a9 /OpenSim
parentMerge branch 'master' into careminster (diff)
parentRevamp the HTTP textures handler to allow a maximum of four fetches (diff)
downloadopensim-SC_OLD-66bf1376b5f9a0c9b5a3bdb58ac7eca09b6389ba.zip
opensim-SC_OLD-66bf1376b5f9a0c9b5a3bdb58ac7eca09b6389ba.tar.gz
opensim-SC_OLD-66bf1376b5f9a0c9b5a3bdb58ac7eca09b6389ba.tar.bz2
opensim-SC_OLD-66bf1376b5f9a0c9b5a3bdb58ac7eca09b6389ba.tar.xz
Merge branch 'avination' into careminster
Conflicts: OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs175
-rw-r--r--OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs6
-rw-r--r--OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs4
-rw-r--r--OpenSim/Capabilities/LLSDAssetUploadRequest.cs11
-rw-r--r--OpenSim/Capabilities/LLSDAssetUploadResponse.cs23
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs49
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs3
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs3
-rw-r--r--OpenSim/Framework/WebUtil.cs20
-rw-r--r--OpenSim/Region/Application/Application.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs111
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs223
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs296
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs198
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs2
-rw-r--r--OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs4
18 files changed, 577 insertions, 561 deletions
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
index 8d25e18..7b4e957 100644
--- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
+++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
@@ -47,36 +47,36 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
47 47
48namespace OpenSim.Capabilities.Handlers 48namespace OpenSim.Capabilities.Handlers
49{ 49{
50 public class GetTextureHandler : BaseStreamHandler 50 public class GetTextureHandler
51 { 51 {
52 private static readonly ILog m_log = 52 private static readonly ILog m_log =
53 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 53 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
54 private IAssetService m_assetService; 55 private IAssetService m_assetService;
55 56
56 public const string DefaultFormat = "x-j2c"; 57 public const string DefaultFormat = "x-j2c";
57 58
58 // TODO: Change this to a config option 59 public GetTextureHandler(IAssetService assService)
59 const string REDIRECT_URL = null;
60
61 public GetTextureHandler(string path, IAssetService assService, string name, string description)
62 : base("GET", path, name, description)
63 { 60 {
64 m_assetService = assService; 61 m_assetService = assService;
65 } 62 }
66 63
67 public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 64 public Hashtable Handle(Hashtable request)
68 { 65 {
69 // Try to parse the texture ID from the request URL 66 Hashtable ret = new Hashtable();
70 NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); 67 ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
71 string textureStr = query.GetOne("texture_id"); 68 ret["content_type"] = "text/plain";
72 string format = query.GetOne("format"); 69 ret["keepalive"] = false;
70 ret["reusecontext"] = false;
71
72 string textureStr = (string)request["texture_id"];
73 string format = (string)request["format"];
73 74
74 //m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr); 75 //m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr);
75 76
76 if (m_assetService == null) 77 if (m_assetService == null)
77 { 78 {
78 m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); 79 m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
79 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
80 } 80 }
81 81
82 UUID textureID; 82 UUID textureID;
@@ -91,30 +91,30 @@ namespace OpenSim.Capabilities.Handlers
91 } 91 }
92 else 92 else
93 { 93 {
94 formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept")); 94 formats = new string[1] { DefaultFormat }; // default
95 if (((Hashtable)request["headers"])["Accept"] != null)
96 formats = WebUtil.GetPreferredImageTypes((string)((Hashtable)request["headers"])["Accept"]);
95 if (formats.Length == 0) 97 if (formats.Length == 0)
96 formats = new string[1] { DefaultFormat }; // default 98 formats = new string[1] { DefaultFormat }; // default
97 99
98 } 100 }
99 // OK, we have an array with preferred formats, possibly with only one entry 101 // OK, we have an array with preferred formats, possibly with only one entry
100 102
101 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
102 foreach (string f in formats) 103 foreach (string f in formats)
103 { 104 {
104 if (FetchTexture(httpRequest, httpResponse, textureID, f)) 105 if (FetchTexture(request, ret, textureID, f))
105 break; 106 break;
106 } 107 }
107 } 108 }
108 else 109 else
109 { 110 {
110 m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url); 111 m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + (string)request["uri"]);
111 } 112 }
112 113
113// m_log.DebugFormat( 114// m_log.DebugFormat(
114// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}", 115// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
115// textureID, httpResponse.StatusCode, httpResponse.ContentLength); 116// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
116 117 return ret;
117 return null;
118 } 118 }
119 119
120 /// <summary> 120 /// <summary>
@@ -125,7 +125,7 @@ namespace OpenSim.Capabilities.Handlers
125 /// <param name="textureID"></param> 125 /// <param name="textureID"></param>
126 /// <param name="format"></param> 126 /// <param name="format"></param>
127 /// <returns>False for "caller try another codec"; true otherwise</returns> 127 /// <returns>False for "caller try another codec"; true otherwise</returns>
128 private bool FetchTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID textureID, string format) 128 private bool FetchTexture(Hashtable request, Hashtable response, UUID textureID, string format)
129 { 129 {
130// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format); 130// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
131 AssetBase texture; 131 AssetBase texture;
@@ -134,84 +134,61 @@ namespace OpenSim.Capabilities.Handlers
134 if (format != DefaultFormat) 134 if (format != DefaultFormat)
135 fullID = fullID + "-" + format; 135 fullID = fullID + "-" + format;
136 136
137 if (!String.IsNullOrEmpty(REDIRECT_URL)) 137 // try the cache
138 texture = m_assetService.GetCached(fullID);
139
140 if (texture == null)
138 { 141 {
139 // Only try to fetch locally cached textures. Misses are redirected 142 //m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
140 texture = m_assetService.GetCached(fullID); 143
144 // Fetch locally or remotely. Misses return a 404
145 texture = m_assetService.Get(textureID.ToString());
141 146
142 if (texture != null) 147 if (texture != null)
143 { 148 {
144 if (texture.Type != (sbyte)AssetType.Texture) 149 if (texture.Type != (sbyte)AssetType.Texture)
150 return true;
151
152 if (format == DefaultFormat)
145 { 153 {
146 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; 154 WriteTextureData(request, response, texture, format);
147 return true; 155 return true;
148 } 156 }
149 WriteTextureData(httpRequest, httpResponse, texture, format); 157 else
150 }
151 else
152 {
153 string textureUrl = REDIRECT_URL + textureID.ToString();
154 m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
155 httpResponse.RedirectLocation = textureUrl;
156 return true;
157 }
158 }
159 else // no redirect
160 {
161 // try the cache
162 texture = m_assetService.GetCached(fullID);
163
164 if (texture == null)
165 {
166// m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
167
168 // Fetch locally or remotely. Misses return a 404
169 texture = m_assetService.Get(textureID.ToString());
170
171 if (texture != null)
172 { 158 {
173 if (texture.Type != (sbyte)AssetType.Texture) 159 AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
174 { 160 newTexture.Data = ConvertTextureData(texture, format);
175 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; 161 if (newTexture.Data.Length == 0)
176 return true; 162 return false; // !!! Caller try another codec, please!
177 } 163
178 if (format == DefaultFormat) 164 newTexture.Flags = AssetFlags.Collectable;
179 { 165 newTexture.Temporary = true;
180 WriteTextureData(httpRequest, httpResponse, texture, format); 166 m_assetService.Store(newTexture);
181 return true; 167 WriteTextureData(request, response, newTexture, format);
182 } 168 return true;
183 else
184 {
185 AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
186 newTexture.Data = ConvertTextureData(texture, format);
187 if (newTexture.Data.Length == 0)
188 return false; // !!! Caller try another codec, please!
189
190 newTexture.Flags = AssetFlags.Collectable;
191 newTexture.Temporary = true;
192 m_assetService.Store(newTexture);
193 WriteTextureData(httpRequest, httpResponse, newTexture, format);
194 return true;
195 }
196 } 169 }
197 } 170 }
198 else // it was on the cache 171 }
199 { 172 else // it was on the cache
200// m_log.DebugFormat("[GETTEXTURE]: texture was in the cache"); 173 {
201 WriteTextureData(httpRequest, httpResponse, texture, format); 174 //m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
202 return true; 175 WriteTextureData(request, response, texture, format);
203 } 176 return true;
204 } 177 }
205 178
206 // not found 179 // not found
207// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); 180// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
208 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
209 return true; 181 return true;
210 } 182 }
211 183
212 private void WriteTextureData(IOSHttpRequest request, IOSHttpResponse response, AssetBase texture, string format) 184 private void WriteTextureData(Hashtable request, Hashtable response, AssetBase texture, string format)
213 { 185 {
214 string range = request.Headers.GetOne("Range"); 186 Hashtable headers = new Hashtable();
187 response["headers"] = headers;
188
189 string range = String.Empty;
190 if (((Hashtable)request["headers"])["Range"] != null)
191 range = (string)((Hashtable)request["headers"])["Range"];
215 192
216 if (!String.IsNullOrEmpty(range)) // JP2's only 193 if (!String.IsNullOrEmpty(range)) // JP2's only
217 { 194 {
@@ -239,10 +216,8 @@ namespace OpenSim.Capabilities.Handlers
239 // However, if we return PartialContent (or OK) instead, the viewer will display that resolution. 216 // However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
240 217
241// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; 218// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
242// response.AddHeader("Content-Range", String.Format("bytes */{0}", texture.Data.Length)); 219 // viewers don't seem to handle RequestedRangeNotSatisfiable and keep retrying with same parameters
243// response.StatusCode = (int)System.Net.HttpStatusCode.OK; 220 response["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
244 response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
245 response.ContentType = texture.Metadata.ContentType;
246 } 221 }
247 else 222 else
248 { 223 {
@@ -256,37 +231,33 @@ namespace OpenSim.Capabilities.Handlers
256 // We were accidentally sending back 404 before in this situation 231 // We were accidentally sending back 404 before in this situation
257 // https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the 232 // https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
258 // entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this. 233 // entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
259 // 234 response["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
260 // We also do not want to send back OK even if the whole range was satisfiable since this causes 235 response["content-type"] = texture.Metadata.ContentType;
261 // HTTP textures on at least Imprudence 1.4.0-beta2 to never display the final texture quality. 236 headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length);
262// if (end > maxEnd)
263// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
264// else
265 response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
266
267 response.ContentLength = len;
268 response.ContentType = texture.Metadata.ContentType;
269 response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
270 237
271 response.Body.Write(texture.Data, start, len); 238 byte[] d = new byte[len];
239 Array.Copy(texture.Data, start, d, 0, len);
240 response["bin_response_data"] = d;
241// response.Body.Write(texture.Data, start, len);
272 } 242 }
273 } 243 }
274 else 244 else
275 { 245 {
276 m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range); 246 m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
277 response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest; 247 response["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
278 } 248 }
279 } 249 }
280 else // JP2's or other formats 250 else // JP2's or other formats
281 { 251 {
282 // Full content request 252 // Full content request
283 response.StatusCode = (int)System.Net.HttpStatusCode.OK; 253 response["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
284 response.ContentLength = texture.Data.Length;
285 if (format == DefaultFormat) 254 if (format == DefaultFormat)
286 response.ContentType = texture.Metadata.ContentType; 255 response["content_type"] = texture.Metadata.ContentType;
287 else 256 else
288 response.ContentType = "image/" + format; 257 response["content_type"] = "image/" + format;
289 response.Body.Write(texture.Data, 0, texture.Data.Length); 258
259 response["bin_response_data"] = texture.Data;
260// response.Body.Write(texture.Data, 0, texture.Data.Length);
290 } 261 }
291 262
292// if (response.StatusCode < 200 || response.StatusCode > 299) 263// if (response.StatusCode < 200 || response.StatusCode > 299)
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs
index 71cf033..bf66acb 100644
--- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs
+++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureServerConnector.cs
@@ -33,6 +33,7 @@ using OpenSim.Framework.Servers.HttpServer;
33using OpenSim.Server.Handlers.Base; 33using OpenSim.Server.Handlers.Base;
34using OpenMetaverse; 34using OpenMetaverse;
35 35
36/*
36namespace OpenSim.Capabilities.Handlers 37namespace OpenSim.Capabilities.Handlers
37{ 38{
38 public class GetTextureServerConnector : ServiceConnector 39 public class GetTextureServerConnector : ServiceConnector
@@ -63,7 +64,8 @@ namespace OpenSim.Capabilities.Handlers
63 throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); 64 throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
64 65
65 server.AddStreamHandler( 66 server.AddStreamHandler(
66 new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null)); 67 new GetTextureHandler("/CAPS/GetTexture/", m_AssetService, "GetTexture", null));
67 } 68 }
68 } 69 }
69} \ No newline at end of file 70}
71*/
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs b/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs
index 761e4e7..b6ae41b 100644
--- a/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs
+++ b/OpenSim/Capabilities/Handlers/GetTexture/Tests/GetTextureHandlerTests.cs
@@ -39,6 +39,7 @@ using OpenSim.Region.Framework.Scenes;
39using OpenSim.Tests.Common; 39using OpenSim.Tests.Common;
40using OpenSim.Tests.Common.Mock; 40using OpenSim.Tests.Common.Mock;
41 41
42/*
42namespace OpenSim.Capabilities.Handlers.GetTexture.Tests 43namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
43{ 44{
44 [TestFixture] 45 [TestFixture]
@@ -60,4 +61,5 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
60 Assert.That(resp.StatusCode, Is.EqualTo((int)System.Net.HttpStatusCode.NotFound)); 61 Assert.That(resp.StatusCode, Is.EqualTo((int)System.Net.HttpStatusCode.NotFound));
61 } 62 }
62 } 63 }
63} \ No newline at end of file 64}
65*/
diff --git a/OpenSim/Capabilities/LLSDAssetUploadRequest.cs b/OpenSim/Capabilities/LLSDAssetUploadRequest.cs
index 6e66f0a..f981bf0 100644
--- a/OpenSim/Capabilities/LLSDAssetUploadRequest.cs
+++ b/OpenSim/Capabilities/LLSDAssetUploadRequest.cs
@@ -31,6 +31,15 @@ using OpenMetaverse;
31namespace OpenSim.Framework.Capabilities 31namespace OpenSim.Framework.Capabilities
32{ 32{
33 [OSDMap] 33 [OSDMap]
34 public class LLSDAssetResource
35 {
36 public OSDArray instance_list = new OSDArray();
37 public OSDArray texture_list = new OSDArray();
38 public OSDArray mesh_list = new OSDArray();
39 public string metric = String.Empty;
40 }
41
42 [OSDMap]
34 public class LLSDAssetUploadRequest 43 public class LLSDAssetUploadRequest
35 { 44 {
36 public string asset_type = String.Empty; 45 public string asset_type = String.Empty;
@@ -38,7 +47,7 @@ namespace OpenSim.Framework.Capabilities
38 public UUID folder_id = UUID.Zero; 47 public UUID folder_id = UUID.Zero;
39 public string inventory_type = String.Empty; 48 public string inventory_type = String.Empty;
40 public string name = String.Empty; 49 public string name = String.Empty;
41 50 public LLSDAssetResource asset_resources = new LLSDAssetResource();
42 public LLSDAssetUploadRequest() 51 public LLSDAssetUploadRequest()
43 { 52 {
44 } 53 }
diff --git a/OpenSim/Capabilities/LLSDAssetUploadResponse.cs b/OpenSim/Capabilities/LLSDAssetUploadResponse.cs
index 0d6f7f9..18285b5 100644
--- a/OpenSim/Capabilities/LLSDAssetUploadResponse.cs
+++ b/OpenSim/Capabilities/LLSDAssetUploadResponse.cs
@@ -30,11 +30,32 @@ using System;
30namespace OpenSim.Framework.Capabilities 30namespace OpenSim.Framework.Capabilities
31{ 31{
32 [OSDMap] 32 [OSDMap]
33 public class LLSDAssetUploadResponsePricebrkDown
34 {
35 public int mesh_streaming;
36 public int mesh_physics;
37 public int mesh_instance;
38 public int texture;
39 public int model;
40 }
41
42 [OSDMap]
43 public class LLSDAssetUploadResponseData
44 {
45 public double resource_cost;
46 public double model_streaming_cost;
47 public double simulation_cost;
48 public double physics_cost;
49 public LLSDAssetUploadResponsePricebrkDown upload_price_breakdown = new LLSDAssetUploadResponsePricebrkDown();
50 }
51
52 [OSDMap]
33 public class LLSDAssetUploadResponse 53 public class LLSDAssetUploadResponse
34 { 54 {
35 public string uploader = String.Empty; 55 public string uploader = String.Empty;
36 public string state = String.Empty; 56 public string state = String.Empty;
37 57 public int upload_price = 0;
58 public LLSDAssetUploadResponseData data = null;
38 public LLSDAssetUploadResponse() 59 public LLSDAssetUploadResponse()
39 { 60 {
40 } 61 }
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 44c3411..691b45a 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -632,7 +632,7 @@ namespace OpenSim.Framework.Servers.HttpServer
632 // Every month or so this will wrap and give bad numbers, not really a problem 632 // Every month or so this will wrap and give bad numbers, not really a problem
633 // since its just for reporting 633 // since its just for reporting
634 int tickdiff = requestEndTick - requestStartTick; 634 int tickdiff = requestEndTick - requestStartTick;
635 if (tickdiff > 3000) 635 if (tickdiff > 3000 && requestHandler.Name != "GetTexture")
636 { 636 {
637 m_log.InfoFormat( 637 m_log.InfoFormat(
638 "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms", 638 "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms",
@@ -1493,7 +1493,8 @@ namespace OpenSim.Framework.Servers.HttpServer
1493 internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response) 1493 internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
1494 { 1494 {
1495 int responsecode; 1495 int responsecode;
1496 string responseString; 1496 string responseString = String.Empty;
1497 byte[] responseData = null;
1497 string contentType; 1498 string contentType;
1498 1499
1499 if (responsedata == null) 1500 if (responsedata == null)
@@ -1509,7 +1510,10 @@ namespace OpenSim.Framework.Servers.HttpServer
1509 { 1510 {
1510 //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response"); 1511 //m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
1511 responsecode = (int)responsedata["int_response_code"]; 1512 responsecode = (int)responsedata["int_response_code"];
1512 responseString = (string)responsedata["str_response_string"]; 1513 if (responsedata["bin_response_data"] != null)
1514 responseData = (byte[])responsedata["bin_response_data"];
1515 else
1516 responseString = (string)responsedata["str_response_string"];
1513 contentType = (string)responsedata["content_type"]; 1517 contentType = (string)responsedata["content_type"];
1514 } 1518 }
1515 catch 1519 catch
@@ -1564,25 +1568,40 @@ namespace OpenSim.Framework.Servers.HttpServer
1564 1568
1565 response.AddHeader("Content-Type", contentType); 1569 response.AddHeader("Content-Type", contentType);
1566 1570
1571 if (responsedata.ContainsKey("headers"))
1572 {
1573 Hashtable headerdata = (Hashtable)responsedata["headers"];
1574
1575 foreach (string header in headerdata.Keys)
1576 response.AddHeader(header, (string)headerdata[header]);
1577 }
1578
1567 byte[] buffer; 1579 byte[] buffer;
1568 1580
1569 if (!(contentType.Contains("image") 1581 if (responseData != null)
1570 || contentType.Contains("x-shockwave-flash")
1571 || contentType.Contains("application/x-oar")
1572 || contentType.Contains("application/vnd.ll.mesh")))
1573 { 1582 {
1574 // Text 1583 buffer = responseData;
1575 buffer = Encoding.UTF8.GetBytes(responseString);
1576 } 1584 }
1577 else 1585 else
1578 { 1586 {
1579 // Binary! 1587 if (!(contentType.Contains("image")
1580 buffer = Convert.FromBase64String(responseString); 1588 || contentType.Contains("x-shockwave-flash")
1581 } 1589 || contentType.Contains("application/x-oar")
1590 || contentType.Contains("application/vnd.ll.mesh")))
1591 {
1592 // Text
1593 buffer = Encoding.UTF8.GetBytes(responseString);
1594 }
1595 else
1596 {
1597 // Binary!
1598 buffer = Convert.FromBase64String(responseString);
1599 }
1582 1600
1583 response.SendChunked = false; 1601 response.SendChunked = false;
1584 response.ContentLength64 = buffer.Length; 1602 response.ContentLength64 = buffer.Length;
1585 response.ContentEncoding = Encoding.UTF8; 1603 response.ContentEncoding = Encoding.UTF8;
1604 }
1586 1605
1587 return buffer; 1606 return buffer;
1588 } 1607 }
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
index c24a000..a80b1d7 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs
@@ -52,7 +52,8 @@ namespace OpenSim.Framework.Servers.HttpServer
52 { 52 {
53 Normal = 0, 53 Normal = 0,
54 LslHttp = 1, 54 LslHttp = 1,
55 Inventory = 2 55 Inventory = 2,
56 Texture = 3
56 } 57 }
57 58
58 public PollServiceEventArgs( 59 public PollServiceEventArgs(
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index a1dee4e..db088e7 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -231,8 +231,7 @@ namespace OpenSim.Framework.Servers.HttpServer
231 { 231 {
232 if (m_running) 232 if (m_running)
233 { 233 {
234 if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LslHttp || 234 if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.Normal)
235 req.PollServiceArgs.Type == PollServiceEventArgs.EventType.Inventory)
236 { 235 {
237 m_requests.Enqueue(req); 236 m_requests.Enqueue(req);
238 } 237 }
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs
index 6a40cd5..8094b6d 100644
--- a/OpenSim/Framework/WebUtil.cs
+++ b/OpenSim/Framework/WebUtil.cs
@@ -695,6 +695,13 @@ namespace OpenSim.Framework
695 public static void MakeRequest<TRequest, TResponse>(string verb, 695 public static void MakeRequest<TRequest, TResponse>(string verb,
696 string requestUrl, TRequest obj, Action<TResponse> action) 696 string requestUrl, TRequest obj, Action<TResponse> action)
697 { 697 {
698 MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, action, 0);
699 }
700
701 public static void MakeRequest<TRequest, TResponse>(string verb,
702 string requestUrl, TRequest obj, Action<TResponse> action,
703 int maxConnections)
704 {
698 int reqnum = WebUtil.RequestNumber++; 705 int reqnum = WebUtil.RequestNumber++;
699 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); 706 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
700 707
@@ -706,6 +713,10 @@ namespace OpenSim.Framework
706 Type type = typeof(TRequest); 713 Type type = typeof(TRequest);
707 714
708 WebRequest request = WebRequest.Create(requestUrl); 715 WebRequest request = WebRequest.Create(requestUrl);
716 HttpWebRequest ht = (HttpWebRequest)request;
717 if (maxConnections > 0 && ht.ServicePoint.ConnectionLimit < maxConnections)
718 ht.ServicePoint.ConnectionLimit = maxConnections;
719
709 WebResponse response = null; 720 WebResponse response = null;
710 TResponse deserial = default(TResponse); 721 TResponse deserial = default(TResponse);
711 XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); 722 XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
@@ -1003,6 +1014,11 @@ namespace OpenSim.Framework
1003 1014
1004 public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout) 1015 public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout)
1005 { 1016 {
1017 return MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, pTimeout, 0);
1018 }
1019
1020 public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout, int maxConnections)
1021 {
1006 int reqnum = WebUtil.RequestNumber++; 1022 int reqnum = WebUtil.RequestNumber++;
1007 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); 1023 // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
1008 1024
@@ -1013,6 +1029,10 @@ namespace OpenSim.Framework
1013 TResponse deserial = default(TResponse); 1029 TResponse deserial = default(TResponse);
1014 1030
1015 WebRequest request = WebRequest.Create(requestUrl); 1031 WebRequest request = WebRequest.Create(requestUrl);
1032 HttpWebRequest ht = (HttpWebRequest)request;
1033 if (maxConnections > 0 && ht.ServicePoint.ConnectionLimit < maxConnections)
1034 ht.ServicePoint.ConnectionLimit = maxConnections;
1035
1016 request.Method = verb; 1036 request.Method = verb;
1017 if (pTimeout != 0) 1037 if (pTimeout != 0)
1018 request.Timeout = pTimeout * 1000; 1038 request.Timeout = pTimeout * 1000;
diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs
index 78636c4..0f90d37 100644
--- a/OpenSim/Region/Application/Application.cs
+++ b/OpenSim/Region/Application/Application.cs
@@ -74,7 +74,7 @@ namespace OpenSim
74 AppDomain.CurrentDomain.UnhandledException += 74 AppDomain.CurrentDomain.UnhandledException +=
75 new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 75 new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
76 76
77 ServicePointManager.DefaultConnectionLimit = 6; 77 ServicePointManager.DefaultConnectionLimit = 12;
78 78
79 // Add the arguments supplied when running the application to the configuration 79 // Add the arguments supplied when running the application to the configuration
80 ArgvConfigSource configSource = new ArgvConfigSource(args); 80 ArgvConfigSource configSource = new ArgvConfigSource(args);
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 88c4d7f..580c005 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Timers;
29using System.Collections; 30using System.Collections;
30using System.Collections.Generic; 31using System.Collections.Generic;
31using System.IO; 32using System.IO;
@@ -60,7 +61,7 @@ namespace OpenSim.Region.ClientStack.Linden
60 61
61 public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors); 62 public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors);
62 63
63 public delegate void NewInventoryItem(UUID userID, InventoryItemBase item); 64 public delegate void NewInventoryItem(UUID userID, InventoryItemBase item, uint cost);
64 65
65 public delegate void NewAsset(AssetBase asset); 66 public delegate void NewAsset(AssetBase asset);
66 67
@@ -386,6 +387,37 @@ namespace OpenSim.Region.ClientStack.Linden
386 return UUID.Zero; 387 return UUID.Zero;
387 } 388 }
388 389
390 private delegate void UploadWithCostCompleteDelegate(string assetName,
391 string assetDescription, UUID assetID, UUID inventoryItem,
392 UUID parentFolder, byte[] data, string inventoryType,
393 string assetType, uint cost);
394
395 private class AssetUploaderWithCost : AssetUploader
396 {
397 private uint m_cost;
398
399 public event UploadWithCostCompleteDelegate OnUpLoad;
400
401 public AssetUploaderWithCost(string assetName, string description, UUID assetID,
402 UUID inventoryItem, UUID parentFolderID, string invType, string assetType,
403 string path, IHttpServer httpServer, bool dumpAssetsToFile, uint cost) :
404 base(assetName, description, assetID, inventoryItem, parentFolderID,
405 invType, assetType, path, httpServer, dumpAssetsToFile)
406 {
407 m_cost = cost;
408
409 base.OnUpLoad += UploadCompleteHandler;
410 }
411
412 private void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
413 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
414 string assetType)
415 {
416 OnUpLoad(assetName, assetDescription, assetID, inventoryItem, parentFolder,
417 data, inventoryType, assetType, m_cost);
418 }
419 }
420
389 /// <summary> 421 /// <summary>
390 /// 422 ///
391 /// </summary> 423 /// </summary>
@@ -396,8 +428,11 @@ namespace OpenSim.Region.ClientStack.Linden
396 //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString()); 428 //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString());
397 //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type); 429 //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type);
398 430
431 uint cost = 0;
432
399 if (llsdRequest.asset_type == "texture" || 433 if (llsdRequest.asset_type == "texture" ||
400 llsdRequest.asset_type == "animation" || 434 llsdRequest.asset_type == "animation" ||
435 llsdRequest.asset_type == "mesh" ||
401 llsdRequest.asset_type == "sound") 436 llsdRequest.asset_type == "sound")
402 { 437 {
403 ScenePresence avatar = null; 438 ScenePresence avatar = null;
@@ -428,7 +463,33 @@ namespace OpenSim.Region.ClientStack.Linden
428 463
429 if (mm != null) 464 if (mm != null)
430 { 465 {
431 if (!mm.UploadCovered(client.AgentId, mm.UploadCharge)) 466 // XPTO: The cost should be calculated about here
467
468 if (llsdRequest.asset_type == "mesh")
469 {
470 cost += 20; // Constant for now to test showing a price
471
472 if (llsdRequest.asset_resources == null)
473 {
474 client.SendAgentAlertMessage("Unable to upload asset. missing information.", false);
475
476 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
477 errorResponse.uploader = "";
478 errorResponse.state = "error";
479 return errorResponse;
480 }
481
482 uint textures_cost = (uint)llsdRequest.asset_resources.texture_list.Array.Count;
483 textures_cost *= (uint)mm.UploadCharge;
484
485 cost += textures_cost;
486 }
487 else
488 {
489 cost = (uint)mm.UploadCharge;
490 }
491
492 if (!mm.UploadCovered(client.AgentId, (int)cost))
432 { 493 {
433 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); 494 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
434 495
@@ -449,9 +510,9 @@ namespace OpenSim.Region.ClientStack.Linden
449 UUID parentFolder = llsdRequest.folder_id; 510 UUID parentFolder = llsdRequest.folder_id;
450 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); 511 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
451 512
452 AssetUploader uploader = 513 AssetUploaderWithCost uploader =
453 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, 514 new AssetUploaderWithCost(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
454 llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile); 515 llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile, cost);
455 516
456 m_HostCapsObj.HttpListener.AddStreamHandler( 517 m_HostCapsObj.HttpListener.AddStreamHandler(
457 new BinaryStreamHandler( 518 new BinaryStreamHandler(
@@ -469,11 +530,31 @@ namespace OpenSim.Region.ClientStack.Linden
469 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase + 530 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase +
470 uploaderPath; 531 uploaderPath;
471 532
533
472 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); 534 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
473 uploadResponse.uploader = uploaderURL; 535 uploadResponse.uploader = uploaderURL;
474 uploadResponse.state = "upload"; 536 uploadResponse.state = "upload";
537 uploadResponse.upload_price = (int)cost;
538
539 // use fake values for now
540 if (llsdRequest.asset_type == "mesh")
541 {
542 uploadResponse.data = new LLSDAssetUploadResponseData();
543 uploadResponse.data.model_streaming_cost = 1.0;
544 uploadResponse.data.simulation_cost = 1.5;
545
546 uploadResponse.data.physics_cost = 2.0;
547 uploadResponse.data.resource_cost = 3.0;
548 uploadResponse.data.upload_price_breakdown.mesh_instance = 1;
549 uploadResponse.data.upload_price_breakdown.mesh_physics = 2;
550 uploadResponse.data.upload_price_breakdown.mesh_streaming = 3;
551 uploadResponse.data.upload_price_breakdown.texture = 5;
552 uploadResponse.data.upload_price_breakdown.model = 4;
553 }
554
475 uploader.OnUpLoad += UploadCompleteHandler; 555 uploader.OnUpLoad += UploadCompleteHandler;
476 return uploadResponse; 556 return uploadResponse;
557
477 } 558 }
478 559
479 /// <summary> 560 /// <summary>
@@ -484,7 +565,7 @@ namespace OpenSim.Region.ClientStack.Linden
484 /// <param name="data"></param> 565 /// <param name="data"></param>
485 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID, 566 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
486 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, 567 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
487 string assetType) 568 string assetType, uint cost)
488 { 569 {
489 m_log.DebugFormat( 570 m_log.DebugFormat(
490 "[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}", 571 "[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}",
@@ -703,7 +784,7 @@ namespace OpenSim.Region.ClientStack.Linden
703 784
704 if (AddNewInventoryItem != null) 785 if (AddNewInventoryItem != null)
705 { 786 {
706 AddNewInventoryItem(m_HostCapsObj.AgentID, item); 787 AddNewInventoryItem(m_HostCapsObj.AgentID, item, cost);
707 } 788 }
708 } 789 }
709 790
@@ -1014,6 +1095,9 @@ namespace OpenSim.Region.ClientStack.Linden
1014 1095
1015 public class AssetUploader 1096 public class AssetUploader
1016 { 1097 {
1098 private static readonly ILog m_log =
1099 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
1100
1017 public event UpLoadedAsset OnUpLoad; 1101 public event UpLoadedAsset OnUpLoad;
1018 private UpLoadedAsset handlerUpLoad = null; 1102 private UpLoadedAsset handlerUpLoad = null;
1019 1103
@@ -1028,6 +1112,7 @@ namespace OpenSim.Region.ClientStack.Linden
1028 1112
1029 private string m_invType = String.Empty; 1113 private string m_invType = String.Empty;
1030 private string m_assetType = String.Empty; 1114 private string m_assetType = String.Empty;
1115 private Timer m_timeoutTimer = new Timer();
1031 1116
1032 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem, 1117 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem,
1033 UUID parentFolderID, string invType, string assetType, string path, 1118 UUID parentFolderID, string invType, string assetType, string path,
@@ -1043,6 +1128,11 @@ namespace OpenSim.Region.ClientStack.Linden
1043 m_assetType = assetType; 1128 m_assetType = assetType;
1044 m_invType = invType; 1129 m_invType = invType;
1045 m_dumpAssetsToFile = dumpAssetsToFile; 1130 m_dumpAssetsToFile = dumpAssetsToFile;
1131
1132 m_timeoutTimer.Elapsed += TimedOut;
1133 m_timeoutTimer.Interval = 120000;
1134 m_timeoutTimer.AutoReset = false;
1135 m_timeoutTimer.Start();
1046 } 1136 }
1047 1137
1048 /// <summary> 1138 /// <summary>
@@ -1064,6 +1154,7 @@ namespace OpenSim.Region.ClientStack.Linden
1064 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); 1154 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1065 1155
1066 httpListener.RemoveStreamHandler("POST", uploaderPath); 1156 httpListener.RemoveStreamHandler("POST", uploaderPath);
1157 m_timeoutTimer.Stop();
1067 1158
1068 // TODO: probably make this a better set of extensions here 1159 // TODO: probably make this a better set of extensions here
1069 string extension = ".jp2"; 1160 string extension = ".jp2";
@@ -1085,6 +1176,12 @@ namespace OpenSim.Region.ClientStack.Linden
1085 return res; 1176 return res;
1086 } 1177 }
1087 1178
1179 private void TimedOut(object sender, ElapsedEventArgs args)
1180 {
1181 m_log.InfoFormat("[CAPS]: Removing URL and handler for timed out mesh upload");
1182 httpListener.RemoveStreamHandler("POST", uploaderPath);
1183 }
1184
1088 ///Left this in and commented in case there are unforseen issues 1185 ///Left this in and commented in case there are unforseen issues
1089 //private void SaveAssetToFile(string filename, byte[] data) 1186 //private void SaveAssetToFile(string filename, byte[] data)
1090 //{ 1187 //{
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
index 5ae9cc3..5b125ea 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,64 +42,73 @@ 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{
53 49
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 50 /// <summary>
51 /// This module implements both WebFetchTextureDescendents and FetchTextureDescendents2 capabilities.
52 /// </summary>
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")]
55 public class GetTextureModule : INonSharedRegionModule 54 public class GetTextureModule : INonSharedRegionModule
56 { 55 {
57// private static readonly ILog m_log = 56 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
58// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 57
59
60 private Scene m_scene; 58 private Scene m_scene;
61 private IAssetService m_assetService;
62 59
63 private bool m_Enabled = false; 60 private static GetTextureHandler m_getTextureHandler;
61
62 private IAssetService m_assetService = null;
64 63
65 // TODO: Change this to a config option 64 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
66 const string REDIRECT_URL = null; 65 private static Thread[] m_workerThreads = null;
67 66
68 private string m_URL; 67 private static OpenMetaverse.BlockingQueue<PollServiceTextureEventArgs> m_queue =
68 new OpenMetaverse.BlockingQueue<PollServiceTextureEventArgs>();
69 69
70 #region ISharedRegionModule Members 70 #region ISharedRegionModule Members
71 71
72 public void Initialise(IConfigSource source) 72 public void Initialise(IConfigSource source)
73 { 73 {
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 } 74 }
83 75
84 public void AddRegion(Scene s) 76 public void AddRegion(Scene s)
85 { 77 {
86 if (!m_Enabled)
87 return;
88
89 m_scene = s; 78 m_scene = s;
79 m_assetService = s.AssetService;
90 } 80 }
91 81
92 public void RemoveRegion(Scene s) 82 public void RemoveRegion(Scene s)
93 { 83 {
94 if (!m_Enabled)
95 return;
96
97 m_scene.EventManager.OnRegisterCaps -= RegisterCaps; 84 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
85 m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
98 m_scene = null; 86 m_scene = null;
99 } 87 }
100 88
101 public void RegionLoaded(Scene s) 89 public void RegionLoaded(Scene s)
102 { 90 {
103 if (!m_Enabled) 91 // We'll reuse the same handler for all requests.
104 return; 92 m_getTextureHandler = new GetTextureHandler(m_assetService);
105 93
106 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
107 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 94 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
95 m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
96
97 if (m_workerThreads == null)
98 {
99 m_workerThreads = new Thread[4];
100
101 for (uint i = 0; i < 4; i++)
102 {
103 m_workerThreads[i] = Watchdog.StartThread(DoTextureRequests,
104 String.Format("TextureWorkerThread{0}", i),
105 ThreadPriority.Normal,
106 false,
107 true,
108 null,
109 int.MaxValue);
110 }
111 }
108 } 112 }
109 113
110 public void PostInitialise() 114 public void PostInitialise()
@@ -122,24 +126,155 @@ namespace OpenSim.Region.ClientStack.Linden
122 126
123 #endregion 127 #endregion
124 128
125 public void RegisterCaps(UUID agentID, Caps caps) 129 ~GetTextureModule()
130 {
131 foreach (Thread t in m_workerThreads)
132 t.Abort();
133 }
134
135 private class PollServiceTextureEventArgs : PollServiceEventArgs
126 { 136 {
127 UUID capID = UUID.Random(); 137 private List<Hashtable> requests =
138 new List<Hashtable>();
139 private Dictionary<UUID, Hashtable> responses =
140 new Dictionary<UUID, Hashtable>();
141
142 private Scene m_scene;
128 143
129 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); 144 public PollServiceTextureEventArgs(UUID pId, Scene scene) :
130 if (m_URL == "localhost") 145 base(null, null, null, null, pId, 30000)
131 { 146 {
132// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); 147 m_scene = scene;
133 caps.RegisterHandler( 148
134 "GetTexture", 149 HasEvents = (x, y) => { return this.responses.ContainsKey(x); };
135 new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString())); 150 GetEvents = (x, y, s) =>
151 {
152 try
153 {
154 return this.responses[x];
155 }
156 finally
157 {
158 responses.Remove(x);
159 }
160 };
161
162 Request = (x, y) =>
163 {
164 y["RequestID"] = x.ToString();
165 lock (this.requests)
166 this.requests.Add(y);
167
168 m_queue.Enqueue(this);
169 };
170
171 NoEvents = (x, y) =>
172 {
173 lock (this.requests)
174 {
175 Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
176 requests.Remove(request);
177 }
178
179 Hashtable response = new Hashtable();
180
181 response["int_response_code"] = 500;
182 response["str_response_string"] = "Script timeout";
183 response["content_type"] = "text/plain";
184 response["keepalive"] = false;
185 response["reusecontext"] = false;
186
187 return response;
188 };
136 } 189 }
137 else 190
191 public void Process()
138 { 192 {
139// m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName); 193 Hashtable response;
140 caps.RegisterHandler("GetTexture", m_URL); 194 Hashtable request = null;
195
196 try
197 {
198 lock (this.requests)
199 {
200 request = requests[0];
201 requests.RemoveAt(0);
202 }
203 }
204 catch
205 {
206 return;
207 }
208
209 UUID requestID = new UUID(request["RequestID"].ToString());
210
211 // If the avatar is gone, don't bother to get the texture
212 if (m_scene.GetScenePresence(Id) == null)
213 {
214 response = new Hashtable();
215
216 response["int_response_code"] = 500;
217 response["str_response_string"] = "Script timeout";
218 response["content_type"] = "text/plain";
219 response["keepalive"] = false;
220 response["reusecontext"] = false;
221
222 responses[requestID] = response;
223 return;
224 }
225
226 response = m_getTextureHandler.Handle(request);
227
228 responses[requestID] = response;
229 }
230 }
231
232 private void RegisterCaps(UUID agentID, Caps caps)
233 {
234 string capUrl = "/CAPS/" + UUID.Random() + "/";
235
236 // Register this as a poll service
237 // absurd large timeout to tune later to make a bit less than viewer
238 PollServiceTextureEventArgs args = new PollServiceTextureEventArgs(agentID, m_scene);
239
240 args.Type = PollServiceEventArgs.EventType.Texture;
241 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
242
243 string hostName = m_scene.RegionInfo.ExternalHostName;
244 uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
245 string protocol = "http";
246
247 if (MainServer.Instance.UseSSL)
248 {
249 hostName = MainServer.Instance.SSLCommonName;
250 port = MainServer.Instance.SSLPort;
251 protocol = "https";
141 } 252 }
253 caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
254
255 m_capsDict[agentID] = capUrl;
142 } 256 }
143 257
258 private void DeregisterCaps(UUID agentID, Caps caps)
259 {
260 string capUrl;
261
262 if (m_capsDict.TryGetValue(agentID, out capUrl))
263 {
264 MainServer.Instance.RemoveHTTPHandler("", capUrl);
265 m_capsDict.Remove(agentID);
266 }
267 }
268
269 private void DoTextureRequests()
270 {
271 while (true)
272 {
273 PollServiceTextureEventArgs args = m_queue.Dequeue();
274
275 args.Process();
276 }
277 }
144 } 278 }
279
145} 280}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
deleted file mode 100644
index 52c4f44..0000000
--- a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
+++ /dev/null
@@ -1,296 +0,0 @@
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.Specialized;
31using System.Reflection;
32using System.IO;
33using System.Web;
34using Mono.Addins;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Framework;
40using OpenSim.Framework.Servers;
41using OpenSim.Framework.Servers.HttpServer;
42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Services.Interfaces;
45using Caps = OpenSim.Framework.Capabilities.Caps;
46using OpenSim.Framework.Capabilities;
47
48namespace OpenSim.Region.ClientStack.Linden
49{
50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
51 public class NewFileAgentInventoryVariablePriceModule : INonSharedRegionModule
52 {
53// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
55 private Scene m_scene;
56// private IAssetService m_assetService;
57 private bool m_dumpAssetsToFile = false;
58 private bool m_enabled = true;
59 private int m_levelUpload = 0;
60
61 #region IRegionModuleBase Members
62
63
64 public Type ReplaceableInterface
65 {
66 get { return null; }
67 }
68
69 public void Initialise(IConfigSource source)
70 {
71 IConfig meshConfig = source.Configs["Mesh"];
72 if (meshConfig == null)
73 return;
74
75 m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true);
76 m_levelUpload = meshConfig.GetInt("LevelUpload", 0);
77 }
78
79 public void AddRegion(Scene pScene)
80 {
81 m_scene = pScene;
82 }
83
84 public void RemoveRegion(Scene scene)
85 {
86
87 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
88 m_scene = null;
89 }
90
91 public void RegionLoaded(Scene scene)
92 {
93
94// m_assetService = m_scene.RequestModuleInterface<IAssetService>();
95 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
96 }
97
98 #endregion
99
100
101 #region IRegionModule Members
102
103
104
105 public void Close() { }
106
107 public string Name { get { return "NewFileAgentInventoryVariablePriceModule"; } }
108
109
110 public void RegisterCaps(UUID agentID, Caps caps)
111 {
112 if(!m_enabled)
113 return;
114
115 UUID capID = UUID.Random();
116
117// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID);
118 caps.RegisterHandler(
119 "NewFileAgentInventoryVariablePrice",
120 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>(
121 "POST",
122 "/CAPS/" + capID.ToString(),
123 req => NewAgentInventoryRequest(req, agentID),
124 "NewFileAgentInventoryVariablePrice",
125 agentID.ToString()));
126 }
127
128 #endregion
129
130 public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID)
131 {
132 //TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit
133 // you need to be aware of this
134
135 //if (llsdRequest.asset_type == "texture" ||
136 // llsdRequest.asset_type == "animation" ||
137 // llsdRequest.asset_type == "sound")
138 // {
139 // check user level
140
141 ScenePresence avatar = null;
142 IClientAPI client = null;
143 m_scene.TryGetScenePresence(agentID, out avatar);
144
145 if (avatar != null)
146 {
147 client = avatar.ControllingClient;
148
149 if (avatar.UserLevel < m_levelUpload)
150 {
151 if (client != null)
152 client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
153
154 LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
155 errorResponse.rsvp = "";
156 errorResponse.state = "error";
157 return errorResponse;
158 }
159 }
160
161 // check funds
162 IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
163
164 if (mm != null)
165 {
166 if (!mm.UploadCovered(agentID, mm.UploadCharge))
167 {
168 if (client != null)
169 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
170
171 LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
172 errorResponse.rsvp = "";
173 errorResponse.state = "error";
174 return errorResponse;
175 }
176 }
177
178 // }
179
180 string assetName = llsdRequest.name;
181 string assetDes = llsdRequest.description;
182 string capsBase = "/CAPS/NewFileAgentInventoryVariablePrice/";
183 UUID newAsset = UUID.Random();
184 UUID newInvItem = UUID.Random();
185 UUID parentFolder = llsdRequest.folder_id;
186 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000") + "/";
187
188 AssetUploader uploader =
189 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
190 llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile);
191
192 MainServer.Instance.AddStreamHandler(
193 new BinaryStreamHandler(
194 "POST",
195 capsBase + uploaderPath,
196 uploader.uploaderCaps,
197 "NewFileAgentInventoryVariablePrice",
198 agentID.ToString()));
199
200 string protocol = "http://";
201
202 if (MainServer.Instance.UseSSL)
203 protocol = "https://";
204
205 string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase +
206 uploaderPath;
207
208
209 LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
210
211 uploadResponse.rsvp = uploaderURL;
212 uploadResponse.state = "upload";
213 uploadResponse.resource_cost = 0;
214 uploadResponse.upload_price = 0;
215
216 uploader.OnUpLoad += //UploadCompleteHandler;
217
218 delegate(
219 string passetName, string passetDescription, UUID passetID,
220 UUID pinventoryItem, UUID pparentFolder, byte[] pdata, string pinventoryType,
221 string passetType)
222 {
223 UploadCompleteHandler(passetName, passetDescription, passetID,
224 pinventoryItem, pparentFolder, pdata, pinventoryType,
225 passetType,agentID);
226 };
227
228 return uploadResponse;
229 }
230
231 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
232 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
233 string assetType,UUID AgentID)
234 {
235// m_log.DebugFormat(
236// "[NEW FILE AGENT INVENTORY VARIABLE PRICE MODULE]: Upload complete for {0}", inventoryItem);
237
238 sbyte assType = 0;
239 sbyte inType = 0;
240
241 if (inventoryType == "sound")
242 {
243 inType = 1;
244 assType = 1;
245 }
246 else if (inventoryType == "animation")
247 {
248 inType = 19;
249 assType = 20;
250 }
251 else if (inventoryType == "wearable")
252 {
253 inType = 18;
254 switch (assetType)
255 {
256 case "bodypart":
257 assType = 13;
258 break;
259 case "clothing":
260 assType = 5;
261 break;
262 }
263 }
264 else if (inventoryType == "mesh")
265 {
266 inType = (sbyte)InventoryType.Mesh;
267 assType = (sbyte)AssetType.Mesh;
268 }
269
270 AssetBase asset;
271 asset = new AssetBase(assetID, assetName, assType, AgentID.ToString());
272 asset.Data = data;
273
274 if (m_scene.AssetService != null)
275 m_scene.AssetService.Store(asset);
276
277 InventoryItemBase item = new InventoryItemBase();
278 item.Owner = AgentID;
279 item.CreatorId = AgentID.ToString();
280 item.ID = inventoryItem;
281 item.AssetID = asset.FullID;
282 item.Description = assetDescription;
283 item.Name = assetName;
284 item.AssetType = assType;
285 item.InvType = inType;
286 item.Folder = parentFolder;
287 item.CurrentPermissions
288 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
289 item.BasePermissions = (uint)PermissionMask.All;
290 item.EveryOnePermissions = 0;
291 item.NextPermissions = (uint)PermissionMask.All;
292 item.CreationDate = Util.UnixTimeSinceEpoch();
293 m_scene.AddInventoryItem(item);
294 }
295 }
296}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
index e996fe8..4908c2c 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -42,6 +42,7 @@ using OpenSim.Region.Framework.Scenes;
42using OpenSim.Services.Interfaces; 42using OpenSim.Services.Interfaces;
43using Caps = OpenSim.Framework.Capabilities.Caps; 43using Caps = OpenSim.Framework.Capabilities.Caps;
44using OpenSim.Capabilities.Handlers; 44using OpenSim.Capabilities.Handlers;
45using OpenSim.Framework.Monitoring;
45 46
46namespace OpenSim.Region.ClientStack.Linden 47namespace OpenSim.Region.ClientStack.Linden
47{ 48{
@@ -58,13 +59,13 @@ namespace OpenSim.Region.ClientStack.Linden
58 private IInventoryService m_InventoryService; 59 private IInventoryService m_InventoryService;
59 private ILibraryService m_LibraryService; 60 private ILibraryService m_LibraryService;
60 61
61 private WebFetchInvDescHandler m_webFetchHandler; 62 private static WebFetchInvDescHandler m_webFetchHandler;
62
63 private object m_lock = new object();
64 63
65 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>(); 64 private Dictionary<UUID, string> m_capsDict = new Dictionary<UUID, string>();
66 private Dictionary<UUID, Hashtable> m_requests = new Dictionary<UUID, Hashtable>(); 65 private static Thread[] m_workerThreads = null;
67 bool m_busy = false; 66
67 private static OpenMetaverse.BlockingQueue<PollServiceInventoryEventArgs> m_queue =
68 new OpenMetaverse.BlockingQueue<PollServiceInventoryEventArgs>();
68 69
69 #region ISharedRegionModule Members 70 #region ISharedRegionModule Members
70 71
@@ -94,6 +95,22 @@ namespace OpenSim.Region.ClientStack.Linden
94 95
95 m_scene.EventManager.OnRegisterCaps += RegisterCaps; 96 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
96 m_scene.EventManager.OnDeregisterCaps += DeregisterCaps; 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 }
97 } 114 }
98 115
99 public void PostInitialise() 116 public void PostInitialise()
@@ -111,13 +128,103 @@ namespace OpenSim.Region.ClientStack.Linden
111 128
112 #endregion 129 #endregion
113 130
131 ~WebFetchInvDescModule()
132 {
133 foreach (Thread t in m_workerThreads)
134 t.Abort();
135 }
136
137 private class PollServiceInventoryEventArgs : PollServiceEventArgs
138 {
139 private List<Hashtable> requests =
140 new List<Hashtable>();
141 private Dictionary<UUID, Hashtable> responses =
142 new Dictionary<UUID, Hashtable>();
143
144 public PollServiceInventoryEventArgs(UUID pId) :
145 base(null, null, null, null, pId, 30000)
146 {
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());
207
208 Hashtable response = new Hashtable();
209
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;
218 }
219 }
220
114 private void RegisterCaps(UUID agentID, Caps caps) 221 private void RegisterCaps(UUID agentID, Caps caps)
115 { 222 {
116 string capUrl = "/CAPS/" + UUID.Random() + "/"; 223 string capUrl = "/CAPS/" + UUID.Random() + "/";
117 224
118 // Register this as a poll service 225 // Register this as a poll service
119 // absurd large timeout to tune later to make a bit less than viewer 226 // absurd large timeout to tune later to make a bit less than viewer
120 PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, agentID, 300000); 227 PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(agentID);
121 228
122 args.Type = PollServiceEventArgs.EventType.Inventory; 229 args.Type = PollServiceEventArgs.EventType.Inventory;
123 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); 230 MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
@@ -135,8 +242,6 @@ namespace OpenSim.Region.ClientStack.Linden
135 caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl)); 242 caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
136 243
137 m_capsDict[agentID] = capUrl; 244 m_capsDict[agentID] = capUrl;
138
139 m_busy = false;
140 } 245 }
141 246
142 private void DeregisterCaps(UUID agentID, Caps caps) 247 private void DeregisterCaps(UUID agentID, Caps caps)
@@ -150,83 +255,14 @@ namespace OpenSim.Region.ClientStack.Linden
150 } 255 }
151 } 256 }
152 257
153 public void HttpRequestHandler(UUID requestID, Hashtable request) 258 private void DoInventoryRequests()
154 { 259 {
155// m_log.DebugFormat("[FETCH2]: Received request {0}", requestID); 260 while (true)
156 lock(m_lock)
157 m_requests[requestID] = request;
158 }
159
160 private bool HasEvents(UUID requestID, UUID sessionID)
161 {
162 lock (m_lock)
163 { 261 {
164 return !m_busy; 262 PollServiceInventoryEventArgs args = m_queue.Dequeue();
165 }
166 }
167
168 private Hashtable NoEvents(UUID requestID, UUID sessionID)
169 {
170 lock(m_lock)
171 m_requests.Remove(requestID);
172
173 Hashtable response = new Hashtable();
174
175 response["int_response_code"] = 500;
176 response["str_response_string"] = "Script timeout";
177 response["content_type"] = "text/plain";
178 response["keepalive"] = false;
179 response["reusecontext"] = false;
180
181 lock (m_lock)
182 m_busy = false;
183 263
184 return response; 264 args.Process();
185 }
186
187 private Hashtable GetEvents(UUID requestID, UUID sessionID, string request)
188 {
189 lock (m_lock)
190 m_busy = true;
191
192 Hashtable response = new Hashtable();
193
194 response["int_response_code"] = 500;
195 response["str_response_string"] = "Internal error";
196 response["content_type"] = "text/plain";
197 response["keepalive"] = false;
198 response["reusecontext"] = false;
199
200 try
201 {
202
203 Hashtable requestHash;
204 lock (m_lock)
205 {
206 if (!m_requests.TryGetValue(requestID, out requestHash))
207 {
208 m_busy = false;
209 response["str_response_string"] = "Invalid request";
210 return response;
211 }
212 m_requests.Remove(requestID);
213 }
214
215// m_log.DebugFormat("[FETCH2]: Processed request {0}", requestID);
216
217 string reply = m_webFetchHandler.FetchInventoryDescendentsRequest(requestHash["body"].ToString(), String.Empty, String.Empty, null, null);
218
219
220 response["int_response_code"] = 200;
221 response["str_response_string"] = reply;
222 }
223 finally
224 {
225 lock (m_lock)
226 m_busy = false;
227 } 265 }
228
229 return response;
230 } 266 }
231 } 267 }
232} 268}
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
index d0cab49..70dd1bc 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
@@ -218,7 +218,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
218 id, m_mod.Scene.RegionInfo.RegionName, currentState)); 218 id, m_mod.Scene.RegionInfo.RegionName, currentState));
219 } 219 }
220 220
221 int count = 200; 221 int count = 400;
222 222
223 // There should be no race condition here since no other code should be removing the agent transfer or 223 // There should be no race condition here since no other code should be removing the agent transfer or
224 // changing the state to another other than Transferring => ReceivedAtDestination. 224 // changing the state to another other than Transferring => ReceivedAtDestination.
@@ -266,4 +266,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
266 } 266 }
267 } 267 }
268 } 268 }
269} \ No newline at end of file 269}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 863aa49..3d68081 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -101,12 +101,12 @@ namespace OpenSim.Region.Framework.Scenes
101 engine.StartProcessing(); 101 engine.StartProcessing();
102 } 102 }
103 103
104 public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item) 104 public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item, uint cost)
105 { 105 {
106 IMoneyModule money = RequestModuleInterface<IMoneyModule>(); 106 IMoneyModule money = RequestModuleInterface<IMoneyModule>();
107 if (money != null) 107 if (money != null)
108 { 108 {
109 money.ApplyUploadCharge(agentID, money.UploadCharge, "Asset upload"); 109 money.ApplyUploadCharge(agentID, (int)cost, "Asset upload");
110 } 110 }
111 111
112 AddInventoryItem(item); 112 AddInventoryItem(item);
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 66cce60..a5fcf4d 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -4315,7 +4315,7 @@ namespace OpenSim.Region.Framework.Scenes
4315 /// <param name='agentID'></param> 4315 /// <param name='agentID'></param>
4316 protected virtual ScenePresence WaitGetScenePresence(UUID agentID) 4316 protected virtual ScenePresence WaitGetScenePresence(UUID agentID)
4317 { 4317 {
4318 int ntimes = 20; 4318 int ntimes = 30;
4319 ScenePresence sp = null; 4319 ScenePresence sp = null;
4320 while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0)) 4320 while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0))
4321 Thread.Sleep(1000); 4321 Thread.Sleep(1000);
diff --git a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs
index 9e04601..daf38bc 100644
--- a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs
@@ -193,7 +193,7 @@ namespace OpenSim.Services.Connectors
193 if (asset == null || asset.Data == null || asset.Data.Length == 0) 193 if (asset == null || asset.Data == null || asset.Data.Length == 0)
194 { 194 {
195 asset = SynchronousRestObjectRequester. 195 asset = SynchronousRestObjectRequester.
196 MakeRequest<int, AssetBase>("GET", uri, 0); 196 MakeRequest<int, AssetBase>("GET", uri, 0, 30);
197 197
198 if (m_Cache != null) 198 if (m_Cache != null)
199 m_Cache.Cache(asset); 199 m_Cache.Cache(asset);
@@ -321,7 +321,7 @@ namespace OpenSim.Services.Connectors
321 h.Invoke(a); 321 h.Invoke(a);
322 if (handlers != null) 322 if (handlers != null)
323 handlers.Clear(); 323 handlers.Clear();
324 }); 324 }, 30);
325 325
326 success = true; 326 success = true;
327 } 327 }