View of /trunk/Extensions/OpenSimFrontend.cs
Parent Directory
|
Revision Log
Revision 41 -
(download)
(annotate)
Tue Dec 2 18:00:11 2008 UTC (4 years, 5 months ago) by jhurliman
File size: 10257 byte(s)
Tue Dec 2 18:00:11 2008 UTC (4 years, 5 months ago) by jhurliman
File size: 10257 byte(s)
* Better parsing of OpenSim asset requests (the ?texture parameter was not being stripped off) * Converted AssetClient to use the file extension to content-type map in AssetServer.Utils (AssetClient now has a reference to AssetServer for this function) * More file extension to content-type mappings
/*
* Copyright (c) 2008 Intel Corporation
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* -- Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* -- Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* -- Neither the name of the Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Net;
using System.IO;
using System.Xml;
using ExtensionLoader;
using OpenMetaverse;
namespace AssetServer.Extensions
{
public class OpenSimFrontend : IExtension<AssetServer>
{
AssetServer server;
public OpenSimFrontend()
{
}
public void Start(AssetServer server)
{
this.server = server;
// Asset request
server.HttpServer.AddHandler("get", null, @"^/assets/",
AssetRequestHandler);
// Asset creation
server.HttpServer.AddHandler("post", null, @"^/assets/",
AssetPostHandler);
}
public void Stop()
{
}
void AssetRequestHandler(ref HttpListenerContext context)
{
UUID assetID;
// Split the URL up to get the asset ID out
string[] rawUrl = context.Request.RawUrl.Split('/');
if (rawUrl.Length >= 3 && rawUrl[2].Length >= 36 && UUID.TryParse(rawUrl[2].Substring(0, 36), out assetID))
{
Metadata metadata;
byte[] assetData;
StorageResponse metadataResponse, dataResponse;
if ((metadataResponse = server.StorageProvider.TryFetchMetadata(assetID, UUID.Zero, out metadata)) == StorageResponse.Success)
{
if ((dataResponse = server.StorageProvider.TryFetchData(assetID, UUID.Zero, out assetData)) == StorageResponse.Success)
{
MemoryStream stream = new MemoryStream();
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create(stream, settings);
writer.WriteStartDocument();
writer.WriteStartElement("AssetBase");
writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
writer.WriteAttributeString("xmlns", "xsd", null, "http://www.w3.org/2001/XMLSchema");
writer.WriteStartElement("FullID");
writer.WriteStartElement("Guid");
writer.WriteString(assetID.ToString());
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteStartElement("ID");
writer.WriteString(assetID.ToString());
writer.WriteEndElement();
writer.WriteStartElement("Data");
writer.WriteBase64(assetData, 0, assetData.Length);
writer.WriteEndElement();
writer.WriteStartElement("Type");
writer.WriteValue(Utils.ContentTypeToSLAssetType(metadata.ContentType));
writer.WriteEndElement();
writer.WriteStartElement("Name");
writer.WriteString(metadata.Name);
writer.WriteEndElement();
writer.WriteStartElement("Description");
writer.WriteString(metadata.Description);
writer.WriteEndElement();
writer.WriteStartElement("Local");
writer.WriteValue(false);
writer.WriteEndElement();
writer.WriteStartElement("Temporary");
writer.WriteValue(metadata.Temporary);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();
byte[] buffer = stream.GetBuffer();
context.Response.StatusCode = (int)HttpStatusCode.OK;
context.Response.ContentType = "application/xml";
context.Response.ContentLength64 = (int)stream.Length;
context.Response.OutputStream.Write(buffer, 0, (int)stream.Length);
return;
}
else
{
Logger.Log.WarnFormat("Failed to fetch asset data for {0}: {1}", assetID, dataResponse);
}
}
else
{
Logger.Log.WarnFormat("Failed to fetch asset metadata for {0}: {1}", assetID, metadataResponse);
}
}
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
}
void AssetPostHandler(ref HttpListenerContext context)
{
byte[] assetData = null;
Metadata metadata = new Metadata();
try
{
using (XmlReader reader = XmlReader.Create(context.Request.InputStream))
{
reader.MoveToContent();
reader.ReadStartElement("AssetBase");
reader.ReadStartElement("FullID");
UUID.TryParse(reader.ReadElementContentAsString("Guid", String.Empty), out metadata.ID);
reader.ReadEndElement();
reader.ReadStartElement("ID");
reader.Skip();
reader.ReadEndElement();
int readBytes = 0;
byte[] buffer = new byte[1024];
MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream);
while ((readBytes = reader.ReadElementContentAsBase64(buffer, 0, buffer.Length)) > 0)
writer.Write(buffer, 0, readBytes);
writer.Flush();
assetData = stream.GetBuffer();
Array.Resize<byte>(ref assetData, (int)stream.Length);
int type;
Int32.TryParse(reader.ReadElementContentAsString("Type", String.Empty), out type);
metadata.ContentType = Utils.SLAssetTypeToContentType(type);
metadata.Name = reader.ReadElementContentAsString("Name", String.Empty);
metadata.Description = reader.ReadElementContentAsString("Description", String.Empty);
Boolean.TryParse(reader.ReadElementContentAsString("Local", String.Empty), out metadata.Temporary);
Boolean.TryParse(reader.ReadElementContentAsString("Temporary", String.Empty), out metadata.Temporary);
reader.ReadEndElement();
}
if (assetData != null && assetData.Length > 0)
{
metadata.SHA1 = OpenMetaverse.Utils.SHA1(assetData);
metadata.CreationDate = DateTime.Now;
StorageResponse response = server.StorageProvider.TryCreateAsset(metadata, assetData, UUID.Zero);
switch (response)
{
case StorageResponse.Success:
context.Response.StatusCode = (int)HttpStatusCode.Created;
break;
case StorageResponse.NotFound:
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
break;
case StorageResponse.AuthNeeded:
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
break;
case StorageResponse.Failure:
default:
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
break;
}
}
else
{
Logger.Log.Warn("AssetPostHandler called with no asset data");
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
}
}
catch (Exception ex)
{
Logger.Log.Warn("Failed to parse POST data (expecting AssetBase): " + ex.Message);
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
}
}
}
}
| ViewVC Help | |
| Powered by ViewVC 1.0.0 |

