diff options
Diffstat (limited to 'OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs')
-rw-r--r-- | OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs | 34 |
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; |