diff options
Diffstat (limited to 'OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs')
-rw-r--r-- | OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs | 185 |
1 files changed, 68 insertions, 117 deletions
diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs index 506f9d2..ed42efe 100644 --- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs | |||
@@ -41,9 +41,6 @@ using OpenSim.Framework.Servers.HttpServer; | |||
41 | using OpenSim.Services.Interfaces; | 41 | using OpenSim.Services.Interfaces; |
42 | using Caps = OpenSim.Framework.Capabilities.Caps; | 42 | using Caps = OpenSim.Framework.Capabilities.Caps; |
43 | 43 | ||
44 | |||
45 | |||
46 | |||
47 | namespace OpenSim.Capabilities.Handlers | 44 | namespace OpenSim.Capabilities.Handlers |
48 | { | 45 | { |
49 | public class GetMeshHandler | 46 | public class GetMeshHandler |
@@ -61,145 +58,99 @@ namespace OpenSim.Capabilities.Handlers | |||
61 | } | 58 | } |
62 | public Hashtable Handle(Hashtable request) | 59 | public Hashtable Handle(Hashtable request) |
63 | { | 60 | { |
64 | Hashtable ret = new Hashtable(); | 61 | return ProcessGetMesh(request, UUID.Zero, null); ; |
65 | ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; | 62 | } |
66 | ret["content_type"] = "text/plain"; | ||
67 | ret["int_bytes"] = 0; | ||
68 | string MeshStr = (string)request["mesh_id"]; | ||
69 | |||
70 | |||
71 | //m_log.DebugFormat("[GETMESH]: called {0}", MeshStr); | ||
72 | 63 | ||
64 | public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap) | ||
65 | { | ||
66 | Hashtable responsedata = new Hashtable(); | ||
73 | if (m_assetService == null) | 67 | if (m_assetService == null) |
74 | { | 68 | { |
75 | m_log.Error("[GETMESH]: Cannot fetch mesh " + MeshStr + " without an asset service"); | 69 | responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.ServiceUnavailable; |
76 | ret["keepalive"] = false; | 70 | responsedata["str_response_string"] = "The asset service is unavailable"; |
77 | return ret; | 71 | responsedata["keepalive"] = false; |
72 | return responsedata; | ||
78 | } | 73 | } |
79 | 74 | ||
80 | UUID meshID; | 75 | responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest; |
81 | if (!String.IsNullOrEmpty(MeshStr) && UUID.TryParse(MeshStr, out meshID)) | 76 | responsedata["content_type"] = "text/plain"; |
82 | { | 77 | responsedata["int_bytes"] = 0; |
83 | // m_log.DebugFormat("[GETMESH]: Received request for mesh id {0}", meshID); | ||
84 | 78 | ||
79 | string meshStr = string.Empty; | ||
80 | if (request.ContainsKey("mesh_id")) | ||
81 | meshStr = request["mesh_id"].ToString(); | ||
85 | 82 | ||
86 | ret = ProcessGetMesh(request, UUID.Zero, null); | 83 | if (String.IsNullOrEmpty(meshStr)) |
84 | return responsedata; | ||
87 | 85 | ||
86 | UUID meshID = UUID.Zero; | ||
87 | if(!UUID.TryParse(meshStr, out meshID)) | ||
88 | return responsedata; | ||
88 | 89 | ||
90 | AssetBase mesh = m_assetService.Get(meshID.ToString()); | ||
91 | if(mesh == null) | ||
92 | { | ||
93 | responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; | ||
94 | responsedata["str_response_string"] = "Mesh not found."; | ||
95 | return responsedata; | ||
89 | } | 96 | } |
90 | else | 97 | |
98 | if (mesh.Type != (SByte)AssetType.Mesh) | ||
91 | { | 99 | { |
92 | m_log.Warn("[GETMESH]: Failed to parse a mesh_id from GetMesh request: " + (string)request["uri"]); | 100 | responsedata["str_response_string"] = "Asset isn't a mesh."; |
101 | return responsedata; | ||
93 | } | 102 | } |
94 | 103 | ||
104 | Hashtable headers = new Hashtable(); | ||
105 | responsedata["headers"] = headers; | ||
95 | 106 | ||
96 | return ret; | 107 | string range = String.Empty; |
97 | } | ||
98 | public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap) | ||
99 | { | ||
100 | Hashtable responsedata = new Hashtable(); | ||
101 | responsedata["int_response_code"] = 400; //501; //410; //404; | ||
102 | responsedata["content_type"] = "text/plain"; | ||
103 | responsedata["int_bytes"] = 0; | ||
104 | 108 | ||
105 | string meshStr = string.Empty; | 109 | if (((Hashtable)request["headers"])["range"] != null) |
110 | range = (string)((Hashtable)request["headers"])["range"]; | ||
111 | else if (((Hashtable)request["headers"])["Range"] != null) | ||
112 | range = (string)((Hashtable)request["headers"])["Range"]; | ||
106 | 113 | ||
107 | if (request.ContainsKey("mesh_id")) | 114 | if (String.IsNullOrEmpty(range)) |
108 | meshStr = request["mesh_id"].ToString(); | 115 | { |
116 | // full mesh | ||
117 | responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); | ||
118 | responsedata["content_type"] = "application/vnd.ll.mesh"; | ||
119 | responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK; | ||
120 | return responsedata; | ||
121 | } | ||
109 | 122 | ||
110 | UUID meshID = UUID.Zero; | 123 | // range request |
111 | if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID)) | 124 | int start, end; |
125 | if (TryParseRange(range, out start, out end)) | ||
112 | { | 126 | { |
113 | if (m_assetService == null) | 127 | // Before clamping start make sure we can satisfy it in order to avoid |
128 | // sending back the last byte instead of an error status | ||
129 | if (start >= mesh.Data.Length) | ||
114 | { | 130 | { |
115 | responsedata["int_response_code"] = 404; //501; //410; //404; | 131 | responsedata["str_response_string"] = "This range doesnt exist."; |
116 | responsedata["keepalive"] = false; | ||
117 | responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh."; | ||
118 | return responsedata; | 132 | return responsedata; |
119 | } | 133 | } |
120 | 134 | ||
121 | AssetBase mesh = m_assetService.Get(meshID.ToString()); | 135 | end = Utils.Clamp(end, 0, mesh.Data.Length - 1); |
136 | start = Utils.Clamp(start, 0, end); | ||
137 | int len = end - start + 1; | ||
122 | 138 | ||
123 | if (mesh != null) | 139 | //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); |
124 | { | 140 | responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent; |
125 | if (mesh.Type == (SByte)AssetType.Mesh) | 141 | headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, mesh.Data.Length); |
126 | { | 142 | |
127 | Hashtable headers = new Hashtable(); | 143 | byte[] d = new byte[len]; |
128 | responsedata["headers"] = headers; | 144 | Array.Copy(mesh.Data, start, d, 0, len); |
129 | 145 | responsedata["bin_response_data"] = d; | |
130 | string range = String.Empty; | 146 | responsedata["int_bytes"] = len; |
131 | 147 | return responsedata; | |
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["str_response_string"] = "This range doesnt exist."; | ||
151 | return responsedata; | ||
152 | } | ||
153 | else | ||
154 | { | ||
155 | end = Utils.Clamp(end, 0, mesh.Data.Length - 1); | ||
156 | start = Utils.Clamp(start, 0, end); | ||
157 | int len = end - start + 1; | ||
158 | |||
159 | //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); | ||
160 | responsedata["int_response_code"] = | ||
161 | (int)System.Net.HttpStatusCode.PartialContent; | ||
162 | headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, mesh.Data.Length); | ||
163 | |||
164 | byte[] d = new byte[len]; | ||
165 | Array.Copy(mesh.Data, start, d, 0, len); | ||
166 | responsedata["bin_response_data"] = d; | ||
167 | responsedata["int_bytes"] = len; | ||
168 | } | ||
169 | } | ||
170 | else | ||
171 | { | ||
172 | m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]); | ||
173 | responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); | ||
174 | responsedata["content_type"] = "application/vnd.ll.mesh"; | ||
175 | responsedata["int_response_code"] = 200; | ||
176 | } | ||
177 | } | ||
178 | else | ||
179 | { | ||
180 | responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); | ||
181 | responsedata["content_type"] = "application/vnd.ll.mesh"; | ||
182 | responsedata["int_response_code"] = 200; | ||
183 | } | ||
184 | } | ||
185 | // Optionally add additional mesh types here | ||
186 | else | ||
187 | { | ||
188 | responsedata["int_response_code"] = 404; //501; //410; //404; | ||
189 | responsedata["content_type"] = "text/plain"; | ||
190 | responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; | ||
191 | return responsedata; | ||
192 | } | ||
193 | } | ||
194 | else | ||
195 | { | ||
196 | responsedata["int_response_code"] = 404; //501; //410; //404; | ||
197 | responsedata["content_type"] = "text/plain"; | ||
198 | responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; | ||
199 | return responsedata; | ||
200 | } | ||
201 | } | 148 | } |
202 | 149 | ||
150 | m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]); | ||
151 | responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); | ||
152 | responsedata["content_type"] = "application/vnd.ll.mesh"; | ||
153 | responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK; | ||
203 | return responsedata; | 154 | return responsedata; |
204 | } | 155 | } |
205 | 156 | ||