diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs index ed42efe710..a76112f773 100644 --- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs @@ -101,9 +101,6 @@ namespace OpenSim.Capabilities.Handlers return responsedata; } - Hashtable headers = new Hashtable(); - responsedata["headers"] = headers; - string range = String.Empty; if (((Hashtable)request["headers"])["range"] != null) @@ -111,18 +108,18 @@ namespace OpenSim.Capabilities.Handlers else if (((Hashtable)request["headers"])["Range"] != null) range = (string)((Hashtable)request["headers"])["Range"]; + responsedata["content_type"] = "application/vnd.ll.mesh"; if (String.IsNullOrEmpty(range)) { // full mesh responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); - responsedata["content_type"] = "application/vnd.ll.mesh"; responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK; return responsedata; } // range request int start, end; - if (TryParseRange(range, out start, out end)) + if (Util.TryParseHttpRange(range, out start, out end)) { // Before clamping start make sure we can satisfy it in order to avoid // sending back the last byte instead of an error status @@ -137,8 +134,10 @@ namespace OpenSim.Capabilities.Handlers int len = end - start + 1; //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); - responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent; + Hashtable headers = new Hashtable(); headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, mesh.Data.Length); + responsedata["headers"] = headers; + responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent; byte[] d = new byte[len]; Array.Copy(mesh.Data, start, d, 0, len); @@ -149,25 +148,8 @@ namespace OpenSim.Capabilities.Handlers m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]); responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); - responsedata["content_type"] = "application/vnd.ll.mesh"; responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK; return responsedata; } - - private bool TryParseRange(string header, out int start, out int end) - { - if (header.StartsWith("bytes=")) - { - string[] rangeValues = header.Substring(6).Split('-'); - if (rangeValues.Length == 2) - { - if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end)) - return true; - } - } - - start = end = 0; - return false; - } } } \ No newline at end of file diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index 57ec2f5d00..51332bc664 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -210,7 +210,7 @@ namespace OpenSim.Capabilities.Handlers { // Range request int start, end; - if (TryParseRange(range, out start, out end)) + if (Util.TryParseHttpRange(range, out start, out end)) { // Before clamping start make sure we can satisfy it in order to avoid // sending back the last byte instead of an error status @@ -289,50 +289,6 @@ namespace OpenSim.Capabilities.Handlers // texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length); } - /// - /// Parse a range header. - /// - /// - /// As per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, - /// this obeys range headers with two values (e.g. 533-4165) and no second value (e.g. 533-). - /// Where there is no value, -1 is returned. - /// FIXME: Need to cover the case where only a second value is specified (e.g. -4165), probably by returning -1 - /// for start. - /// - /// - /// Start of the range. Undefined if this was not a number. - /// End of the range. Will be -1 if no end specified. Undefined if there was a raw string but this was not a number. - private bool TryParseRange(string header, out int start, out int end) - { - start = end = 0; - - if (header.StartsWith("bytes=")) - { - string[] rangeValues = header.Substring(6).Split('-'); - - if (rangeValues.Length == 2) - { - if (!Int32.TryParse(rangeValues[0], out start)) - return false; - - string rawEnd = rangeValues[1]; - - if (rawEnd == "") - { - end = -1; - return true; - } - else if (Int32.TryParse(rawEnd, out end)) - { - return true; - } - } - } - - start = end = 0; - return false; - } - private byte[] ConvertTextureData(AssetBase texture, string format) { m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format); diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index f8469b6667..52f9aeab2b 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -2382,6 +2382,38 @@ namespace OpenSim.Framework return sb.ToString(); } + public static bool TryParseHttpRange(string header, out int start, out int end) + { + start = end = 0; + + if (header.StartsWith("bytes=")) + { + string[] rangeValues = header.Substring(6).Split('-'); + + if (rangeValues.Length == 2) + { + string rawStart = rangeValues[0].Trim(); + if (rawStart != "" && !Int32.TryParse(rawStart, out start)) + return false; + + if (start < 0) + return false; + + string rawEnd = rangeValues[1].Trim(); + if (rawEnd == "") + { + end = -1; + return true; + } + else if (Int32.TryParse(rawEnd, out end)) + return end > 0; + } + } + + start = end = 0; + return false; + } + /// /// Used to trigger an early library load on Windows systems. ///