aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Capabilities/Handlers
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2012-09-06 00:11:47 +0100
committerJustin Clark-Casey (justincc)2012-09-06 00:11:47 +0100
commita0d0c9f751f45d54772af2e33866b27c9be33511 (patch)
treeb94a250c12264f8c44387e79e35b62893dab441b /OpenSim/Capabilities/Handlers
parentBump master code up to 0.7.5 now that 0.7.4 is out. (diff)
downloadopensim-SC-a0d0c9f751f45d54772af2e33866b27c9be33511.zip
opensim-SC-a0d0c9f751f45d54772af2e33866b27c9be33511.tar.gz
opensim-SC-a0d0c9f751f45d54772af2e33866b27c9be33511.tar.bz2
opensim-SC-a0d0c9f751f45d54772af2e33866b27c9be33511.tar.xz
If the GetTexture capability receives a request for a range of data beyond that of an otherwise valid asset, return HTTP PartialContent rather than RequestedRangeNotSatisfiable.
This is because recent viewers (3.2.1, 3.3.4) and probably earlier ones using the http GetTexture capability will sometimes make such invalid range requests. This appears to happen if the viewer's estimate of texture sizes at discard levels > 0 (chiefly 2) exceeds the total texture size. I believe this does not normally happen but can occur for dynamic textures with are large but mainly blank. If this happens, returning a RequestedRangeNotSatisfiable will cause the viewer to not render the texture at the final resolution. However, returning a PartialContent (or OK) even with 0 data will allow the viewer to render the final texture.
Diffstat (limited to 'OpenSim/Capabilities/Handlers')
-rw-r--r--OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs34
1 files changed, 29 insertions, 5 deletions
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
index ae6c44b..9b43a80 100644
--- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
+++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
@@ -163,7 +163,7 @@ namespace OpenSim.Capabilities.Handlers
163 163
164 if (texture == null) 164 if (texture == null)
165 { 165 {
166 //m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache"); 166// m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
167 167
168 // Fetch locally or remotely. Misses return a 404 168 // Fetch locally or remotely. Misses return a 404
169 texture = m_assetService.Get(textureID.ToString()); 169 texture = m_assetService.Get(textureID.ToString());
@@ -197,7 +197,7 @@ namespace OpenSim.Capabilities.Handlers
197 } 197 }
198 else // it was on the cache 198 else // it was on the cache
199 { 199 {
200 //m_log.DebugFormat("[GETTEXTURE]: texture was in the cache"); 200// m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
201 WriteTextureData(httpRequest, httpResponse, texture, format); 201 WriteTextureData(httpRequest, httpResponse, texture, format);
202 return true; 202 return true;
203 } 203 }
@@ -219,12 +219,30 @@ namespace OpenSim.Capabilities.Handlers
219 int start, end; 219 int start, end;
220 if (TryParseRange(range, out start, out end)) 220 if (TryParseRange(range, out start, out end))
221 { 221 {
222
223 // Before clamping start make sure we can satisfy it in order to avoid 222 // Before clamping start make sure we can satisfy it in order to avoid
224 // sending back the last byte instead of an error status 223 // sending back the last byte instead of an error status
225 if (start >= texture.Data.Length) 224 if (start >= texture.Data.Length)
226 { 225 {
227 response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; 226 m_log.DebugFormat(
227 "[GETTEXTURE]: Client requested range for texture {0} starting at {1} but texture has end of {2}",
228 texture.ID, start, texture.Data.Length);
229
230 // Stricly speaking, as per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, we should be sending back
231 // Requested Range Not Satisfiable (416) here. However, it appears that at least recent implementations
232 // of the Linden Lab viewer (3.2.1 and 3.3.4 and probably earlier), a viewer that has previously
233 // received a very small texture may attempt to fetch bytes from the server past the
234 // range of data that it received originally. Whether this happens appears to depend on whether
235 // the viewer's estimation of how large a request it needs to make for certain discard levels
236 // (http://wiki.secondlife.com/wiki/Image_System#Discard_Level_and_Mip_Mapping), chiefly discard
237 // level 2. If this estimate is greater than the total texture size, returning a RequestedRangeNotSatisfiable
238 // here will cause the viewer to treat the texture as bad and never display the full resolution
239 // However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
240
241// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
242// response.AddHeader("Content-Range", String.Format("bytes */{0}", texture.Data.Length));
243// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
244 response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
245 response.ContentType = texture.Metadata.ContentType;
228 } 246 }
229 else 247 else
230 { 248 {
@@ -232,12 +250,18 @@ namespace OpenSim.Capabilities.Handlers
232 start = Utils.Clamp(start, 0, end); 250 start = Utils.Clamp(start, 0, end);
233 int len = end - start + 1; 251 int len = end - start + 1;
234 252
235 //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); 253// m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
236 254
237 // Always return PartialContent, even if the range covered the entire data length 255 // Always return PartialContent, even if the range covered the entire data length
238 // We were accidentally sending back 404 before in this situation 256 // We were accidentally sending back 404 before in this situation
239 // https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the 257 // https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
240 // entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this. 258 // entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
259 //
260 // We also do not want to send back OK even if the whole range was satisfiable since this causes
261 // HTTP textures on at least Imprudence 1.4.0-beta2 to never display the final texture quality.
262// if (end > maxEnd)
263// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
264// else
241 response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; 265 response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
242 266
243 response.ContentLength = len; 267 response.ContentLength = len;