aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Capabilities
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Capabilities')
-rw-r--r--OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs131
1 files changed, 126 insertions, 5 deletions
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
45{ 45{
46 public class GetMeshHandler 46 public class GetMeshHandler
47 { 47 {
48// private static readonly ILog m_log = 48 private static readonly ILog m_log =
49// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 50
51 private IAssetService m_assetService; 51 private IAssetService m_assetService;
52 52
53 public const string DefaultFormat = "vnd.ll.mesh";
54
53 public GetMeshHandler(IAssetService assService) 55 public GetMeshHandler(IAssetService assService)
54 { 56 {
55 m_assetService = assService; 57 m_assetService = assService;
56 } 58 }
59 public Hashtable Handle(Hashtable request)
60 {
61 Hashtable ret = new Hashtable();
62 ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
63 ret["content_type"] = "text/plain";
64 ret["keepalive"] = false;
65 ret["reusecontext"] = false;
66 ret["int_bytes"] = 0;
67 string MeshStr = (string)request["mesh_id"];
68
69
70 //m_log.DebugFormat("[GETMESH]: called {0}", MeshStr);
71
72 if (m_assetService == null)
73 {
74 m_log.Error("[GETMESH]: Cannot fetch mesh " + MeshStr + " without an asset service");
75 }
76
77 UUID meshID;
78 if (!String.IsNullOrEmpty(MeshStr) && UUID.TryParse(MeshStr, out meshID))
79 {
80 // m_log.DebugFormat("[GETMESH]: Received request for mesh id {0}", meshID);
57 81
82
83 ret = ProcessGetMesh(request, UUID.Zero, null);
84
85
86 }
87 else
88 {
89 m_log.Warn("[GETMESH]: Failed to parse a mesh_id from GetMesh request: " + (string)request["uri"]);
90 }
91
92
93 return ret;
94 }
58 public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap) 95 public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
59 { 96 {
60 Hashtable responsedata = new Hashtable(); 97 Hashtable responsedata = new Hashtable();
@@ -86,9 +123,78 @@ namespace OpenSim.Capabilities.Handlers
86 { 123 {
87 if (mesh.Type == (SByte)AssetType.Mesh) 124 if (mesh.Type == (SByte)AssetType.Mesh)
88 { 125 {
89 responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); 126
90 responsedata["content_type"] = "application/vnd.ll.mesh"; 127 Hashtable headers = new Hashtable();
91 responsedata["int_response_code"] = 200; 128 responsedata["headers"] = headers;
129
130 string range = String.Empty;
131
132 if (((Hashtable)request["headers"])["range"] != null)
133 range = (string)((Hashtable)request["headers"])["range"];
134
135 else if (((Hashtable)request["headers"])["Range"] != null)
136 range = (string)((Hashtable)request["headers"])["Range"];
137
138 if (!String.IsNullOrEmpty(range)) // Mesh Asset LOD // Physics
139 {
140 // Range request
141 int start, end;
142 if (TryParseRange(range, out start, out end))
143 {
144 // Before clamping start make sure we can satisfy it in order to avoid
145 // sending back the last byte instead of an error status
146 if (start >= mesh.Data.Length)
147 {
148 responsedata["int_response_code"] = 404; //501; //410; //404;
149 responsedata["content_type"] = "text/plain";
150 responsedata["keepalive"] = false;
151 responsedata["str_response_string"] = "This range doesnt exist.";
152 return responsedata;
153 }
154 else
155 {
156 end = Utils.Clamp(end, 0, mesh.Data.Length - 1);
157 start = Utils.Clamp(start, 0, end);
158 int len = end - start + 1;
159
160 //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
161
162
163
164 if (start == 0 && len == mesh.Data.Length) // well redudante maybe
165 {
166 responsedata["int_response_code"] = (int) System.Net.HttpStatusCode.OK;
167 responsedata["bin_response_data"] = mesh.Data;
168 responsedata["int_bytes"] = mesh.Data.Length;
169 }
170 else
171 {
172 responsedata["int_response_code"] =
173 (int) System.Net.HttpStatusCode.PartialContent;
174 headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end,
175 mesh.Data.Length);
176
177 byte[] d = new byte[len];
178 Array.Copy(mesh.Data, start, d, 0, len);
179 responsedata["bin_response_data"] = d;
180 responsedata["int_bytes"] = len;
181 }
182 }
183 }
184 else
185 {
186 m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]);
187 responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
188 responsedata["content_type"] = "application/vnd.ll.mesh";
189 responsedata["int_response_code"] = 200;
190 }
191 }
192 else
193 {
194 responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
195 responsedata["content_type"] = "application/vnd.ll.mesh";
196 responsedata["int_response_code"] = 200;
197 }
92 } 198 }
93 // Optionally add additional mesh types here 199 // Optionally add additional mesh types here
94 else 200 else
@@ -112,5 +218,20 @@ namespace OpenSim.Capabilities.Handlers
112 218
113 return responsedata; 219 return responsedata;
114 } 220 }
221 private bool TryParseRange(string header, out int start, out int end)
222 {
223 if (header.StartsWith("bytes="))
224 {
225 string[] rangeValues = header.Substring(6).Split('-');
226 if (rangeValues.Length == 2)
227 {
228 if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end))
229 return true;
230 }
231 }
232
233 start = end = 0;
234 return false;
235 }
115 } 236 }
116} \ No newline at end of file 237} \ No newline at end of file