diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Grid/NewAssetServer/Extensions/OpenSimFrontend.cs | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/OpenSim/Grid/NewAssetServer/Extensions/OpenSimFrontend.cs b/OpenSim/Grid/NewAssetServer/Extensions/OpenSimFrontend.cs new file mode 100644 index 0000000..7a645b3 --- /dev/null +++ b/OpenSim/Grid/NewAssetServer/Extensions/OpenSimFrontend.cs | |||
@@ -0,0 +1,215 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008 Intel Corporation | ||
3 | * All rights reserved. | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * | ||
8 | * -- Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * -- Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * -- Neither the name of the Intel Corporation nor the names of its | ||
14 | * contributors may be used to endorse or promote products derived from | ||
15 | * this software without specific prior written permission. | ||
16 | * | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
18 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
20 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS | ||
21 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
22 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
23 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
24 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
25 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
26 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
28 | */ | ||
29 | |||
30 | using System; | ||
31 | using System.Collections.Generic; | ||
32 | using System.Net; | ||
33 | using System.IO; | ||
34 | using System.Xml; | ||
35 | using ExtensionLoader; | ||
36 | using OpenMetaverse; | ||
37 | using HttpServer; | ||
38 | |||
39 | namespace AssetServer.Extensions | ||
40 | { | ||
41 | public class OpenSimFrontend : IExtension<AssetServer> | ||
42 | { | ||
43 | AssetServer server; | ||
44 | |||
45 | public OpenSimFrontend() | ||
46 | { | ||
47 | } | ||
48 | |||
49 | public void Start(AssetServer server) | ||
50 | { | ||
51 | this.server = server; | ||
52 | |||
53 | // Asset request | ||
54 | server.HttpServer.AddHandler("get", null, @"^/assets/", AssetRequestHandler); | ||
55 | |||
56 | // Asset creation | ||
57 | server.HttpServer.AddHandler("post", null, @"^/assets/", AssetPostHandler); | ||
58 | } | ||
59 | |||
60 | public void Stop() | ||
61 | { | ||
62 | } | ||
63 | |||
64 | bool AssetRequestHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) | ||
65 | { | ||
66 | UUID assetID; | ||
67 | // Split the URL up to get the asset ID out | ||
68 | string[] rawUrl = request.Uri.PathAndQuery.Split('/'); | ||
69 | |||
70 | if (rawUrl.Length >= 3 && rawUrl[2].Length >= 36 && UUID.TryParse(rawUrl[2].Substring(0, 36), out assetID)) | ||
71 | { | ||
72 | Metadata metadata; | ||
73 | byte[] assetData; | ||
74 | BackendResponse dataResponse; | ||
75 | |||
76 | if ((dataResponse = server.StorageProvider.TryFetchDataMetadata(assetID, out metadata, out assetData)) == BackendResponse.Success) | ||
77 | { | ||
78 | MemoryStream stream = new MemoryStream(); | ||
79 | |||
80 | XmlWriterSettings settings = new XmlWriterSettings(); | ||
81 | settings.Indent = true; | ||
82 | XmlWriter writer = XmlWriter.Create(stream, settings); | ||
83 | |||
84 | writer.WriteStartDocument(); | ||
85 | writer.WriteStartElement("AssetBase"); | ||
86 | writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance"); | ||
87 | writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema"); | ||
88 | writer.WriteStartElement("FullID"); | ||
89 | writer.WriteStartElement("Guid"); | ||
90 | writer.WriteString(assetID.ToString()); | ||
91 | writer.WriteEndElement(); | ||
92 | writer.WriteEndElement(); | ||
93 | writer.WriteStartElement("ID"); | ||
94 | writer.WriteString(assetID.ToString()); | ||
95 | writer.WriteEndElement(); | ||
96 | writer.WriteStartElement("Data"); | ||
97 | writer.WriteBase64(assetData, 0, assetData.Length); | ||
98 | writer.WriteEndElement(); | ||
99 | writer.WriteStartElement("Type"); | ||
100 | writer.WriteValue(Utils.ContentTypeToSLAssetType(metadata.ContentType)); | ||
101 | writer.WriteEndElement(); | ||
102 | writer.WriteStartElement("Name"); | ||
103 | writer.WriteString(metadata.Name); | ||
104 | writer.WriteEndElement(); | ||
105 | writer.WriteStartElement("Description"); | ||
106 | writer.WriteString(metadata.Description); | ||
107 | writer.WriteEndElement(); | ||
108 | writer.WriteStartElement("Local"); | ||
109 | writer.WriteValue(false); | ||
110 | writer.WriteEndElement(); | ||
111 | writer.WriteStartElement("Temporary"); | ||
112 | writer.WriteValue(metadata.Temporary); | ||
113 | writer.WriteEndElement(); | ||
114 | writer.WriteEndElement(); | ||
115 | writer.WriteEndDocument(); | ||
116 | |||
117 | writer.Flush(); | ||
118 | byte[] buffer = stream.GetBuffer(); | ||
119 | |||
120 | response.Status = HttpStatusCode.OK; | ||
121 | response.ContentType = "application/xml"; | ||
122 | response.ContentLength = stream.Length; | ||
123 | response.Body.Write(buffer, 0, (int)stream.Length); | ||
124 | response.Body.Flush(); | ||
125 | } | ||
126 | else | ||
127 | { | ||
128 | Logger.Log.WarnFormat("Failed to fetch asset data or metadata for {0}: {1}", assetID, dataResponse); | ||
129 | response.Status = HttpStatusCode.NotFound; | ||
130 | } | ||
131 | } | ||
132 | else | ||
133 | { | ||
134 | Logger.Log.Warn("Unrecognized OpenSim asset request: " + request.Uri.PathAndQuery); | ||
135 | } | ||
136 | |||
137 | return true; | ||
138 | } | ||
139 | |||
140 | bool AssetPostHandler(IHttpClientContext client, IHttpRequest request, IHttpResponse response) | ||
141 | { | ||
142 | byte[] assetData = null; | ||
143 | Metadata metadata = new Metadata(); | ||
144 | |||
145 | Logger.Log.Debug("Handling OpenSim asset upload"); | ||
146 | |||
147 | try | ||
148 | { | ||
149 | using (XmlReader reader = XmlReader.Create(request.Body)) | ||
150 | { | ||
151 | reader.MoveToContent(); | ||
152 | reader.ReadStartElement("AssetBase"); | ||
153 | |||
154 | reader.ReadStartElement("FullID"); | ||
155 | UUID.TryParse(reader.ReadElementContentAsString("Guid", String.Empty), out metadata.ID); | ||
156 | reader.ReadEndElement(); | ||
157 | reader.ReadStartElement("ID"); | ||
158 | reader.Skip(); | ||
159 | reader.ReadEndElement(); | ||
160 | |||
161 | // HACK: Broken on Mono. https://bugzilla.novell.com/show_bug.cgi?id=464229 | ||
162 | //int readBytes = 0; | ||
163 | //byte[] buffer = new byte[1024]; | ||
164 | //MemoryStream stream = new MemoryStream(); | ||
165 | //BinaryWriter writer = new BinaryWriter(stream); | ||
166 | //while ((readBytes = reader.ReadElementContentAsBase64(buffer, 0, buffer.Length)) > 0) | ||
167 | // writer.Write(buffer, 0, readBytes); | ||
168 | //writer.Flush(); | ||
169 | //assetData = stream.GetBuffer(); | ||
170 | //Array.Resize<byte>(ref assetData, (int)stream.Length); | ||
171 | |||
172 | assetData = Convert.FromBase64String(reader.ReadElementContentAsString()); | ||
173 | |||
174 | int type; | ||
175 | Int32.TryParse(reader.ReadElementContentAsString("Type", String.Empty), out type); | ||
176 | metadata.ContentType = Utils.SLAssetTypeToContentType(type); | ||
177 | metadata.Name = reader.ReadElementContentAsString("Name", String.Empty); | ||
178 | metadata.Description = reader.ReadElementContentAsString("Description", String.Empty); | ||
179 | Boolean.TryParse(reader.ReadElementContentAsString("Local", String.Empty), out metadata.Temporary); | ||
180 | Boolean.TryParse(reader.ReadElementContentAsString("Temporary", String.Empty), out metadata.Temporary); | ||
181 | |||
182 | reader.ReadEndElement(); | ||
183 | } | ||
184 | |||
185 | if (assetData != null && assetData.Length > 0) | ||
186 | { | ||
187 | metadata.SHA1 = OpenMetaverse.Utils.SHA1(assetData); | ||
188 | metadata.CreationDate = DateTime.Now; | ||
189 | |||
190 | BackendResponse storageResponse = server.StorageProvider.TryCreateAsset(metadata, assetData); | ||
191 | |||
192 | if (storageResponse == BackendResponse.Success) | ||
193 | response.Status = HttpStatusCode.Created; | ||
194 | else if (storageResponse == BackendResponse.NotFound) | ||
195 | response.Status = HttpStatusCode.NotFound; | ||
196 | else | ||
197 | response.Status = HttpStatusCode.InternalServerError; | ||
198 | } | ||
199 | else | ||
200 | { | ||
201 | Logger.Log.Warn("AssetPostHandler called with no asset data"); | ||
202 | response.Status = HttpStatusCode.BadRequest; | ||
203 | } | ||
204 | } | ||
205 | catch (Exception ex) | ||
206 | { | ||
207 | Logger.Log.Warn("Failed to parse POST data (expecting AssetBase): " + ex.Message); | ||
208 | response.Status = HttpStatusCode.BadRequest; | ||
209 | } | ||
210 | |||
211 | Logger.Log.Debug("Finished handling OpenSim asset upload, Status: " + response.Status.ToString()); | ||
212 | return true; | ||
213 | } | ||
214 | } | ||
215 | } | ||