* Removed AssetHttpServer, using BaseHttpServer instead

* Removed legacy REST handling
* Created two custom IStreamHandlers for asset up/download
* Removed quite a lot of double and triple encodings, trying to work towards binary only and direct write into storage.
* Introduced BaseStreamHandler with GetParam() and some other goodies
Sugilite
lbsa71 2007-07-04 14:12:32 +00:00
parent 9a51949cb4
commit 6a2588454a
16 changed files with 503 additions and 591 deletions

View File

@ -29,17 +29,6 @@ Global
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
({FD2D303D-0000-0000-0000-000000000000}).2 = ({36B72A9B-0000-0000-0000-000000000000})
({17F7F694-0000-0000-0000-000000000000}).1 = ({36B72A9B-0000-0000-0000-000000000000})
({17F7F6BE-0000-0000-0000-000000000000}).2 = ({36B72A9B-0000-0000-0000-000000000000})
({6ECC56A9-0000-0000-0000-000000000000}).1 = ({36B72A9B-0000-0000-0000-000000000000})
({586E2916-0000-0000-0000-000000000000}).4 = ({36B72A9B-0000-0000-0000-000000000000})
({60FCC3A6-0000-0000-0000-000000000000}).4 = ({36B72A9B-0000-0000-0000-000000000000})
({60FCC3A6-0000-0000-0000-000000000000}).7 = ({4B7BFD1C-0000-0000-0000-000000000000})
({2FC96F92-0000-0000-0000-000000000000}).4 = ({36B72A9B-0000-0000-0000-000000000000})
({2FC96F92-0000-0000-0000-000000000000}).7 = ({586E2916-0000-0000-0000-000000000000})
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{36B72A9B-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {36B72A9B-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{36B72A9B-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU {36B72A9B-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU

View File

@ -57,89 +57,6 @@ Global
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
({438A9556-0000-0000-0000-000000000000}).3 = ({8ACA2445-0000-0000-0000-000000000000})
({438A9556-0000-0000-0000-000000000000}).4 = ({CB52B7E7-0000-0000-0000-000000000000})
({438A9556-0000-0000-0000-000000000000}).5 = ({A7CD0630-0000-0000-0000-000000000000})
({438A9556-0000-0000-0000-000000000000}).6 = ({36B72A9B-0000-0000-0000-000000000000})
({438A9556-0000-0000-0000-000000000000}).7 = ({C74E4A30-0000-0000-0000-000000000000})
({438A9556-0000-0000-0000-000000000000}).8 = ({2CC71860-0000-0000-0000-000000000000})
({438A9556-0000-0000-0000-000000000000}).9 = ({586E2916-0000-0000-0000-000000000000})
({438A9556-0000-0000-0000-000000000000}).10 = ({61FCCDB3-0000-0000-0000-000000000000})
({438A9556-0000-0000-0000-000000000000}).11 = ({DC3698B2-0000-0000-0000-000000000000})
({438A9556-0000-0000-0000-000000000000}).12 = ({BFB5D807-0000-0000-0000-000000000000})
({438A9556-0000-0000-0000-000000000000}).13 = ({4806E378-0000-0000-0000-000000000000})
({438A9556-0000-0000-0000-000000000000}).14 = ({DCBA491C-0000-0000-0000-000000000000})
({438A9556-0000-0000-0000-000000000000}).15 = ({F4FF31EB-0000-0000-0000-000000000000})
({438A9556-0000-0000-0000-000000000000}).16 = ({C9E0F891-0000-0000-0000-000000000000})
({8ACA2445-0000-0000-0000-000000000000}).2 = ({A7CD0630-0000-0000-0000-000000000000})
({CB52B7E7-0000-0000-0000-000000000000}).1 = ({8ACA2445-0000-0000-0000-000000000000})
({CB52B7E7-0000-0000-0000-000000000000}).2 = ({36B72A9B-0000-0000-0000-000000000000})
({FD2D303D-0000-0000-0000-000000000000}).2 = ({36B72A9B-0000-0000-0000-000000000000})
({C74E4A30-0000-0000-0000-000000000000}).0 = ({8ACA2445-0000-0000-0000-000000000000})
({2CC71860-0000-0000-0000-000000000000}).1 = ({8ACA2445-0000-0000-0000-000000000000})
({2CC71860-0000-0000-0000-000000000000}).2 = ({A7CD0630-0000-0000-0000-000000000000})
({586E2916-0000-0000-0000-000000000000}).2 = ({8ACA2445-0000-0000-0000-000000000000})
({586E2916-0000-0000-0000-000000000000}).3 = ({A7CD0630-0000-0000-0000-000000000000})
({586E2916-0000-0000-0000-000000000000}).4 = ({36B72A9B-0000-0000-0000-000000000000})
({586E2916-0000-0000-0000-000000000000}).5 = ({C74E4A30-0000-0000-0000-000000000000})
({586E2916-0000-0000-0000-000000000000}).6 = ({2CC71860-0000-0000-0000-000000000000})
({61FCCDB3-0000-0000-0000-000000000000}).1 = ({8ACA2445-0000-0000-0000-000000000000})
({39038E85-0000-0000-0000-000000000000}).1 = ({8ACA2445-0000-0000-0000-000000000000})
({39038E85-0000-0000-0000-000000000000}).2 = ({2CC71860-0000-0000-0000-000000000000})
({39038E85-0000-0000-0000-000000000000}).3 = ({61FCCDB3-0000-0000-0000-000000000000})
({DC3698B2-0000-0000-0000-000000000000}).3 = ({8ACA2445-0000-0000-0000-000000000000})
({DC3698B2-0000-0000-0000-000000000000}).4 = ({A7CD0630-0000-0000-0000-000000000000})
({DC3698B2-0000-0000-0000-000000000000}).5 = ({2CC71860-0000-0000-0000-000000000000})
({DC3698B2-0000-0000-0000-000000000000}).6 = ({61FCCDB3-0000-0000-0000-000000000000})
({DC3698B2-0000-0000-0000-000000000000}).7 = ({F4FF31EB-0000-0000-0000-000000000000})
({DC3698B2-0000-0000-0000-000000000000}).8 = ({C9E0F891-0000-0000-0000-000000000000})
({BFB5D807-0000-0000-0000-000000000000}).1 = ({8ACA2445-0000-0000-0000-000000000000})
({BFB5D807-0000-0000-0000-000000000000}).2 = ({CB52B7E7-0000-0000-0000-000000000000})
({BFB5D807-0000-0000-0000-000000000000}).3 = ({36B72A9B-0000-0000-0000-000000000000})
({BFB5D807-0000-0000-0000-000000000000}).4 = ({586E2916-0000-0000-0000-000000000000})
({4806E378-0000-0000-0000-000000000000}).1 = ({8ACA2445-0000-0000-0000-000000000000})
({4806E378-0000-0000-0000-000000000000}).2 = ({CB52B7E7-0000-0000-0000-000000000000})
({4806E378-0000-0000-0000-000000000000}).3 = ({A7CD0630-0000-0000-0000-000000000000})
({4806E378-0000-0000-0000-000000000000}).4 = ({36B72A9B-0000-0000-0000-000000000000})
({4806E378-0000-0000-0000-000000000000}).5 = ({2CC71860-0000-0000-0000-000000000000})
({DCBA491C-0000-0000-0000-000000000000}).4 = ({8ACA2445-0000-0000-0000-000000000000})
({DCBA491C-0000-0000-0000-000000000000}).5 = ({CB52B7E7-0000-0000-0000-000000000000})
({DCBA491C-0000-0000-0000-000000000000}).6 = ({A7CD0630-0000-0000-0000-000000000000})
({DCBA491C-0000-0000-0000-000000000000}).7 = ({C74E4A30-0000-0000-0000-000000000000})
({DCBA491C-0000-0000-0000-000000000000}).8 = ({2CC71860-0000-0000-0000-000000000000})
({DCBA491C-0000-0000-0000-000000000000}).9 = ({61FCCDB3-0000-0000-0000-000000000000})
({DCBA491C-0000-0000-0000-000000000000}).10 = ({39038E85-0000-0000-0000-000000000000})
({DCBA491C-0000-0000-0000-000000000000}).11 = ({F4FF31EB-0000-0000-0000-000000000000})
({DCBA491C-0000-0000-0000-000000000000}).12 = ({C9E0F891-0000-0000-0000-000000000000})
({241A8CDD-0000-0000-0000-000000000000}).2 = ({8ACA2445-0000-0000-0000-000000000000})
({241A8CDD-0000-0000-0000-000000000000}).3 = ({A7CD0630-0000-0000-0000-000000000000})
({98C7B681-0000-0000-0000-000000000000}).1 = ({8ACA2445-0000-0000-0000-000000000000})
({98C7B681-0000-0000-0000-000000000000}).2 = ({A7CD0630-0000-0000-0000-000000000000})
({15B4FEF3-0000-0000-0000-000000000000}).1 = ({F4FF31EB-0000-0000-0000-000000000000})
({F4FF31EB-0000-0000-0000-000000000000}).1 = ({8ACA2445-0000-0000-0000-000000000000})
({F4FF31EB-0000-0000-0000-000000000000}).2 = ({A7CD0630-0000-0000-0000-000000000000})
({90620634-0000-0000-0000-000000000000}).2 = ({F4FF31EB-0000-0000-0000-000000000000})
({A6D191D8-0000-0000-0000-000000000000}).1 = ({F4FF31EB-0000-0000-0000-000000000000})
({A4691E59-0000-0000-0000-000000000000}).3 = ({8ACA2445-0000-0000-0000-000000000000})
({A4691E59-0000-0000-0000-000000000000}).4 = ({A7CD0630-0000-0000-0000-000000000000})
({43DB702D-0000-0000-0000-000000000000}).2 = ({8ACA2445-0000-0000-0000-000000000000})
({43DB702D-0000-0000-0000-000000000000}).3 = ({A7CD0630-0000-0000-0000-000000000000})
({477B9270-0000-0000-0000-000000000000}).1 = ({8ACA2445-0000-0000-0000-000000000000})
({477B9270-0000-0000-0000-000000000000}).2 = ({A7CD0630-0000-0000-0000-000000000000})
({24B12448-0000-0000-0000-000000000000}).1 = ({8ACA2445-0000-0000-0000-000000000000})
({24B12448-0000-0000-0000-000000000000}).2 = ({CB52B7E7-0000-0000-0000-000000000000})
({24B12448-0000-0000-0000-000000000000}).3 = ({A7CD0630-0000-0000-0000-000000000000})
({24B12448-0000-0000-0000-000000000000}).4 = ({2CC71860-0000-0000-0000-000000000000})
({24B12448-0000-0000-0000-000000000000}).5 = ({586E2916-0000-0000-0000-000000000000})
({24B12448-0000-0000-0000-000000000000}).6 = ({61FCCDB3-0000-0000-0000-000000000000})
({24B12448-0000-0000-0000-000000000000}).7 = ({39038E85-0000-0000-0000-000000000000})
({24B12448-0000-0000-0000-000000000000}).8 = ({DC3698B2-0000-0000-0000-000000000000})
({24B12448-0000-0000-0000-000000000000}).9 = ({BFB5D807-0000-0000-0000-000000000000})
({24B12448-0000-0000-0000-000000000000}).10 = ({DCBA491C-0000-0000-0000-000000000000})
({24B12448-0000-0000-0000-000000000000}).11 = ({241A8CDD-0000-0000-0000-000000000000})
({24B12448-0000-0000-0000-000000000000}).12 = ({F4FF31EB-0000-0000-0000-000000000000})
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{438A9556-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {438A9556-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{438A9556-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU {438A9556-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU

View File

@ -42,48 +42,56 @@ namespace OpenSim.Framework.Servers
{ {
protected Thread m_workerThread; protected Thread m_workerThread;
protected HttpListener m_httpListener; protected HttpListener m_httpListener;
protected Dictionary<string, RestMethodEntry> m_restHandlers = new Dictionary<string, RestMethodEntry>(); //protected Dictionary<string, RestMethodEntry> m_restHandlers = new Dictionary<string, RestMethodEntry>();
protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>(); protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>();
protected Dictionary<string, IStreamHandler> m_streamHandlers = new Dictionary<string, IStreamHandler>(); protected Dictionary<string, IStreamHandler> m_streamHandlers = new Dictionary<string, IStreamHandler>();
protected int m_port; protected int m_port;
protected bool firstcaps = true; protected bool m_firstcaps = true;
public BaseHttpServer(int port) public BaseHttpServer(int port)
{ {
m_port = port; m_port = port;
} }
public void AddStreamHandler( string path, IStreamHandler handler) public void AddStreamHandler( IStreamHandler handler)
{ {
string handlerKey = handler.HttpMethod + ":" + path; string httpMethod = handler.HttpMethod;
string path = handler.Path;
string handlerKey = GetHandlerKey(httpMethod, path);
m_streamHandlers.Add(handlerKey, handler); m_streamHandlers.Add(handlerKey, handler);
} }
public bool AddRestHandler(string method, string path, RestMethod handler) private static string GetHandlerKey(string httpMethod, string path)
{ {
//Console.WriteLine("adding new REST handler for path " + path); return httpMethod + ":" + path;
string methodKey = String.Format("{0}: {1}", method, path);
if (!this.m_restHandlers.ContainsKey(methodKey))
{
this.m_restHandlers.Add(methodKey, new RestMethodEntry(path, handler));
return true;
} }
//must already have a handler for that path so return false //public bool AddRestHandler(string method, string path, RestMethod handler)
return false; //{
} // //Console.WriteLine("adding new REST handler for path " + path);
// string methodKey = String.Format("{0}: {1}", method, path);
public bool RemoveRestHandler(string method, string path) // if (!this.m_restHandlers.ContainsKey(methodKey))
{ // {
string methodKey = String.Format("{0}: {1}", method, path); // this.m_restHandlers.Add(methodKey, new RestMethodEntry(path, handler));
if (this.m_restHandlers.ContainsKey(methodKey)) // return true;
{ // }
this.m_restHandlers.Remove(methodKey);
return true; // //must already have a handler for that path so return false
} // return false;
return false; //}
}
//public bool RemoveRestHandler(string method, string path)
//{
// string methodKey = String.Format("{0}: {1}", method, path);
// if (this.m_restHandlers.ContainsKey(methodKey))
// {
// this.m_restHandlers.Remove(methodKey);
// return true;
// }
// return false;
//}
public bool AddXmlRPCHandler(string method, XmlRpcMethod handler) public bool AddXmlRPCHandler(string method, XmlRpcMethod handler)
{ {
@ -119,40 +127,40 @@ namespace OpenSim.Framework.Servers
return XmlRpcResponseSerializer.Singleton.Serialize(response); return XmlRpcResponseSerializer.Singleton.Serialize(response);
} }
protected virtual string ParseREST(string request, string path, string method) //protected virtual string ParseREST(string request, string path, string method)
{ //{
string response; // string response;
string requestKey = String.Format("{0}: {1}", method, path); // string requestKey = String.Format("{0}: {1}", method, path);
string bestMatch = String.Empty; // string bestMatch = String.Empty;
foreach (string currentKey in m_restHandlers.Keys) // foreach (string currentKey in m_restHandlers.Keys)
{ // {
if (requestKey.StartsWith(currentKey)) // if (requestKey.StartsWith(currentKey))
{ // {
if (currentKey.Length > bestMatch.Length) // if (currentKey.Length > bestMatch.Length)
{ // {
bestMatch = currentKey; // bestMatch = currentKey;
} // }
} // }
} // }
RestMethodEntry restMethodEntry; // RestMethodEntry restMethodEntry;
if (m_restHandlers.TryGetValue(bestMatch, out restMethodEntry)) // if (m_restHandlers.TryGetValue(bestMatch, out restMethodEntry))
{ // {
RestMethod restMethod = restMethodEntry.RestMethod; // RestMethod restMethod = restMethodEntry.RestMethod;
string param = path.Substring(restMethodEntry.Path.Length); // string param = path.Substring(restMethodEntry.Path.Length);
response = restMethod(request, path, param); // response = restMethod(request, path, param);
} // }
else // else
{ // {
response = String.Empty; // response = String.Empty;
} // }
return response; // return response;
} //}
protected virtual string ParseXMLRPC(string requestBody) protected virtual string ParseXMLRPC(string requestBody)
@ -179,13 +187,13 @@ namespace OpenSim.Framework.Servers
response.SendChunked = false; response.SendChunked = false;
string path = request.RawUrl; string path = request.RawUrl;
string handlerKey = request.HttpMethod + ":" + path; string handlerKey = GetHandlerKey( request.HttpMethod, path );
IStreamHandler streamHandler; IStreamHandler streamHandler;
if (TryGetStreamHandler( handlerKey, out streamHandler)) if (TryGetStreamHandler( handlerKey, out streamHandler))
{ {
byte[] buffer = streamHandler.Handle(path, request.InputStream ); byte[] buffer = streamHandler.Handle(path, request.InputStream);
request.InputStream.Close(); request.InputStream.Close();
response.ContentType = streamHandler.ContentType; response.ContentType = streamHandler.ContentType;
@ -253,25 +261,25 @@ namespace OpenSim.Framework.Servers
response.AddHeader("Content-type", "text/xml"); response.AddHeader("Content-type", "text/xml");
break; break;
case "application/xml": //case "application/xml":
case "application/octet-stream": //case "application/octet-stream":
// probably LLSD we hope, otherwise it should be ignored by the parser // // probably LLSD we hope, otherwise it should be ignored by the parser
// responseString = ParseLLSDXML(requestBody); // // responseString = ParseLLSDXML(requestBody);
responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); // responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
response.AddHeader("Content-type", "application/xml"); // response.AddHeader("Content-type", "application/xml");
break; // break;
case "application/x-www-form-urlencoded": //case "application/x-www-form-urlencoded":
// a form data POST so send to the REST parser // // a form data POST so send to the REST parser
responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); // responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
response.AddHeader("Content-type", "text/html"); // response.AddHeader("Content-type", "text/html");
break; // break;
case null: //case null:
// must be REST or invalid crap, so pass to the REST parser // // must be REST or invalid crap, so pass to the REST parser
responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod); // responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
response.AddHeader("Content-type", "text/html"); // response.AddHeader("Content-type", "text/html");
break; // break;
} }
@ -318,5 +326,10 @@ namespace OpenSim.Framework.Servers
} }
} }
public void RemoveStreamHandler(string httpMethod, string path)
{
m_streamHandlers.Remove(GetHandlerKey(httpMethod, path));
}
} }
} }

View File

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace OpenSim.Framework.Servers
{
public abstract class BaseStreamHandler : IStreamHandler
{
public string ContentType
{
get { return "application/xml"; }
}
private string m_httpMethod;
public string HttpMethod
{
get { return m_httpMethod; }
}
private string m_path;
public string Path
{
get { return m_path; }
}
protected string GetParam( string path )
{
return path.Substring( m_path.Length );
}
public abstract byte[] Handle(string path, Stream request);
protected BaseStreamHandler(string path, string httpMethod )
{
m_httpMethod = httpMethod;
m_path = path;
}
}
}

View File

@ -15,5 +15,8 @@ namespace OpenSim.Framework.Servers
// Return required http method // Return required http method
string HttpMethod { get;} string HttpMethod { get;}
// Return path
string Path { get; }
} }
} }

View File

@ -93,6 +93,9 @@
<Compile Include="BaseHttpServer.cs"> <Compile Include="BaseHttpServer.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="BaseStreamHandler.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="CheckSumServer.cs"> <Compile Include="CheckSumServer.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>

View File

@ -12,6 +12,7 @@
</resources> </resources>
<sources failonempty="true"> <sources failonempty="true">
<include name="BaseHttpServer.cs" /> <include name="BaseHttpServer.cs" />
<include name="BaseStreamHandler.cs" />
<include name="CheckSumServer.cs" /> <include name="CheckSumServer.cs" />
<include name="ILlsdMethodHandler.cs" /> <include name="ILlsdMethodHandler.cs" />
<include name="IStreamHandler.cs" /> <include name="IStreamHandler.cs" />

View File

@ -5,41 +5,27 @@ using System.IO;
namespace OpenSim.Framework.Servers namespace OpenSim.Framework.Servers
{ {
public class RestStreamHandler : IStreamHandler public class RestStreamHandler : BaseStreamHandler
{ {
RestMethod m_restMethod; RestMethod m_restMethod;
private string m_contentType; override public byte[] Handle(string path, Stream request )
public string ContentType
{
get { return m_contentType; }
}
private string m_httpMethod;
public string HttpMethod
{
get { return m_httpMethod; }
}
public byte[] Handle(string path, Stream request )
{ {
Encoding encoding = Encoding.UTF8; Encoding encoding = Encoding.UTF8;
StreamReader reader = new StreamReader(request, encoding); StreamReader streamReader = new StreamReader(request, encoding);
string requestBody = reader.ReadToEnd(); string requestBody = streamReader.ReadToEnd();
reader.Close(); streamReader.Close();
string responseString = m_restMethod(requestBody, path, m_httpMethod); string param = GetParam(path);
string responseString = m_restMethod(requestBody, path, param );
return Encoding.UTF8.GetBytes(responseString); return Encoding.UTF8.GetBytes(responseString);
} }
public RestStreamHandler(RestMethod restMethod, string httpMethod, string contentType) public RestStreamHandler(string httpMethod, string path, RestMethod restMethod) : base( path, httpMethod )
{ {
m_restMethod = restMethod; m_restMethod = restMethod;
m_httpMethod = httpMethod;
m_contentType = contentType;
} }
} }
} }

View File

@ -1,125 +0,0 @@
/*
* Copyright (c) Contributors, http://www.openmetaverse.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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 OpenSim Project 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 DEVELOPERS ``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 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.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using OpenSim.Framework.Servers;
namespace OpenSim.Grid.AssetServer
{
/// <summary>
/// An HTTP server for sending assets
/// </summary>
public class AssetHttpServer :BaseHttpServer
{
/// <summary>
/// Creates the new asset server
/// </summary>
/// <param name="port">Port to initalise on</param>
public AssetHttpServer(int port)
: base(port)
{
}
/// <summary>
/// Handles an HTTP request
/// </summary>
/// <param name="stateinfo">HTTP State Info</param>
public override void HandleRequest(Object stateinfo)
{
try
{
HttpListenerContext context = (HttpListenerContext)stateinfo;
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
response.KeepAlive = false;
response.SendChunked = false;
Stream body = request.InputStream;
Encoding encoding = Encoding.UTF8;
StreamReader reader = new StreamReader(body, encoding);
string requestBody = reader.ReadToEnd();
body.Close();
reader.Close();
//Console.WriteLine(request.HttpMethod + " " + request.RawUrl + " Http/" + request.ProtocolVersion.ToString() + " content type: " + request.ContentType);
//Console.WriteLine(requestBody);
string responseString = "";
switch (request.ContentType)
{
case "text/xml":
// must be XML-RPC, so pass to the XML-RPC parser
responseString = ParseXMLRPC(requestBody);
responseString = Regex.Replace(responseString, "utf-16", "utf-8");
response.AddHeader("Content-type", "text/xml");
break;
case "application/xml":
// probably LLSD we hope, otherwise it should be ignored by the parser
responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
response.AddHeader("Content-type", "application/xml");
break;
case "application/x-www-form-urlencoded":
// a form data POST so send to the REST parser
responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
response.AddHeader("Content-type", "text/plain");
break;
case null:
// must be REST or invalid crap, so pass to the REST parser
responseString = ParseREST(requestBody, request.RawUrl, request.HttpMethod);
response.AddHeader("Content-type", "text/plain");
break;
}
Encoding Windows1252Encoding = Encoding.GetEncoding(1252);
byte[] buffer = Windows1252Encoding.GetBytes(responseString);
Stream output = response.OutputStream;
response.SendChunked = false;
response.ContentLength64 = buffer.Length;
output.Write(buffer, 0, buffer.Length);
output.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}

View File

@ -33,6 +33,7 @@ using Db4objects.Db4o;
using libsecondlife; using libsecondlife;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Framework.Types; using OpenSim.Framework.Types;
using OpenSim.Framework.Servers;
namespace OpenSim.Grid.AssetServer namespace OpenSim.Grid.AssetServer
{ {
@ -76,58 +77,60 @@ namespace OpenSim.Grid.AssetServer
public void Startup() public void Startup()
{ {
m_console.Verbose( "Main.cs:Startup() - Setting up asset DB"); m_console.Verbose("Main.cs:Startup() - Setting up asset DB");
setupDB(); setupDB();
m_console.Verbose( "Main.cs:Startup() - Starting HTTP process"); m_console.Verbose("Main.cs:Startup() - Starting HTTP process");
AssetHttpServer httpServer = new AssetHttpServer(8003); BaseHttpServer httpServer = new BaseHttpServer(8003);
httpServer.AddStreamHandler( new GetAssetStreamHandler(this));
httpServer.AddStreamHandler(new PostAssetStreamHandler( this ));
httpServer.AddRestHandler("GET", "/assets/", this.assetGetMethod); //httpServer.AddRestHandler("GET", "/assets/", this.assetGetMethod);
httpServer.AddRestHandler("POST", "/assets/", this.assetPostMethod); //httpServer.AddRestHandler("POST", "/assets/", this.assetPostMethod);
httpServer.Start(); httpServer.Start();
} }
public string assetPostMethod(string requestBody, string path, string param) //public string AssetPostMethod(string requestBody, string path, string param)
{ //{
AssetBase asset = new AssetBase(); // AssetBase asset = new AssetBase();
asset.Name = ""; // asset.Name = "";
asset.FullID = new LLUUID(param); // asset.FullID = new LLUUID(param);
Encoding Windows1252Encoding = Encoding.GetEncoding(1252); // Encoding Windows1252Encoding = Encoding.GetEncoding(1252);
byte[] buffer = Windows1252Encoding.GetBytes(requestBody); // byte[] buffer = Windows1252Encoding.GetBytes(requestBody);
asset.Data = buffer; // asset.Data = buffer;
AssetStorage store = new AssetStorage(); // AssetStorage store = new AssetStorage();
store.Data = asset.Data; // store.Data = asset.Data;
store.Name = asset.Name; // store.Name = asset.Name;
store.UUID = asset.FullID; // store.UUID = asset.FullID;
db.Set(store); // db.Set(store);
db.Commit(); // db.Commit();
return ""; // return "";
} //}
public string assetGetMethod(string request, string path, string param) //public string AssetGetMethod(string request, string path, string param)
{ //{
Console.WriteLine("got a request " + param); // Console.WriteLine("got a request " + param);
byte[] assetdata = getAssetData(new LLUUID(param), false); // byte[] assetdata = GetAssetData(new LLUUID(param), false);
if (assetdata != null) // if (assetdata != null)
{ // {
Encoding Windows1252Encoding = Encoding.GetEncoding(1252); // Encoding Windows1252Encoding = Encoding.GetEncoding(1252);
string ret = Windows1252Encoding.GetString(assetdata); // string ret = Windows1252Encoding.GetString(assetdata);
//string ret = System.Text.Encoding.Unicode.GetString(assetdata); // //string ret = System.Text.Encoding.Unicode.GetString(assetdata);
return ret; // return ret;
} // }
else // else
{ // {
return ""; // return "";
} // }
} //}
public byte[] getAssetData(LLUUID assetID, bool isTexture) public byte[] GetAssetData(LLUUID assetID, bool isTexture)
{ {
bool found = false; bool found = false;
AssetStorage foundAsset = null; AssetStorage foundAsset = null;
@ -155,7 +158,7 @@ namespace OpenSim.Grid.AssetServer
try try
{ {
db = Db4oFactory.OpenFile("assets.yap"); db = Db4oFactory.OpenFile("assets.yap");
MainLog.Instance.Verbose( "Main.cs:setupDB() - creation"); MainLog.Instance.Verbose("Main.cs:setupDB() - creation");
} }
catch (Exception e) catch (Exception e)
{ {
@ -305,6 +308,21 @@ namespace OpenSim.Grid.AssetServer
return config; return config;
}*/ }*/
public void CreateAsset(LLUUID assetId, byte[] assetData)
{
AssetBase asset = new AssetBase();
asset.Name = "";
asset.FullID = assetId;
asset.Data = assetData;
AssetStorage store = new AssetStorage();
store.Data = asset.Data;
store.Name = asset.Name;
store.UUID = asset.FullID;
db.Set(store);
db.Commit();
}
public void RunCmd(string cmd, string[] cmdparams) public void RunCmd(string cmd, string[] cmdparams)
{ {
switch (cmd) switch (cmd)
@ -324,4 +342,65 @@ namespace OpenSim.Grid.AssetServer
{ {
} }
} }
public class GetAssetStreamHandler : BaseStreamHandler
{
OpenAsset_Main m_assetManager;
override public byte[] Handle(string path, Stream request)
{
string param = GetParam(path);
byte[] assetdata = m_assetManager.GetAssetData(new LLUUID(param), false);
if (assetdata != null)
{
return assetdata;
}
else
{
return new byte[]{};
}
}
public GetAssetStreamHandler(OpenAsset_Main assetManager):base( "/assets/", "GET")
{
m_assetManager = assetManager;
}
}
public class PostAssetStreamHandler : BaseStreamHandler
{
OpenAsset_Main m_assetManager;
override public byte[] Handle(string path, Stream request)
{
string param = GetParam(path);
LLUUID assetId = new LLUUID(param);
byte[] txBuffer = new byte[4096];
using( BinaryReader binReader = new BinaryReader( request ) )
{
using (MemoryStream memoryStream = new MemoryStream(4096))
{
int count;
while ((count = binReader.Read(txBuffer, 0, 4096)) > 0)
{
memoryStream.Write(txBuffer, 0, count);
}
byte[] assetData = memoryStream.ToArray();
m_assetManager.CreateAsset(assetId, assetData);
}
}
return new byte[]{};
}
public PostAssetStreamHandler( OpenAsset_Main assetManager )
: base("/assets/", "POST")
{
m_assetManager = assetManager;
}
}
} }

View File

@ -98,9 +98,6 @@
<ItemGroup> <ItemGroup>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="AssetHttpServer.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Main.cs"> <Compile Include="Main.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>

View File

@ -11,7 +11,6 @@
<resources prefix="OpenSim.Grid.AssetServer" dynamicprefix="true" > <resources prefix="OpenSim.Grid.AssetServer" dynamicprefix="true" >
</resources> </resources>
<sources failonempty="true"> <sources failonempty="true">
<include name="AssetHttpServer.cs" />
<include name="Main.cs" /> <include name="Main.cs" />
<include name="Properties/AssemblyInfo.cs" /> <include name="Properties/AssemblyInfo.cs" />
</sources> </sources>

View File

@ -127,25 +127,16 @@ namespace OpenSim.Grid.GridServer
httpServer.AddXmlRPCHandler("simulator_login", m_gridManager.XmlRpcSimulatorLoginMethod); httpServer.AddXmlRPCHandler("simulator_login", m_gridManager.XmlRpcSimulatorLoginMethod);
httpServer.AddXmlRPCHandler("map_block", m_gridManager.XmlRpcMapBlockMethod); httpServer.AddXmlRPCHandler("map_block", m_gridManager.XmlRpcMapBlockMethod);
httpServer.AddRestHandler("GET", "/sims/", m_gridManager.RestGetSimMethod); httpServer.AddStreamHandler(new RestStreamHandler("GET", "/sims/", m_gridManager.RestGetSimMethod ));
httpServer.AddRestHandler("POST", "/sims/", m_gridManager.RestSetSimMethod); httpServer.AddStreamHandler(new RestStreamHandler("POST", "/sims/", m_gridManager.RestSetSimMethod ));
httpServer.AddRestHandler("GET", "/regions/", m_gridManager.RestGetRegionMethod);
httpServer.AddRestHandler("POST", "/regions/", m_gridManager.RestSetRegionMethod);
httpServer.AddStreamHandler( new RestStreamHandler("GET", "/regions/", m_gridManager.RestGetRegionMethod ));
httpServer.AddStreamHandler( new RestStreamHandler("POST","/regions/", m_gridManager.RestSetRegionMethod ));
// lbsa71 : This code snippet taken from old http server. //httpServer.AddRestHandler("GET", "/sims/", m_gridManager.RestGetSimMethod);
// I have no idea what this was supposed to do - looks like an infinite recursion to me. //httpServer.AddRestHandler("POST", "/sims/", m_gridManager.RestSetSimMethod);
// case "regions": //httpServer.AddRestHandler("GET", "/regions/", m_gridManager.RestGetRegionMethod);
//// DIRTY HACK ALERT //httpServer.AddRestHandler("POST", "/regions/", m_gridManager.RestSetRegionMethod);
//Console.Notice("/regions/ accessed");
//TheSim = OpenGrid_Main.thegrid._regionmanager.GetProfileByHandle((ulong)Convert.ToUInt64(rest_params[1]));
//respstring = ParseREST("/regions/" + rest_params[1], requestBody, HTTPmethod);
//break;
// lbsa71 : I guess these were never used?
//Listener.Prefixes.Add("http://+:8001/gods/");
//Listener.Prefixes.Add("http://+:8001/highestuuid/");
//Listener.Prefixes.Add("http://+:8001/uuidblocks/");
httpServer.Start(); httpServer.Start();

View File

@ -105,7 +105,7 @@ namespace OpenSim.Grid.UserServer
httpServer.AddXmlRPCHandler("get_user_by_name", m_userManager.XmlRPCGetUserMethodName); httpServer.AddXmlRPCHandler("get_user_by_name", m_userManager.XmlRPCGetUserMethodName);
httpServer.AddXmlRPCHandler("get_user_by_uuid", m_userManager.XmlRPCGetUserMethodUUID); httpServer.AddXmlRPCHandler("get_user_by_uuid", m_userManager.XmlRPCGetUserMethodUUID);
httpServer.AddRestHandler("DELETE", "/usersessions/", m_userManager.RestDeleteUserSessionMethod); httpServer.AddStreamHandler( new RestStreamHandler("DELETE", "/usersessions/", m_userManager.RestDeleteUserSessionMethod ));
httpServer.Start(); httpServer.Start();
m_console.Status("Userserver 0.3 - Startup complete"); m_console.Status("Userserver 0.3 - Startup complete");

View File

@ -44,6 +44,7 @@ using OpenSim.Region.ClientStack;
using OpenSim.Region.Communications.Local; using OpenSim.Region.Communications.Local;
using OpenSim.Region.Communications.OGS1; using OpenSim.Region.Communications.OGS1;
using OpenSim.Region.Environment.Scenes; using OpenSim.Region.Environment.Scenes;
using System.Text;
namespace OpenSim namespace OpenSim
{ {
@ -84,7 +85,7 @@ namespace OpenSim
m_log = new LogBase(m_logFilename, "Region", this, m_silent); m_log = new LogBase(m_logFilename, "Region", this, m_silent);
MainLog.Instance = m_log; MainLog.Instance = m_log;
m_log.Verbose( "Main.cs:Startup() - Loading configuration"); m_log.Verbose("Main.cs:Startup() - Loading configuration");
this.serversData.InitConfig(this.m_sandbox, this.localConfig); this.serversData.InitConfig(this.m_sandbox, this.localConfig);
this.localConfig.Close();//for now we can close it as no other classes read from it , but this should change this.localConfig.Close();//for now we can close it as no other classes read from it , but this should change
@ -114,7 +115,7 @@ namespace OpenSim
this.SetupWorld(); this.SetupWorld();
m_log.Verbose( "Main.cs:Startup() - Initialising HTTP server"); m_log.Verbose("Main.cs:Startup() - Initialising HTTP server");
@ -124,7 +125,7 @@ namespace OpenSim
} }
//Start http server //Start http server
m_log.Verbose( "Main.cs:Startup() - Starting HTTP server"); m_log.Verbose("Main.cs:Startup() - Starting HTTP server");
httpServer.Start(); httpServer.Start();
// Start UDP servers // Start UDP servers
@ -145,7 +146,7 @@ namespace OpenSim
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Error( e.Message + "\nSorry, could not setup local cache"); m_log.Error(e.Message + "\nSorry, could not setup local cache");
Environment.Exit(1); Environment.Exit(1);
} }
@ -160,7 +161,7 @@ namespace OpenSim
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Error( e.Message + "\nSorry, could not setup remote cache"); m_log.Error(e.Message + "\nSorry, could not setup remote cache");
Environment.Exit(1); Environment.Exit(1);
} }
} }
@ -226,7 +227,7 @@ namespace OpenSim
LocalWorld.LoadStorageDLL("OpenSim.Region.Storage.LocalStorageDb4o.dll"); //all these dll names shouldn't be hard coded. LocalWorld.LoadStorageDLL("OpenSim.Region.Storage.LocalStorageDb4o.dll"); //all these dll names shouldn't be hard coded.
LocalWorld.LoadWorldMap(); LocalWorld.LoadWorldMap();
m_log.Verbose( "Main.cs:Startup() - Starting up messaging system"); m_log.Verbose("Main.cs:Startup() - Starting up messaging system");
LocalWorld.PhysScene = this.physManager.GetPhysicsScene(this.m_physicsEngine); LocalWorld.PhysScene = this.physManager.GetPhysicsScene(this.m_physicsEngine);
LocalWorld.PhysScene.SetTerrain(LocalWorld.Terrain.getHeights1D()); LocalWorld.PhysScene.SetTerrain(LocalWorld.Terrain.getHeights1D());
LocalWorld.LoadPrimsFromStorage(); LocalWorld.LoadPrimsFromStorage();
@ -244,21 +245,36 @@ namespace OpenSim
} }
} }
private class SimStatusHandler : IStreamHandler
{
public byte[] Handle(string path, Stream request)
{
return Encoding.UTF8.GetBytes("OK");
}
public string ContentType
{
get { return "text/plain"; }
}
public string HttpMethod
{
get { return "GET"; }
}
public string Path
{
get { return "/simstatus/"; }
}
}
protected override void SetupHttpListener() protected override void SetupHttpListener()
{ {
httpServer = new BaseHttpServer(this.serversData.HttpListenerPort); //regionData[0].IPListenPort); httpServer = new BaseHttpServer(this.serversData.HttpListenerPort); //regionData[0].IPListenPort);
if (!this.m_sandbox) if (!this.m_sandbox)
{ {
httpServer.AddStreamHandler( new SimStatusHandler() );
// we are in Grid mode so set a XmlRpc handler to handle "expect_user" calls from the user server
httpServer.AddRestHandler("GET", "/simstatus/",
delegate(string request, string path, string param)
{
return "OK";
});
} }
} }
@ -340,7 +356,7 @@ namespace OpenSim
switch (attri) switch (attri)
{ {
default: default:
m_log.Warn( "Main.cs: SetupFromConfig() - Invalid value for PhysicsEngine attribute, terminating"); m_log.Warn("Main.cs: SetupFromConfig() - Invalid value for PhysicsEngine attribute, terminating");
Environment.Exit(1); Environment.Exit(1);
break; break;
@ -376,11 +392,11 @@ namespace OpenSim
/// </summary> /// </summary>
public virtual void Shutdown() public virtual void Shutdown()
{ {
m_log.Verbose( "Main.cs:Shutdown() - Closing all threads"); m_log.Verbose("Main.cs:Shutdown() - Closing all threads");
m_log.Verbose( "Main.cs:Shutdown() - Killing listener thread"); m_log.Verbose("Main.cs:Shutdown() - Killing listener thread");
m_log.Verbose( "Main.cs:Shutdown() - Killing clients"); m_log.Verbose("Main.cs:Shutdown() - Killing clients");
// IMPLEMENT THIS // IMPLEMENT THIS
m_log.Verbose( "Main.cs:Shutdown() - Closing console and terminating"); m_log.Verbose("Main.cs:Shutdown() - Closing console and terminating");
for (int i = 0; i < m_localWorld.Count; i++) for (int i = 0; i < m_localWorld.Count; i++)
{ {
((Scene)m_localWorld[i]).Close(); ((Scene)m_localWorld[i]).Close();
@ -400,8 +416,8 @@ namespace OpenSim
switch (command) switch (command)
{ {
case "help": case "help":
m_log.Error( "show users - show info about connected users"); m_log.Error("show users - show info about connected users");
m_log.Error( "shutdown - disconnect all clients and shutdown"); m_log.Error("shutdown - disconnect all clients and shutdown");
break; break;
case "show": case "show":
@ -415,7 +431,7 @@ namespace OpenSim
string result = ""; string result = "";
for (int i = 0; i < m_localWorld.Count; i++) for (int i = 0; i < m_localWorld.Count; i++)
{ {
if (!((Scene)m_localWorld[i]).Terrain.RunTerrainCmd(cmdparams, ref result,m_localWorld[i].RegionInfo.RegionName)) if (!((Scene)m_localWorld[i]).Terrain.RunTerrainCmd(cmdparams, ref result, m_localWorld[i].RegionInfo.RegionName))
{ {
m_log.Error(result); m_log.Error(result);
} }
@ -427,7 +443,7 @@ namespace OpenSim
break; break;
default: default:
m_log.Error( "Unknown command"); m_log.Error("Unknown command");
break; break;
} }
} }
@ -441,12 +457,12 @@ namespace OpenSim
switch (ShowWhat) switch (ShowWhat)
{ {
case "uptime": case "uptime":
m_log.Error( "OpenSim has been running since " + startuptime.ToString()); m_log.Error("OpenSim has been running since " + startuptime.ToString());
m_log.Error( "That is " + (DateTime.Now - startuptime).ToString()); m_log.Error("That is " + (DateTime.Now - startuptime).ToString());
break; break;
case "users": case "users":
ScenePresence TempAv; ScenePresence TempAv;
m_log.Error( String.Format("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16}{5,-16}{6,-16}", "Firstname", "Lastname", "Agent ID", "Session ID", "Circuit", "IP","World")); m_log.Error(String.Format("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16}{5,-16}{6,-16}", "Firstname", "Lastname", "Agent ID", "Session ID", "Circuit", "IP", "World"));
for (int i = 0; i < m_localWorld.Count; i++) for (int i = 0; i < m_localWorld.Count; i++)
{ {
foreach (libsecondlife.LLUUID UUID in ((Scene)m_localWorld[i]).Entities.Keys) foreach (libsecondlife.LLUUID UUID in ((Scene)m_localWorld[i]).Entities.Keys)

View File

@ -82,7 +82,7 @@ namespace OpenSim.Region.Capabilities
private void AddCapsHandler( BaseHttpServer httpListener, string path, RestMethod restMethod ) private void AddCapsHandler( BaseHttpServer httpListener, string path, RestMethod restMethod )
{ {
string capsBase = "/CAPS/" + m_capsObjectPath; string capsBase = "/CAPS/" + m_capsObjectPath;
httpListener.AddStreamHandler(capsBase + path, new RestStreamHandler(restMethod, "POST", "application/xml")); httpListener.AddStreamHandler(new RestStreamHandler("POST", capsBase + path, restMethod));
} }
/// <summary> /// <summary>
@ -211,9 +211,11 @@ namespace OpenSim.Region.Capabilities
string res = ""; string res = "";
LLUUID newAsset = LLUUID.Random(); LLUUID newAsset = LLUUID.Random();
LLUUID newInvItem = LLUUID.Random(); LLUUID newInvItem = LLUUID.Random();
string uploaderPath = m_capsObjectPath + Util.RandomClass.Next(5000, 8000).ToString("0000"); string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
AssetUploader uploader = new AssetUploader(newAsset, newInvItem, uploaderPath, this.httpListener); AssetUploader uploader = new AssetUploader(newAsset, newInvItem, uploaderPath, this.httpListener);
httpListener.AddRestHandler("POST", "/CAPS/" + uploaderPath, uploader.uploaderCaps);
AddCapsHandler( httpListener, uploaderPath, uploader.uploaderCaps);
string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + "/CAPS/" + uploaderPath; string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + "/CAPS/" + uploaderPath;
//Console.WriteLine("uploader url is " + uploaderURL); //Console.WriteLine("uploader url is " + uploaderURL);
res += "<llsd><map>"; res += "<llsd><map>";
@ -269,7 +271,8 @@ namespace OpenSim.Region.Capabilities
res += "</map></llsd>"; res += "</map></llsd>";
// Console.WriteLine("asset " + newAssetID.ToStringHyphenated() + " , inventory item " + inv.ToStringHyphenated()); // Console.WriteLine("asset " + newAssetID.ToStringHyphenated() + " , inventory item " + inv.ToStringHyphenated());
httpListener.RemoveRestHandler("POST", "/CAPS/" + uploaderPath); httpListener.RemoveStreamHandler("POST", "/CAPS/" + uploaderPath);
if (OnUpLoad != null) if (OnUpLoad != null)
{ {
OnUpLoad(newAssetID, inv, data); OnUpLoad(newAssetID, inv, data);