diff options
Diffstat (limited to 'OpenSim/Grid/AssetInventoryServer/Plugins/ReferenceFrontendPlugin.cs')
-rw-r--r-- | OpenSim/Grid/AssetInventoryServer/Plugins/ReferenceFrontendPlugin.cs | 329 |
1 files changed, 217 insertions, 112 deletions
diff --git a/OpenSim/Grid/AssetInventoryServer/Plugins/ReferenceFrontendPlugin.cs b/OpenSim/Grid/AssetInventoryServer/Plugins/ReferenceFrontendPlugin.cs index fddc385..d1ea201 100644 --- a/OpenSim/Grid/AssetInventoryServer/Plugins/ReferenceFrontendPlugin.cs +++ b/OpenSim/Grid/AssetInventoryServer/Plugins/ReferenceFrontendPlugin.cs | |||
@@ -28,6 +28,7 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | using System; | 30 | using System; |
31 | using System.IO; | ||
31 | using System.Collections.Generic; | 32 | using System.Collections.Generic; |
32 | using System.Net; | 33 | using System.Net; |
33 | using System.Xml; | 34 | using System.Xml; |
@@ -35,12 +36,13 @@ using OpenMetaverse; | |||
35 | using OpenMetaverse.StructuredData; | 36 | using OpenMetaverse.StructuredData; |
36 | using HttpServer; | 37 | using HttpServer; |
37 | using OpenSim.Framework; | 38 | using OpenSim.Framework; |
39 | using OpenSim.Framework.Servers; | ||
38 | 40 | ||
39 | namespace OpenSim.Grid.AssetInventoryServer.Plugins | 41 | namespace OpenSim.Grid.AssetInventoryServer.Plugins |
40 | { | 42 | { |
41 | public class ReferenceFrontendPlugin : IAssetInventoryServerPlugin | 43 | public class ReferenceFrontendPlugin : IAssetInventoryServerPlugin |
42 | { | 44 | { |
43 | AssetInventoryServer server; | 45 | AssetInventoryServer m_server; |
44 | 46 | ||
45 | public ReferenceFrontendPlugin() | 47 | public ReferenceFrontendPlugin() |
46 | { | 48 | { |
@@ -50,18 +52,16 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins | |||
50 | 52 | ||
51 | public void Initialise(AssetInventoryServer server) | 53 | public void Initialise(AssetInventoryServer server) |
52 | { | 54 | { |
53 | this.server = server; | 55 | m_server = server; |
54 | 56 | ||
55 | // Asset metadata request | 57 | // Asset metadata request |
56 | server.HttpServer.AddHandler("get", null, @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/metadata", | 58 | m_server.HttpServer.AddStreamHandler(new MetadataRequestHandler(server)); |
57 | MetadataRequestHandler); | ||
58 | 59 | ||
59 | // Asset data request | 60 | // Asset data request |
60 | server.HttpServer.AddHandler("get", null, @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/data", | 61 | m_server.HttpServer.AddStreamHandler(new DataRequestHandler(server)); |
61 | DataRequestHandler); | ||
62 | 62 | ||
63 | // Asset creation | 63 | // Asset creation |
64 | server.HttpServer.AddHandler("post", null, "^/createasset", CreateRequestHandler); | 64 | m_server.HttpServer.AddStreamHandler(new CreateRequestHandler(server)); |
65 | 65 | ||
66 | Logger.Log.Info("[ASSET] Reference Frontend loaded."); | 66 | Logger.Log.Info("[ASSET] Reference Frontend loaded."); |
67 | } | 67 | } |
@@ -92,174 +92,279 @@ namespace OpenSim.Grid.AssetInventoryServer.Plugins | |||
92 | 92 | ||
93 | #endregion IPlugin implementation | 93 | #endregion IPlugin implementation |
94 | 94 | ||
95 | bool MetadataRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) | 95 | public class MetadataRequestHandler : IStreamedRequestHandler |
96 | { | 96 | { |
97 | UUID assetID; | 97 | AssetInventoryServer m_server; |
98 | // Split the URL up into an AssetID and a method | 98 | string m_contentType; |
99 | string[] rawUrl = request.Uri.PathAndQuery.Split('/'); | 99 | string m_httpMethod; |
100 | string m_path; | ||
100 | 101 | ||
101 | if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID)) | 102 | public MetadataRequestHandler(AssetInventoryServer server) |
102 | { | 103 | { |
103 | UUID authToken = Utils.GetAuthToken(request); | 104 | m_server = server; |
105 | m_contentType = null; | ||
106 | m_httpMethod = "GET"; | ||
107 | m_path = @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/metadata"; | ||
108 | } | ||
109 | |||
110 | #region IStreamedRequestHandler implementation | ||
111 | |||
112 | public string ContentType | ||
113 | { | ||
114 | get { return m_contentType; } | ||
115 | } | ||
116 | |||
117 | public string HttpMethod | ||
118 | { | ||
119 | get { return m_httpMethod; } | ||
120 | } | ||
121 | |||
122 | public string Path | ||
123 | { | ||
124 | get { return m_path; } | ||
125 | } | ||
104 | 126 | ||
105 | if (server.AuthorizationProvider.IsMetadataAuthorized(authToken, assetID)) | 127 | public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) |
128 | { | ||
129 | byte[] serializedData = null; | ||
130 | UUID assetID; | ||
131 | // Split the URL up into an AssetID and a method | ||
132 | string[] rawUrl = httpRequest.Url.PathAndQuery.Split('/'); | ||
133 | |||
134 | if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID)) | ||
106 | { | 135 | { |
107 | Metadata metadata; | 136 | UUID authToken = Utils.GetAuthToken(httpRequest); |
108 | BackendResponse storageResponse = server.StorageProvider.TryFetchMetadata(assetID, out metadata); | ||
109 | 137 | ||
110 | if (storageResponse == BackendResponse.Success) | 138 | if (m_server.AuthorizationProvider.IsMetadataAuthorized(authToken, assetID)) |
111 | { | 139 | { |
112 | // If the asset data location wasn't specified in the metadata, specify it | 140 | Metadata metadata; |
113 | // manually here by pointing back to this asset server | 141 | BackendResponse storageResponse = m_server.StorageProvider.TryFetchMetadata(assetID, out metadata); |
114 | if (!metadata.Methods.ContainsKey("data")) | ||
115 | { | ||
116 | metadata.Methods["data"] = new Uri(String.Format("{0}://{1}/{2}/data", | ||
117 | request.Uri.Scheme, request.Uri.Authority, assetID)); | ||
118 | } | ||
119 | 142 | ||
120 | byte[] serializedData = metadata.SerializeToBytes(); | 143 | if (storageResponse == BackendResponse.Success) |
144 | { | ||
145 | // If the asset data location wasn't specified in the metadata, specify it | ||
146 | // manually here by pointing back to this asset server | ||
147 | if (!metadata.Methods.ContainsKey("data")) | ||
148 | { | ||
149 | metadata.Methods["data"] = new Uri(String.Format("{0}://{1}/{2}/data", | ||
150 | httpRequest.Url.Scheme, httpRequest.Url.Authority, assetID)); | ||
151 | } | ||
121 | 152 | ||
122 | response.Status = HttpStatusCode.OK; | 153 | serializedData = metadata.SerializeToBytes(); |
123 | response.ContentType = "application/json"; | ||
124 | response.ContentLength = serializedData.Length; | ||
125 | response.Body.Write(serializedData, 0, serializedData.Length); | ||
126 | 154 | ||
127 | } | 155 | httpResponse.StatusCode = (int) HttpStatusCode.OK; |
128 | else if (storageResponse == BackendResponse.NotFound) | 156 | httpResponse.ContentType = "application/json"; |
129 | { | 157 | httpResponse.ContentLength = serializedData.Length; |
130 | Logger.Log.Warn("Could not find metadata for asset " + assetID.ToString()); | 158 | httpResponse.Body.Write(serializedData, 0, serializedData.Length); |
131 | response.Status = HttpStatusCode.NotFound; | 159 | } |
160 | else if (storageResponse == BackendResponse.NotFound) | ||
161 | { | ||
162 | Logger.Log.Warn("Could not find metadata for asset " + assetID.ToString()); | ||
163 | httpResponse.StatusCode = (int) HttpStatusCode.NotFound; | ||
164 | } | ||
165 | else | ||
166 | { | ||
167 | httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError; | ||
168 | } | ||
132 | } | 169 | } |
133 | else | 170 | else |
134 | { | 171 | { |
135 | response.Status = HttpStatusCode.InternalServerError; | 172 | httpResponse.StatusCode = (int) HttpStatusCode.Forbidden; |
136 | } | 173 | } |
137 | } | 174 | |
138 | else | 175 | return serializedData; |
139 | { | ||
140 | response.Status = HttpStatusCode.Forbidden; | ||
141 | } | 176 | } |
142 | 177 | ||
143 | return true; | 178 | httpResponse.StatusCode = (int) HttpStatusCode.NotFound; |
179 | return serializedData; | ||
144 | } | 180 | } |
145 | 181 | ||
146 | response.Status = HttpStatusCode.NotFound; | 182 | #endregion IStreamedRequestHandler implementation |
147 | return true; | ||
148 | } | 183 | } |
149 | 184 | ||
150 | bool DataRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) | 185 | public class DataRequestHandler : IStreamedRequestHandler |
151 | { | 186 | { |
152 | UUID assetID; | 187 | AssetInventoryServer m_server; |
153 | // Split the URL up into an AssetID and a method | 188 | string m_contentType; |
154 | string[] rawUrl = request.Uri.PathAndQuery.Split('/'); | 189 | string m_httpMethod; |
190 | string m_path; | ||
191 | |||
192 | public DataRequestHandler(AssetInventoryServer server) | ||
193 | { | ||
194 | m_server = server; | ||
195 | m_contentType = null; | ||
196 | m_httpMethod = "GET"; | ||
197 | m_path = @"^/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/data"; | ||
198 | } | ||
199 | |||
200 | #region IStreamedRequestHandler implementation | ||
201 | |||
202 | public string ContentType | ||
203 | { | ||
204 | get { return m_contentType; } | ||
205 | } | ||
155 | 206 | ||
156 | if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID)) | 207 | public string HttpMethod |
157 | { | 208 | { |
158 | UUID authToken = Utils.GetAuthToken(request); | 209 | get { return m_httpMethod; } |
210 | } | ||
211 | |||
212 | public string Path | ||
213 | { | ||
214 | get { return m_path; } | ||
215 | } | ||
159 | 216 | ||
160 | if (server.AuthorizationProvider.IsDataAuthorized(authToken, assetID)) | 217 | public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) |
218 | { | ||
219 | byte[] assetData = null; | ||
220 | UUID assetID; | ||
221 | // Split the URL up into an AssetID and a method | ||
222 | string[] rawUrl = httpRequest.Url.PathAndQuery.Split('/'); | ||
223 | |||
224 | if (rawUrl.Length >= 3 && UUID.TryParse(rawUrl[1], out assetID)) | ||
161 | { | 225 | { |
162 | byte[] assetData; | 226 | UUID authToken = Utils.GetAuthToken(httpRequest); |
163 | BackendResponse storageResponse = server.StorageProvider.TryFetchData(assetID, out assetData); | ||
164 | 227 | ||
165 | if (storageResponse == BackendResponse.Success) | 228 | if (m_server.AuthorizationProvider.IsDataAuthorized(authToken, assetID)) |
166 | { | 229 | { |
167 | response.Status = HttpStatusCode.OK; | 230 | BackendResponse storageResponse = m_server.StorageProvider.TryFetchData(assetID, out assetData); |
168 | response.Status = HttpStatusCode.OK; | 231 | |
169 | response.ContentType = "application/octet-stream"; | 232 | if (storageResponse == BackendResponse.Success) |
170 | response.AddHeader("Content-Disposition", "attachment; filename=" + assetID.ToString()); | 233 | { |
171 | response.ContentLength = assetData.Length; | 234 | httpResponse.StatusCode = (int) HttpStatusCode.OK; |
172 | response.Body.Write(assetData, 0, assetData.Length); | 235 | httpResponse.ContentType = "application/octet-stream"; |
173 | } | 236 | httpResponse.AddHeader("Content-Disposition", "attachment; filename=" + assetID.ToString()); |
174 | else if (storageResponse == BackendResponse.NotFound) | 237 | httpResponse.ContentLength = assetData.Length; |
175 | { | 238 | httpResponse.Body.Write(assetData, 0, assetData.Length); |
176 | response.Status = HttpStatusCode.NotFound; | 239 | } |
240 | else if (storageResponse == BackendResponse.NotFound) | ||
241 | { | ||
242 | httpResponse.StatusCode = (int) HttpStatusCode.NotFound; | ||
243 | } | ||
244 | else | ||
245 | { | ||
246 | httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError; | ||
247 | } | ||
177 | } | 248 | } |
178 | else | 249 | else |
179 | { | 250 | { |
180 | response.Status = HttpStatusCode.InternalServerError; | 251 | httpResponse.StatusCode = (int) HttpStatusCode.Forbidden; |
181 | } | 252 | } |
182 | } | 253 | |
183 | else | 254 | return assetData; |
184 | { | ||
185 | response.Status = HttpStatusCode.Forbidden; | ||
186 | } | 255 | } |
187 | 256 | ||
188 | return true; | 257 | httpResponse.StatusCode = (int) HttpStatusCode.BadRequest; |
258 | return assetData; | ||
189 | } | 259 | } |
190 | 260 | ||
191 | response.Status = HttpStatusCode.BadRequest; | 261 | #endregion IStreamedRequestHandler implementation |
192 | return true; | ||
193 | } | 262 | } |
194 | 263 | ||
195 | bool CreateRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) | 264 | public class CreateRequestHandler : IStreamedRequestHandler |
196 | { | 265 | { |
197 | UUID authToken = Utils.GetAuthToken(request); | 266 | AssetInventoryServer m_server; |
267 | string m_contentType; | ||
268 | string m_httpMethod; | ||
269 | string m_path; | ||
198 | 270 | ||
199 | if (server.AuthorizationProvider.IsCreateAuthorized(authToken)) | 271 | public CreateRequestHandler(AssetInventoryServer server) |
200 | { | 272 | { |
201 | try | 273 | m_server = server; |
202 | { | 274 | m_contentType = null; |
203 | OSD osdata = OSDParser.DeserializeJson(request.Body); | 275 | m_httpMethod = "POST"; |
276 | m_path = "^/createasset"; | ||
277 | } | ||
204 | 278 | ||
205 | if (osdata.Type == OSDType.Map) | 279 | #region IStreamedRequestHandler implementation |
206 | { | 280 | |
207 | OSDMap map = (OSDMap)osdata; | 281 | public string ContentType |
208 | Metadata metadata = new Metadata(); | 282 | { |
209 | metadata.Deserialize(map); | 283 | get { return m_contentType; } |
284 | } | ||
285 | |||
286 | public string HttpMethod | ||
287 | { | ||
288 | get { return m_httpMethod; } | ||
289 | } | ||
290 | |||
291 | public string Path | ||
292 | { | ||
293 | get { return m_path; } | ||
294 | } | ||
295 | |||
296 | public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) | ||
297 | { | ||
298 | byte[] responseData = null; | ||
299 | UUID authToken = Utils.GetAuthToken(httpRequest); | ||
210 | 300 | ||
211 | byte[] assetData = map["data"].AsBinary(); | 301 | if (m_server.AuthorizationProvider.IsCreateAuthorized(authToken)) |
302 | { | ||
303 | try | ||
304 | { | ||
305 | OSD osdata = OSDParser.DeserializeJson(httpRequest.InputStream); | ||
212 | 306 | ||
213 | if (assetData != null && assetData.Length > 0) | 307 | if (osdata.Type == OSDType.Map) |
214 | { | 308 | { |
215 | BackendResponse storageResponse; | 309 | OSDMap map = (OSDMap)osdata; |
310 | Metadata metadata = new Metadata(); | ||
311 | metadata.Deserialize(map); | ||
216 | 312 | ||
217 | if (metadata.ID != UUID.Zero) | 313 | byte[] assetData = map["data"].AsBinary(); |
218 | storageResponse = server.StorageProvider.TryCreateAsset(metadata, assetData); | ||
219 | else | ||
220 | storageResponse = server.StorageProvider.TryCreateAsset(metadata, assetData, out metadata.ID); | ||
221 | 314 | ||
222 | if (storageResponse == BackendResponse.Success) | 315 | if (assetData != null && assetData.Length > 0) |
223 | { | ||
224 | response.Status = HttpStatusCode.Created; | ||
225 | OSDMap responseMap = new OSDMap(1); | ||
226 | responseMap["id"] = OSD.FromUUID(metadata.ID); | ||
227 | LitJson.JsonData jsonData = OSDParser.SerializeJson(responseMap); | ||
228 | byte[] responseData = System.Text.Encoding.UTF8.GetBytes(jsonData.ToJson()); | ||
229 | response.Body.Write(responseData, 0, responseData.Length); | ||
230 | response.Body.Flush(); | ||
231 | } | ||
232 | else if (storageResponse == BackendResponse.NotFound) | ||
233 | { | 316 | { |
234 | response.Status = HttpStatusCode.NotFound; | 317 | BackendResponse storageResponse; |
318 | |||
319 | if (metadata.ID != UUID.Zero) | ||
320 | storageResponse = m_server.StorageProvider.TryCreateAsset(metadata, assetData); | ||
321 | else | ||
322 | storageResponse = m_server.StorageProvider.TryCreateAsset(metadata, assetData, out metadata.ID); | ||
323 | |||
324 | if (storageResponse == BackendResponse.Success) | ||
325 | { | ||
326 | httpResponse.StatusCode = (int) HttpStatusCode.Created; | ||
327 | OSDMap responseMap = new OSDMap(1); | ||
328 | responseMap["id"] = OSD.FromUUID(metadata.ID); | ||
329 | LitJson.JsonData jsonData = OSDParser.SerializeJson(responseMap); | ||
330 | responseData = System.Text.Encoding.UTF8.GetBytes(jsonData.ToJson()); | ||
331 | httpResponse.Body.Write(responseData, 0, responseData.Length); | ||
332 | httpResponse.Body.Flush(); | ||
333 | } | ||
334 | else if (storageResponse == BackendResponse.NotFound) | ||
335 | { | ||
336 | httpResponse.StatusCode = (int) HttpStatusCode.NotFound; | ||
337 | } | ||
338 | else | ||
339 | { | ||
340 | httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError; | ||
341 | } | ||
235 | } | 342 | } |
236 | else | 343 | else |
237 | { | 344 | { |
238 | response.Status = HttpStatusCode.InternalServerError; | 345 | httpResponse.StatusCode = (int) HttpStatusCode.BadRequest; |
239 | } | 346 | } |
240 | } | 347 | } |
241 | else | 348 | else |
242 | { | 349 | { |
243 | response.Status = HttpStatusCode.BadRequest; | 350 | httpResponse.StatusCode = (int) HttpStatusCode.BadRequest; |
244 | } | 351 | } |
245 | } | 352 | } |
246 | else | 353 | catch (Exception ex) |
247 | { | 354 | { |
248 | response.Status = HttpStatusCode.BadRequest; | 355 | httpResponse.StatusCode = (int) HttpStatusCode.InternalServerError; |
356 | httpResponse.StatusDescription = ex.Message; | ||
249 | } | 357 | } |
250 | } | 358 | } |
251 | catch (Exception ex) | 359 | else |
252 | { | 360 | { |
253 | response.Status = HttpStatusCode.InternalServerError; | 361 | httpResponse.StatusCode = (int) HttpStatusCode.Forbidden; |
254 | response.Reason = ex.Message; | ||
255 | } | 362 | } |
256 | } | 363 | |
257 | else | 364 | return responseData; |
258 | { | ||
259 | response.Status = HttpStatusCode.Forbidden; | ||
260 | } | 365 | } |
261 | 366 | ||
262 | return true; | 367 | #endregion IStreamedRequestHandler implementation |
263 | } | 368 | } |
264 | } | 369 | } |
265 | } | 370 | } |