29 using System.Collections;
30 using System.Collections.Specialized;
31 using System.Reflection;
37 using OpenMetaverse.StructuredData;
38 using OpenSim.Framework;
39 using OpenSim.Framework.Servers;
40 using OpenSim.Framework.Servers.HttpServer;
41 using OpenSim.Services.Interfaces;
47 namespace OpenSim.Capabilities.Handlers
51 private static readonly ILog m_log =
52 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56 public const string DefaultFormat =
"vnd.ll.mesh";
60 m_assetService = assService;
62 public Hashtable
Handle(Hashtable request)
64 Hashtable ret =
new Hashtable();
65 ret[
"int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
66 ret[
"content_type"] =
"text/plain";
67 ret[
"keepalive"] =
false;
68 ret[
"reusecontext"] =
false;
71 string MeshStr = (
string)request[
"mesh_id"];
76 if (m_assetService == null)
78 m_log.Error(
"[GETMESH]: Cannot fetch mesh " + MeshStr +
" without an asset service");
82 if (!String.IsNullOrEmpty(MeshStr) && UUID.TryParse(MeshStr, out meshID))
87 ret = ProcessGetMesh(request, UUID.Zero, null);
93 m_log.Warn(
"[GETMESH]: Failed to parse a mesh_id from GetMesh request: " + (string)request[
"uri"]);
101 Hashtable responsedata =
new Hashtable();
102 responsedata[
"int_response_code"] = 400;
103 responsedata[
"content_type"] =
"text/plain";
104 responsedata[
"keepalive"] =
false;
105 responsedata[
"str_response_string"] =
"Request wasn't what was expected";
106 responsedata[
"reusecontext"] =
false;
107 responsedata[
"int_lod"] = 0;
108 responsedata[
"int_bytes"] = 0;
110 string meshStr = string.Empty;
112 if (request.ContainsKey(
"mesh_id"))
113 meshStr = request[
"mesh_id"].ToString();
115 UUID meshID = UUID.Zero;
116 if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID))
118 if (m_assetService == null)
120 responsedata[
"int_response_code"] = 404;
121 responsedata[
"content_type"] =
"text/plain";
122 responsedata[
"keepalive"] =
false;
123 responsedata[
"str_response_string"] =
"The asset service is unavailable. So is your mesh.";
124 responsedata[
"reusecontext"] =
false;
128 AssetBase mesh = m_assetService.Get(meshID.ToString());
132 if (mesh.
Type == (SByte)AssetType.Mesh)
135 Hashtable headers =
new Hashtable();
136 responsedata[
"headers"] = headers;
138 string range = String.Empty;
140 if (((Hashtable)request[
"headers"])[
"range"] != null)
141 range = (string)((Hashtable)request[
"headers"])[
"range"];
143 else if (((Hashtable)request[
"headers"])[
"Range"] != null)
144 range = (
string)((Hashtable)request[
"headers"])[
"Range"];
146 if (!String.IsNullOrEmpty(range))
150 if (TryParseRange(range, out start, out end))
154 if (start >= mesh.
Data.Length)
156 responsedata[
"int_response_code"] = 404;
157 responsedata[
"content_type"] =
"text/plain";
158 responsedata[
"keepalive"] =
false;
159 responsedata[
"str_response_string"] =
"This range doesnt exist.";
160 responsedata[
"reusecontext"] =
false;
161 responsedata[
"int_lod"] = 3;
166 end = Utils.Clamp(end, 0, mesh.Data.Length - 1);
167 start = Utils.Clamp(start, 0, end);
168 int len = end - start + 1;
174 responsedata[
"int_lod"] = 3;
176 else if (start < 4097)
178 responsedata[
"int_lod"] = 1;
182 responsedata[
"int_lod"] = 2;
186 if (start == 0 && len == mesh.
Data.Length)
188 responsedata[
"int_response_code"] = (int)System.Net.HttpStatusCode.OK;
189 responsedata[
"bin_response_data"] = mesh.
Data;
190 responsedata[
"int_bytes"] = mesh.
Data.Length;
191 responsedata[
"reusecontext"] =
false;
192 responsedata[
"int_lod"] = 3;
197 responsedata[
"int_response_code"] =
198 (int)System.Net.HttpStatusCode.PartialContent;
199 headers[
"Content-Range"] = String.Format(
"bytes {0}-{1}/{2}", start, end,
202 byte[] d =
new byte[len];
203 Array.Copy(mesh.Data, start, d, 0, len);
204 responsedata[
"bin_response_data"] = d;
205 responsedata[
"int_bytes"] = len;
206 responsedata[
"reusecontext"] =
false;
212 m_log.Warn(
"[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request[
"uri"]);
213 responsedata[
"str_response_string"] = Convert.ToBase64String(mesh.Data);
214 responsedata[
"content_type"] =
"application/vnd.ll.mesh";
215 responsedata[
"int_response_code"] = 200;
216 responsedata[
"reusecontext"] =
false;
217 responsedata[
"int_lod"] = 3;
222 responsedata[
"str_response_string"] = Convert.ToBase64String(mesh.Data);
223 responsedata[
"content_type"] =
"application/vnd.ll.mesh";
224 responsedata[
"int_response_code"] = 200;
225 responsedata[
"reusecontext"] =
false;
226 responsedata[
"int_lod"] = 3;
232 responsedata[
"int_response_code"] = 404;
233 responsedata[
"content_type"] =
"text/plain";
234 responsedata[
"keepalive"] =
false;
235 responsedata[
"str_response_string"] =
"Unfortunately, this asset isn't a mesh.";
236 responsedata[
"reusecontext"] =
false;
237 responsedata[
"int_lod"] = 1;
243 responsedata[
"int_response_code"] = 404;
244 responsedata[
"content_type"] =
"text/plain";
245 responsedata[
"keepalive"] =
false;
246 responsedata[
"str_response_string"] =
"Your Mesh wasn't found. Sorry!";
247 responsedata[
"reusecontext"] =
false;
248 responsedata[
"int_lod"] = 0;
255 private bool TryParseRange(
string header, out
int start, out
int end)
257 if (header.StartsWith(
"bytes="))
259 string[] rangeValues = header.Substring(6).Split(
'-');
260 if (rangeValues.Length == 2)
262 if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end))
Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
OpenSim.Framework.Capabilities.Caps Caps
Hashtable Handle(Hashtable request)
sbyte Type
(sbyte) AssetType enum
Asset class. All Assets are reference by this class or a class derived from this class ...
OpenSim.Framework.Capabilities.Caps Caps
GetMeshHandler(IAssetService assService)