* 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,7 +187,7 @@ 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;
@ -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
{ {
@ -80,54 +81,56 @@ namespace OpenSim.Grid.AssetServer
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;
@ -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
{ {
@ -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";
});
} }
} }

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);