diff options
author | teravus | 2012-11-09 23:55:30 -0500 |
---|---|---|
committer | teravus | 2012-11-09 23:55:30 -0500 |
commit | cda127e30f0049cda21137363e4d759fd7fd4959 (patch) | |
tree | 426814e4aa4c63eb5bd8c2f920bfa9aedeecd930 /OpenSim/Capabilities/Handlers/GetMesh | |
parent | This implements the Caps throttler. After some testing, the system seemed ... (diff) | |
download | opensim-SC-cda127e30f0049cda21137363e4d759fd7fd4959.zip opensim-SC-cda127e30f0049cda21137363e4d759fd7fd4959.tar.gz opensim-SC-cda127e30f0049cda21137363e4d759fd7fd4959.tar.bz2 opensim-SC-cda127e30f0049cda21137363e4d759fd7fd4959.tar.xz |
* 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.
Diffstat (limited to 'OpenSim/Capabilities/Handlers/GetMesh')
-rw-r--r-- | OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs | 131 |
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 |