From cda127e30f0049cda21137363e4d759fd7fd4959 Mon Sep 17 00:00:00 2001 From: teravus Date: Fri, 9 Nov 2012 23:55:30 -0500 Subject: * Prep work switching the GetMeshModule over to a poll service. * This still has the image throttler in it.. as is... so it's not suitable for live yet.... The throttler keeps track of the task throttle but doesn't balance the UDP throttle yet. --- .../Handlers/GetMesh/GetMeshHandler.cs | 131 ++++++++++++++++++++- 1 file changed, 126 insertions(+), 5 deletions(-) (limited to 'OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs') diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs index 720640e..d29bed9 100644 --- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs @@ -45,16 +45,53 @@ namespace OpenSim.Capabilities.Handlers { public class GetMeshHandler { -// private static readonly ILog m_log = -// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private IAssetService m_assetService; + public const string DefaultFormat = "vnd.ll.mesh"; + public GetMeshHandler(IAssetService assService) { m_assetService = assService; } + public Hashtable Handle(Hashtable request) + { + Hashtable ret = new Hashtable(); + ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; + ret["content_type"] = "text/plain"; + ret["keepalive"] = false; + ret["reusecontext"] = false; + ret["int_bytes"] = 0; + string MeshStr = (string)request["mesh_id"]; + + + //m_log.DebugFormat("[GETMESH]: called {0}", MeshStr); + + if (m_assetService == null) + { + m_log.Error("[GETMESH]: Cannot fetch mesh " + MeshStr + " without an asset service"); + } + + UUID meshID; + if (!String.IsNullOrEmpty(MeshStr) && UUID.TryParse(MeshStr, out meshID)) + { + // m_log.DebugFormat("[GETMESH]: Received request for mesh id {0}", meshID); + + ret = ProcessGetMesh(request, UUID.Zero, null); + + + } + else + { + m_log.Warn("[GETMESH]: Failed to parse a mesh_id from GetMesh request: " + (string)request["uri"]); + } + + + return ret; + } public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap) { Hashtable responsedata = new Hashtable(); @@ -86,9 +123,78 @@ namespace OpenSim.Capabilities.Handlers { if (mesh.Type == (SByte)AssetType.Mesh) { - responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); - responsedata["content_type"] = "application/vnd.ll.mesh"; - responsedata["int_response_code"] = 200; + + Hashtable headers = new Hashtable(); + responsedata["headers"] = headers; + + string range = String.Empty; + + if (((Hashtable)request["headers"])["range"] != null) + range = (string)((Hashtable)request["headers"])["range"]; + + else if (((Hashtable)request["headers"])["Range"] != null) + range = (string)((Hashtable)request["headers"])["Range"]; + + if (!String.IsNullOrEmpty(range)) // Mesh Asset LOD // Physics + { + // Range request + int start, end; + if (TryParseRange(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 + if (start >= mesh.Data.Length) + { + responsedata["int_response_code"] = 404; //501; //410; //404; + responsedata["content_type"] = "text/plain"; + responsedata["keepalive"] = false; + responsedata["str_response_string"] = "This range doesnt exist."; + return responsedata; + } + else + { + end = Utils.Clamp(end, 0, mesh.Data.Length - 1); + start = Utils.Clamp(start, 0, end); + int len = end - start + 1; + + //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); + + + + if (start == 0 && len == mesh.Data.Length) // well redudante maybe + { + responsedata["int_response_code"] = (int) System.Net.HttpStatusCode.OK; + responsedata["bin_response_data"] = mesh.Data; + responsedata["int_bytes"] = mesh.Data.Length; + } + else + { + responsedata["int_response_code"] = + (int) System.Net.HttpStatusCode.PartialContent; + headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, + mesh.Data.Length); + + byte[] d = new byte[len]; + Array.Copy(mesh.Data, start, d, 0, len); + responsedata["bin_response_data"] = d; + responsedata["int_bytes"] = len; + } + } + } + else + { + 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"] = 200; + } + } + else + { + responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); + responsedata["content_type"] = "application/vnd.ll.mesh"; + responsedata["int_response_code"] = 200; + } } // Optionally add additional mesh types here else @@ -112,5 +218,20 @@ namespace OpenSim.Capabilities.Handlers 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 -- cgit v1.1 From 619c39e5144f15aca129d6d999bcc5c34133ee64 Mon Sep 17 00:00:00 2001 From: teravus Date: Thu, 15 Nov 2012 09:44:02 -0500 Subject: * Fixes mesh loading issues in last commit. --- OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs') diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs index d29bed9..da59294 100644 --- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs @@ -99,6 +99,7 @@ namespace OpenSim.Capabilities.Handlers responsedata["content_type"] = "text/plain"; responsedata["keepalive"] = false; responsedata["str_response_string"] = "Request wasn't what was expected"; + responsedata["reusecontext"] = false; string meshStr = string.Empty; @@ -114,6 +115,7 @@ namespace OpenSim.Capabilities.Handlers responsedata["content_type"] = "text/plain"; responsedata["keepalive"] = false; responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh."; + responsedata["reusecontext"] = false; return responsedata; } @@ -149,6 +151,7 @@ namespace OpenSim.Capabilities.Handlers responsedata["content_type"] = "text/plain"; responsedata["keepalive"] = false; responsedata["str_response_string"] = "This range doesnt exist."; + responsedata["reusecontext"] = false; return responsedata; } else @@ -166,6 +169,7 @@ namespace OpenSim.Capabilities.Handlers responsedata["int_response_code"] = (int) System.Net.HttpStatusCode.OK; responsedata["bin_response_data"] = mesh.Data; responsedata["int_bytes"] = mesh.Data.Length; + responsedata["reusecontext"] = false; } else { @@ -178,6 +182,7 @@ namespace OpenSim.Capabilities.Handlers Array.Copy(mesh.Data, start, d, 0, len); responsedata["bin_response_data"] = d; responsedata["int_bytes"] = len; + responsedata["reusecontext"] = false; } } } @@ -187,6 +192,7 @@ namespace OpenSim.Capabilities.Handlers responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); responsedata["content_type"] = "application/vnd.ll.mesh"; responsedata["int_response_code"] = 200; + responsedata["reusecontext"] = false; } } else @@ -194,6 +200,7 @@ namespace OpenSim.Capabilities.Handlers responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); responsedata["content_type"] = "application/vnd.ll.mesh"; responsedata["int_response_code"] = 200; + responsedata["reusecontext"] = false; } } // Optionally add additional mesh types here @@ -203,6 +210,7 @@ namespace OpenSim.Capabilities.Handlers responsedata["content_type"] = "text/plain"; responsedata["keepalive"] = false; responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; + responsedata["reusecontext"] = false; return responsedata; } } @@ -212,6 +220,7 @@ namespace OpenSim.Capabilities.Handlers responsedata["content_type"] = "text/plain"; responsedata["keepalive"] = false; responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; + responsedata["reusecontext"] = false; return responsedata; } } -- cgit v1.1