aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Capabilities/Handlers/GetMesh
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Capabilities/Handlers/GetMesh')
-rw-r--r--OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs162
1 files changed, 157 insertions, 5 deletions
diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs
index 720640e..ec574a3 100644
--- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs
+++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs
@@ -45,16 +45,54 @@ 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 ret["int_lod"] = 0;
68 string MeshStr = (string)request["mesh_id"];
69
70
71 //m_log.DebugFormat("[GETMESH]: called {0}", MeshStr);
72
73 if (m_assetService == null)
74 {
75 m_log.Error("[GETMESH]: Cannot fetch mesh " + MeshStr + " without an asset service");
76 }
77
78 UUID meshID;
79 if (!String.IsNullOrEmpty(MeshStr) && UUID.TryParse(MeshStr, out meshID))
80 {
81 // m_log.DebugFormat("[GETMESH]: Received request for mesh id {0}", meshID);
57 82
83
84 ret = ProcessGetMesh(request, UUID.Zero, null);
85
86
87 }
88 else
89 {
90 m_log.Warn("[GETMESH]: Failed to parse a mesh_id from GetMesh request: " + (string)request["uri"]);
91 }
92
93
94 return ret;
95 }
58 public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap) 96 public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
59 { 97 {
60 Hashtable responsedata = new Hashtable(); 98 Hashtable responsedata = new Hashtable();
@@ -62,6 +100,9 @@ namespace OpenSim.Capabilities.Handlers
62 responsedata["content_type"] = "text/plain"; 100 responsedata["content_type"] = "text/plain";
63 responsedata["keepalive"] = false; 101 responsedata["keepalive"] = false;
64 responsedata["str_response_string"] = "Request wasn't what was expected"; 102 responsedata["str_response_string"] = "Request wasn't what was expected";
103 responsedata["reusecontext"] = false;
104 responsedata["int_lod"] = 0;
105 responsedata["int_bytes"] = 0;
65 106
66 string meshStr = string.Empty; 107 string meshStr = string.Empty;
67 108
@@ -77,6 +118,7 @@ namespace OpenSim.Capabilities.Handlers
77 responsedata["content_type"] = "text/plain"; 118 responsedata["content_type"] = "text/plain";
78 responsedata["keepalive"] = false; 119 responsedata["keepalive"] = false;
79 responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh."; 120 responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh.";
121 responsedata["reusecontext"] = false;
80 return responsedata; 122 return responsedata;
81 } 123 }
82 124
@@ -86,9 +128,100 @@ namespace OpenSim.Capabilities.Handlers
86 { 128 {
87 if (mesh.Type == (SByte)AssetType.Mesh) 129 if (mesh.Type == (SByte)AssetType.Mesh)
88 { 130 {
89 responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); 131
90 responsedata["content_type"] = "application/vnd.ll.mesh"; 132 Hashtable headers = new Hashtable();
91 responsedata["int_response_code"] = 200; 133 responsedata["headers"] = headers;
134
135 string range = String.Empty;
136
137 if (((Hashtable)request["headers"])["range"] != null)
138 range = (string)((Hashtable)request["headers"])["range"];
139
140 else if (((Hashtable)request["headers"])["Range"] != null)
141 range = (string)((Hashtable)request["headers"])["Range"];
142
143 if (!String.IsNullOrEmpty(range)) // Mesh Asset LOD // Physics
144 {
145 // Range request
146 int start, end;
147 if (TryParseRange(range, out start, out end))
148 {
149 // Before clamping start make sure we can satisfy it in order to avoid
150 // sending back the last byte instead of an error status
151 if (start >= mesh.Data.Length)
152 {
153 responsedata["int_response_code"] = 404; //501; //410; //404;
154 responsedata["content_type"] = "text/plain";
155 responsedata["keepalive"] = false;
156 responsedata["str_response_string"] = "This range doesnt exist.";
157 responsedata["reusecontext"] = false;
158 responsedata["int_lod"] = 3;
159 return responsedata;
160 }
161 else
162 {
163 end = Utils.Clamp(end, 0, mesh.Data.Length - 1);
164 start = Utils.Clamp(start, 0, end);
165 int len = end - start + 1;
166
167 //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
168
169 if (start > 20000)
170 {
171 responsedata["int_lod"] = 3;
172 }
173 else if (start < 4097)
174 {
175 responsedata["int_lod"] = 1;
176 }
177 else
178 {
179 responsedata["int_lod"] = 2;
180 }
181
182
183 if (start == 0 && len == mesh.Data.Length) // well redudante maybe
184 {
185 responsedata["int_response_code"] = (int) System.Net.HttpStatusCode.OK;
186 responsedata["bin_response_data"] = mesh.Data;
187 responsedata["int_bytes"] = mesh.Data.Length;
188 responsedata["reusecontext"] = false;
189 responsedata["int_lod"] = 3;
190
191 }
192 else
193 {
194 responsedata["int_response_code"] =
195 (int) System.Net.HttpStatusCode.PartialContent;
196 headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end,
197 mesh.Data.Length);
198
199 byte[] d = new byte[len];
200 Array.Copy(mesh.Data, start, d, 0, len);
201 responsedata["bin_response_data"] = d;
202 responsedata["int_bytes"] = len;
203 responsedata["reusecontext"] = false;
204 }
205 }
206 }
207 else
208 {
209 m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]);
210 responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
211 responsedata["content_type"] = "application/vnd.ll.mesh";
212 responsedata["int_response_code"] = 200;
213 responsedata["reusecontext"] = false;
214 responsedata["int_lod"] = 3;
215 }
216 }
217 else
218 {
219 responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
220 responsedata["content_type"] = "application/vnd.ll.mesh";
221 responsedata["int_response_code"] = 200;
222 responsedata["reusecontext"] = false;
223 responsedata["int_lod"] = 3;
224 }
92 } 225 }
93 // Optionally add additional mesh types here 226 // Optionally add additional mesh types here
94 else 227 else
@@ -97,6 +230,8 @@ namespace OpenSim.Capabilities.Handlers
97 responsedata["content_type"] = "text/plain"; 230 responsedata["content_type"] = "text/plain";
98 responsedata["keepalive"] = false; 231 responsedata["keepalive"] = false;
99 responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; 232 responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
233 responsedata["reusecontext"] = false;
234 responsedata["int_lod"] = 1;
100 return responsedata; 235 return responsedata;
101 } 236 }
102 } 237 }
@@ -106,11 +241,28 @@ namespace OpenSim.Capabilities.Handlers
106 responsedata["content_type"] = "text/plain"; 241 responsedata["content_type"] = "text/plain";
107 responsedata["keepalive"] = false; 242 responsedata["keepalive"] = false;
108 responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; 243 responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
244 responsedata["reusecontext"] = false;
245 responsedata["int_lod"] = 0;
109 return responsedata; 246 return responsedata;
110 } 247 }
111 } 248 }
112 249
113 return responsedata; 250 return responsedata;
114 } 251 }
252 private bool TryParseRange(string header, out int start, out int end)
253 {
254 if (header.StartsWith("bytes="))
255 {
256 string[] rangeValues = header.Substring(6).Split('-');
257 if (rangeValues.Length == 2)
258 {
259 if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end))
260 return true;
261 }
262 }
263
264 start = end = 0;
265 return false;
266 }
115 } 267 }
116} \ No newline at end of file 268} \ No newline at end of file