Committing the changed tree
parent
acfb5051cd
commit
ec0d2c28fa
|
@ -0,0 +1,510 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Timers;
|
||||||
|
using log4net;
|
||||||
|
using log4net.Appender;
|
||||||
|
using log4net.Core;
|
||||||
|
using log4net.Repository;
|
||||||
|
using OpenSim.Framework.Console;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Framework.Statistics;
|
||||||
|
using Timer=System.Timers.Timer;
|
||||||
|
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenMetaverse.StructuredData;
|
||||||
|
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Common base for the main OpenSimServers (user, grid, inventory, region, etc)
|
||||||
|
/// </summary>
|
||||||
|
public abstract class BaseOpenSimServer
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This will control a periodic log printout of the current 'show stats' (if they are active) for this
|
||||||
|
/// server.
|
||||||
|
/// </summary>
|
||||||
|
private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000);
|
||||||
|
|
||||||
|
protected CommandConsole m_console;
|
||||||
|
protected OpenSimAppender m_consoleAppender;
|
||||||
|
protected IAppender m_logFileAppender = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Time at which this server was started
|
||||||
|
/// </summary>
|
||||||
|
protected DateTime m_startuptime;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Record the initial startup directory for info purposes
|
||||||
|
/// </summary>
|
||||||
|
protected string m_startupDirectory = Environment.CurrentDirectory;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Server version information. Usually VersionInfo + information about svn revision, operating system, etc.
|
||||||
|
/// </summary>
|
||||||
|
protected string m_version;
|
||||||
|
|
||||||
|
protected string m_pidFile = String.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Random uuid for private data
|
||||||
|
/// </summary>
|
||||||
|
protected string m_osSecret = String.Empty;
|
||||||
|
|
||||||
|
protected BaseHttpServer m_httpServer;
|
||||||
|
public BaseHttpServer HttpServer
|
||||||
|
{
|
||||||
|
get { return m_httpServer; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Holds the non-viewer statistics collection object for this service/server
|
||||||
|
/// </summary>
|
||||||
|
protected IStatsCollector m_stats;
|
||||||
|
|
||||||
|
public BaseOpenSimServer()
|
||||||
|
{
|
||||||
|
m_startuptime = DateTime.Now;
|
||||||
|
m_version = VersionInfo.Version;
|
||||||
|
|
||||||
|
// Random uuid for private data
|
||||||
|
m_osSecret = UUID.Random().ToString();
|
||||||
|
|
||||||
|
m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics);
|
||||||
|
m_periodicDiagnosticsTimer.Enabled = true;
|
||||||
|
|
||||||
|
// Add ourselves to thread monitoring. This thread will go on to become the console listening thread
|
||||||
|
Thread.CurrentThread.Name = "ConsoleThread";
|
||||||
|
ThreadTracker.Add(Thread.CurrentThread);
|
||||||
|
|
||||||
|
ILoggerRepository repository = LogManager.GetRepository();
|
||||||
|
IAppender[] appenders = repository.GetAppenders();
|
||||||
|
|
||||||
|
foreach (IAppender appender in appenders)
|
||||||
|
{
|
||||||
|
if (appender.Name == "LogFileAppender")
|
||||||
|
{
|
||||||
|
m_logFileAppender = appender;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Must be overriden by child classes for their own server specific startup behaviour.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void StartupSpecific()
|
||||||
|
{
|
||||||
|
if (m_console != null)
|
||||||
|
{
|
||||||
|
ILoggerRepository repository = LogManager.GetRepository();
|
||||||
|
IAppender[] appenders = repository.GetAppenders();
|
||||||
|
|
||||||
|
foreach (IAppender appender in appenders)
|
||||||
|
{
|
||||||
|
if (appender.Name == "Console")
|
||||||
|
{
|
||||||
|
m_consoleAppender = (OpenSimAppender)appender;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null == m_consoleAppender)
|
||||||
|
{
|
||||||
|
Notice("No appender named Console found (see the log4net config file for this executable)!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_consoleAppender.Console = m_console;
|
||||||
|
|
||||||
|
// If there is no threshold set then the threshold is effectively everything.
|
||||||
|
if (null == m_consoleAppender.Threshold)
|
||||||
|
m_consoleAppender.Threshold = Level.All;
|
||||||
|
|
||||||
|
Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_console.Commands.AddCommand("base", false, "quit",
|
||||||
|
"quit",
|
||||||
|
"Quit the application", HandleQuit);
|
||||||
|
|
||||||
|
m_console.Commands.AddCommand("base", false, "shutdown",
|
||||||
|
"shutdown",
|
||||||
|
"Quit the application", HandleQuit);
|
||||||
|
|
||||||
|
m_console.Commands.AddCommand("base", false, "set log level",
|
||||||
|
"set log level <level>",
|
||||||
|
"Set the console logging level", HandleLogLevel);
|
||||||
|
|
||||||
|
m_console.Commands.AddCommand("base", false, "show info",
|
||||||
|
"show info",
|
||||||
|
"Show general information", HandleShow);
|
||||||
|
|
||||||
|
m_console.Commands.AddCommand("base", false, "show stats",
|
||||||
|
"show stats",
|
||||||
|
"Show statistics", HandleShow);
|
||||||
|
|
||||||
|
m_console.Commands.AddCommand("base", false, "show threads",
|
||||||
|
"show threads",
|
||||||
|
"Show thread status", HandleShow);
|
||||||
|
|
||||||
|
m_console.Commands.AddCommand("base", false, "show uptime",
|
||||||
|
"show uptime",
|
||||||
|
"Show server uptime", HandleShow);
|
||||||
|
|
||||||
|
m_console.Commands.AddCommand("base", false, "show version",
|
||||||
|
"show version",
|
||||||
|
"Show server version", HandleShow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should be overriden and referenced by descendents if they need to perform extra shutdown processing
|
||||||
|
/// </summary>
|
||||||
|
public virtual void ShutdownSpecific() {}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides a list of help topics that are available. Overriding classes should append their topics to the
|
||||||
|
/// information returned when the base method is called.
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
/// <returns>
|
||||||
|
/// A list of strings that represent different help topics on which more information is available
|
||||||
|
/// </returns>
|
||||||
|
protected virtual List<string> GetHelpTopics() { return new List<string>(); }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Print statistics to the logfile, if they are active
|
||||||
|
/// </summary>
|
||||||
|
protected void LogDiagnostics(object source, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder("DIAGNOSTICS\n\n");
|
||||||
|
sb.Append(GetUptimeReport());
|
||||||
|
|
||||||
|
if (m_stats != null)
|
||||||
|
{
|
||||||
|
sb.Append(m_stats.Report());
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.Append(Environment.NewLine);
|
||||||
|
sb.Append(GetThreadsReport());
|
||||||
|
|
||||||
|
m_log.Debug(sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a report about the registered threads in this server.
|
||||||
|
/// </summary>
|
||||||
|
protected string GetThreadsReport()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
List<Thread> threads = ThreadTracker.GetThreads();
|
||||||
|
if (threads == null)
|
||||||
|
{
|
||||||
|
sb.Append("Thread tracking is only enabled in DEBUG mode.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.Append(threads.Count + " threads are being tracked:" + Environment.NewLine);
|
||||||
|
foreach (Thread t in threads)
|
||||||
|
{
|
||||||
|
if (t.IsAlive)
|
||||||
|
{
|
||||||
|
sb.Append(
|
||||||
|
"ID: " + t.ManagedThreadId + ", Name: " + t.Name + ", Alive: " + t.IsAlive
|
||||||
|
+ ", Pri: " + t.Priority + ", State: " + t.ThreadState + Environment.NewLine);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sb.Append("ID: " + t.ManagedThreadId + ", Name: " + t.Name + ", DEAD" + Environment.NewLine);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
sb.Append("THREAD ERROR" + Environment.NewLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return a report about the uptime of this server
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected string GetUptimeReport()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder(String.Format("Time now is {0}\n", DateTime.Now));
|
||||||
|
sb.Append(String.Format("Server has been running since {0}, {1}\n", m_startuptime.DayOfWeek, m_startuptime));
|
||||||
|
sb.Append(String.Format("That is an elapsed time of {0}\n", DateTime.Now - m_startuptime));
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Performs initialisation of the scene, such as loading configuration from disk.
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Startup()
|
||||||
|
{
|
||||||
|
m_log.Info("[STARTUP]: Beginning startup processing");
|
||||||
|
|
||||||
|
EnhanceVersionInformation();
|
||||||
|
|
||||||
|
m_log.Info("[STARTUP]: Version: " + m_version + "\n");
|
||||||
|
|
||||||
|
StartupSpecific();
|
||||||
|
|
||||||
|
TimeSpan timeTaken = DateTime.Now - m_startuptime;
|
||||||
|
|
||||||
|
m_log.InfoFormat("[STARTUP]: Startup took {0}m {1}s", timeTaken.Minutes, timeTaken.Seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should be overriden and referenced by descendents if they need to perform extra shutdown processing
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Shutdown()
|
||||||
|
{
|
||||||
|
ShutdownSpecific();
|
||||||
|
|
||||||
|
m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting...");
|
||||||
|
RemovePIDFile();
|
||||||
|
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleQuit(string module, string[] args)
|
||||||
|
{
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleLogLevel(string module, string[] cmd)
|
||||||
|
{
|
||||||
|
if (null == m_consoleAppender)
|
||||||
|
{
|
||||||
|
Notice("No appender named Console found (see the log4net config file for this executable)!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string rawLevel = cmd[3];
|
||||||
|
|
||||||
|
ILoggerRepository repository = LogManager.GetRepository();
|
||||||
|
Level consoleLevel = repository.LevelMap[rawLevel];
|
||||||
|
|
||||||
|
if (consoleLevel != null)
|
||||||
|
m_consoleAppender.Threshold = consoleLevel;
|
||||||
|
else
|
||||||
|
Notice(
|
||||||
|
String.Format(
|
||||||
|
"{0} is not a valid logging level. Valid logging levels are ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF",
|
||||||
|
rawLevel));
|
||||||
|
|
||||||
|
Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Show help information
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="helpArgs"></param>
|
||||||
|
protected virtual void ShowHelp(string[] helpArgs)
|
||||||
|
{
|
||||||
|
Notice("");
|
||||||
|
|
||||||
|
if (helpArgs.Length == 0)
|
||||||
|
{
|
||||||
|
Notice("set log level [level] - change the console logging level only. For example, off or debug.");
|
||||||
|
Notice("show info - show server information (e.g. startup path).");
|
||||||
|
|
||||||
|
if (m_stats != null)
|
||||||
|
Notice("show stats - show statistical information for this server");
|
||||||
|
|
||||||
|
Notice("show threads - list tracked threads");
|
||||||
|
Notice("show uptime - show server startup time and uptime.");
|
||||||
|
Notice("show version - show server version.");
|
||||||
|
Notice("");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void HandleShow(string module, string[] cmd)
|
||||||
|
{
|
||||||
|
List<string> args = new List<string>(cmd);
|
||||||
|
|
||||||
|
args.RemoveAt(0);
|
||||||
|
|
||||||
|
string[] showParams = args.ToArray();
|
||||||
|
|
||||||
|
switch (showParams[0])
|
||||||
|
{
|
||||||
|
case "info":
|
||||||
|
Notice("Version: " + m_version);
|
||||||
|
Notice("Startup directory: " + m_startupDirectory);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "stats":
|
||||||
|
if (m_stats != null)
|
||||||
|
Notice(m_stats.Report());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "threads":
|
||||||
|
Notice(GetThreadsReport());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "uptime":
|
||||||
|
Notice(GetUptimeReport());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "version":
|
||||||
|
Notice(
|
||||||
|
String.Format(
|
||||||
|
"Version: {0} (interface version {1})", m_version, VersionInfo.MajorInterfaceVersion));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Console output is only possible if a console has been established.
|
||||||
|
/// That is something that cannot be determined within this class. So
|
||||||
|
/// all attempts to use the console MUST be verified.
|
||||||
|
/// </summary>
|
||||||
|
protected void Notice(string msg)
|
||||||
|
{
|
||||||
|
if (m_console != null)
|
||||||
|
{
|
||||||
|
m_console.Notice(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enhance the version string with extra information if it's available.
|
||||||
|
/// </summary>
|
||||||
|
protected void EnhanceVersionInformation()
|
||||||
|
{
|
||||||
|
string buildVersion = string.Empty;
|
||||||
|
|
||||||
|
// Add subversion revision information if available
|
||||||
|
// Try file "svn_revision" in the current directory first, then the .svn info.
|
||||||
|
// This allows to make the revision available in simulators not running from the source tree.
|
||||||
|
// FIXME: Making an assumption about the directory we're currently in - we do this all over the place
|
||||||
|
// elsewhere as well
|
||||||
|
string svnRevisionFileName = "svn_revision";
|
||||||
|
string svnFileName = ".svn/entries";
|
||||||
|
string inputLine;
|
||||||
|
int strcmp;
|
||||||
|
|
||||||
|
if (File.Exists(svnRevisionFileName))
|
||||||
|
{
|
||||||
|
StreamReader RevisionFile = File.OpenText(svnRevisionFileName);
|
||||||
|
buildVersion = RevisionFile.ReadLine();
|
||||||
|
buildVersion.Trim();
|
||||||
|
RevisionFile.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(buildVersion) && File.Exists(svnFileName))
|
||||||
|
{
|
||||||
|
StreamReader EntriesFile = File.OpenText(svnFileName);
|
||||||
|
inputLine = EntriesFile.ReadLine();
|
||||||
|
while (inputLine != null)
|
||||||
|
{
|
||||||
|
// using the dir svn revision at the top of entries file
|
||||||
|
strcmp = String.Compare(inputLine, "dir");
|
||||||
|
if (strcmp == 0)
|
||||||
|
{
|
||||||
|
buildVersion = EntriesFile.ReadLine();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inputLine = EntriesFile.ReadLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EntriesFile.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_version += string.IsNullOrEmpty(buildVersion) ? " " : ("." + buildVersion + " ").Substring(0, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void CreatePIDFile(string path)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
|
||||||
|
FileStream fs = File.Create(path);
|
||||||
|
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
|
||||||
|
Byte[] buf = enc.GetBytes(pidstring);
|
||||||
|
fs.Write(buf, 0, buf.Length);
|
||||||
|
fs.Close();
|
||||||
|
m_pidFile = path;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string osSecret {
|
||||||
|
// Secret uuid for the simulator
|
||||||
|
get { return m_osSecret; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public string StatReport(OSHttpRequest httpRequest)
|
||||||
|
{
|
||||||
|
return m_stats.XReport((DateTime.Now - m_startuptime).ToString() , m_version );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void RemovePIDFile()
|
||||||
|
{
|
||||||
|
if (m_pidFile != String.Empty)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Delete(m_pidFile);
|
||||||
|
m_pidFile = String.Empty;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,218 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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 OpenSimulator 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.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using log4net;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Data;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Framework.Statistics;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers
|
||||||
|
{
|
||||||
|
public class CachedGetAssetStreamHandler : BaseStreamHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
// private OpenAsset_Main m_assetManager;
|
||||||
|
private IAssetCache m_assetProvider;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="assetManager"></param>
|
||||||
|
/// <param name="assetProvider"></param>
|
||||||
|
public CachedGetAssetStreamHandler(IAssetCache assetProvider)
|
||||||
|
: base("GET", "/assets")
|
||||||
|
{
|
||||||
|
m_log.Info("[REST]: In Get Request");
|
||||||
|
// m_assetManager = assetManager;
|
||||||
|
m_assetProvider = assetProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override byte[] Handle(string path, Stream request,
|
||||||
|
OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
string param = GetParam(path);
|
||||||
|
byte[] result = new byte[] { };
|
||||||
|
|
||||||
|
string[] p = param.Split(new char[] { '/', '?', '&' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
if (p.Length > 0)
|
||||||
|
{
|
||||||
|
UUID assetID = UUID.Zero;
|
||||||
|
|
||||||
|
if (!UUID.TryParse(p[0], out assetID))
|
||||||
|
{
|
||||||
|
m_log.InfoFormat(
|
||||||
|
"[REST]: GET:/asset ignoring request with malformed UUID {0}", p[0]);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StatsManager.AssetStats != null)
|
||||||
|
StatsManager.AssetStats.AddRequest();
|
||||||
|
|
||||||
|
AssetBase asset = m_assetProvider.GetAsset(assetID,true); // TODO IsTexture should be deduced from loaded asset. It is not used in this case.
|
||||||
|
|
||||||
|
if (asset != null)
|
||||||
|
{
|
||||||
|
// if (asset.ContainsReferences)
|
||||||
|
// {
|
||||||
|
// asset.Data = ProcessOutgoingAssetData(asset.Data);
|
||||||
|
// }
|
||||||
|
if (p.Length > 1 && p[1] == "data")
|
||||||
|
{
|
||||||
|
httpResponse.StatusCode = (int)HttpStatusCode.OK;
|
||||||
|
httpResponse.ContentType = SLAssetTypeToContentType(asset.Type);
|
||||||
|
result = asset.Data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XmlSerializer xs = new XmlSerializer(typeof(AssetBase));
|
||||||
|
MemoryStream ms = new MemoryStream();
|
||||||
|
XmlTextWriter xw = new XmlTextWriter(ms, Encoding.UTF8);
|
||||||
|
xw.Formatting = Formatting.Indented;
|
||||||
|
xs.Serialize(xw, asset);
|
||||||
|
xw.Flush();
|
||||||
|
|
||||||
|
ms.Seek(0, SeekOrigin.Begin);
|
||||||
|
//StreamReader sr = new StreamReader(ms);
|
||||||
|
|
||||||
|
result = ms.GetBuffer();
|
||||||
|
|
||||||
|
Array.Resize<byte>(ref result, (int)ms.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (StatsManager.AssetStats != null)
|
||||||
|
StatsManager.AssetStats.AddNotFoundRequest();
|
||||||
|
|
||||||
|
m_log.InfoFormat("[REST]: GET:/asset failed to find {0}", assetID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// private byte[] ProcessOutgoingAssetData(byte[] assetData)
|
||||||
|
// {
|
||||||
|
// string data = Encoding.ASCII.GetString(assetData);
|
||||||
|
|
||||||
|
// data = ProcessAssetDataString(data);
|
||||||
|
|
||||||
|
// return Encoding.ASCII.GetBytes(data);
|
||||||
|
// }
|
||||||
|
|
||||||
|
public string ProcessAssetDataString(string data)
|
||||||
|
{
|
||||||
|
Regex regex = new Regex("(creator_id|owner_id)\\s+(\\S+)");
|
||||||
|
|
||||||
|
// IUserService userService = null;
|
||||||
|
|
||||||
|
data = regex.Replace(data, delegate(Match m)
|
||||||
|
{
|
||||||
|
string result = String.Empty;
|
||||||
|
|
||||||
|
// string key = m.Groups[1].Captures[0].Value;
|
||||||
|
//
|
||||||
|
// string value = m.Groups[2].Captures[0].Value;
|
||||||
|
//
|
||||||
|
// Guid userUri;
|
||||||
|
//
|
||||||
|
// switch (key)
|
||||||
|
// {
|
||||||
|
// case "creator_id":
|
||||||
|
// userUri = new Guid(value);
|
||||||
|
// // result = "creator_url " + userService(userService, userUri);
|
||||||
|
// break;
|
||||||
|
//
|
||||||
|
// case "owner_id":
|
||||||
|
// userUri = new Guid(value);
|
||||||
|
// // result = "owner_url " + ResolveUserUri(userService, userUri);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string SLAssetTypeToContentType(int assetType)
|
||||||
|
{
|
||||||
|
switch (assetType)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return "image/jp2";
|
||||||
|
case 1:
|
||||||
|
return "application/ogg";
|
||||||
|
case 2:
|
||||||
|
return "application/x-metaverse-callingcard";
|
||||||
|
case 3:
|
||||||
|
return "application/x-metaverse-landmark";
|
||||||
|
case 5:
|
||||||
|
return "application/x-metaverse-clothing";
|
||||||
|
case 6:
|
||||||
|
return "application/x-metaverse-primitive";
|
||||||
|
case 7:
|
||||||
|
return "application/x-metaverse-notecard";
|
||||||
|
case 8:
|
||||||
|
return "application/x-metaverse-folder";
|
||||||
|
case 10:
|
||||||
|
return "application/x-metaverse-lsl";
|
||||||
|
case 11:
|
||||||
|
return "application/x-metaverse-lso";
|
||||||
|
case 12:
|
||||||
|
return "image/tga";
|
||||||
|
case 13:
|
||||||
|
return "application/x-metaverse-bodypart";
|
||||||
|
case 17:
|
||||||
|
return "audio/x-wav";
|
||||||
|
case 19:
|
||||||
|
return "image/jpeg";
|
||||||
|
case 20:
|
||||||
|
return "application/x-metaverse-animation";
|
||||||
|
case 21:
|
||||||
|
return "application/x-metaverse-gesture";
|
||||||
|
case 22:
|
||||||
|
return "application/x-metaverse-simstate";
|
||||||
|
default:
|
||||||
|
return "application/octet-stream";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.
|
||||||
|
*/
|
|
@ -0,0 +1,217 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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 OpenSimulator 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.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using log4net;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Data;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Framework.Statistics;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers
|
||||||
|
{
|
||||||
|
public class GetAssetStreamHandler : BaseStreamHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
// private OpenAsset_Main m_assetManager;
|
||||||
|
private IAssetDataPlugin m_assetProvider;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="assetManager"></param>
|
||||||
|
/// <param name="assetProvider"></param>
|
||||||
|
public GetAssetStreamHandler(IAssetDataPlugin assetProvider)
|
||||||
|
: base("GET", "/assets")
|
||||||
|
{
|
||||||
|
m_log.Info("[REST]: In Get Request");
|
||||||
|
// m_assetManager = assetManager;
|
||||||
|
m_assetProvider = assetProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override byte[] Handle(string path, Stream request,
|
||||||
|
OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
string param = GetParam(path);
|
||||||
|
byte[] result = new byte[] { };
|
||||||
|
|
||||||
|
string[] p = param.Split(new char[] { '/', '?', '&' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
if (p.Length > 0)
|
||||||
|
{
|
||||||
|
UUID assetID = UUID.Zero;
|
||||||
|
|
||||||
|
if (!UUID.TryParse(p[0], out assetID))
|
||||||
|
{
|
||||||
|
m_log.InfoFormat(
|
||||||
|
"[REST]: GET:/asset ignoring request with malformed UUID {0}", p[0]);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StatsManager.AssetStats != null)
|
||||||
|
StatsManager.AssetStats.AddRequest();
|
||||||
|
|
||||||
|
AssetBase asset = m_assetProvider.FetchAsset(assetID);
|
||||||
|
if (asset != null)
|
||||||
|
{
|
||||||
|
// if (asset.ContainsReferences)
|
||||||
|
// {
|
||||||
|
// asset.Data = ProcessOutgoingAssetData(asset.Data);
|
||||||
|
// }
|
||||||
|
if (p.Length > 1 && p[1] == "data")
|
||||||
|
{
|
||||||
|
httpResponse.StatusCode = (int)HttpStatusCode.OK;
|
||||||
|
httpResponse.ContentType = SLAssetTypeToContentType(asset.Type);
|
||||||
|
result = asset.Data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XmlSerializer xs = new XmlSerializer(typeof(AssetBase));
|
||||||
|
MemoryStream ms = new MemoryStream();
|
||||||
|
XmlTextWriter xw = new XmlTextWriter(ms, Encoding.UTF8);
|
||||||
|
xw.Formatting = Formatting.Indented;
|
||||||
|
xs.Serialize(xw, asset);
|
||||||
|
xw.Flush();
|
||||||
|
|
||||||
|
ms.Seek(0, SeekOrigin.Begin);
|
||||||
|
//StreamReader sr = new StreamReader(ms);
|
||||||
|
|
||||||
|
result = ms.GetBuffer();
|
||||||
|
|
||||||
|
Array.Resize<byte>(ref result, (int)ms.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (StatsManager.AssetStats != null)
|
||||||
|
StatsManager.AssetStats.AddNotFoundRequest();
|
||||||
|
|
||||||
|
m_log.InfoFormat("[REST]: GET:/asset failed to find {0}", assetID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// private byte[] ProcessOutgoingAssetData(byte[] assetData)
|
||||||
|
// {
|
||||||
|
// string data = Encoding.ASCII.GetString(assetData);
|
||||||
|
|
||||||
|
// data = ProcessAssetDataString(data);
|
||||||
|
|
||||||
|
// return Encoding.ASCII.GetBytes(data);
|
||||||
|
// }
|
||||||
|
|
||||||
|
public string ProcessAssetDataString(string data)
|
||||||
|
{
|
||||||
|
Regex regex = new Regex("(creator_id|owner_id)\\s+(\\S+)");
|
||||||
|
|
||||||
|
// IUserService userService = null;
|
||||||
|
|
||||||
|
data = regex.Replace(data, delegate(Match m)
|
||||||
|
{
|
||||||
|
string result = String.Empty;
|
||||||
|
|
||||||
|
// string key = m.Groups[1].Captures[0].Value;
|
||||||
|
//
|
||||||
|
// string value = m.Groups[2].Captures[0].Value;
|
||||||
|
//
|
||||||
|
// Guid userUri;
|
||||||
|
//
|
||||||
|
// switch (key)
|
||||||
|
// {
|
||||||
|
// case "creator_id":
|
||||||
|
// userUri = new Guid(value);
|
||||||
|
// // result = "creator_url " + userService(userService, userUri);
|
||||||
|
// break;
|
||||||
|
//
|
||||||
|
// case "owner_id":
|
||||||
|
// userUri = new Guid(value);
|
||||||
|
// // result = "owner_url " + ResolveUserUri(userService, userUri);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string SLAssetTypeToContentType(int assetType)
|
||||||
|
{
|
||||||
|
switch (assetType)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return "image/jp2";
|
||||||
|
case 1:
|
||||||
|
return "application/ogg";
|
||||||
|
case 2:
|
||||||
|
return "application/x-metaverse-callingcard";
|
||||||
|
case 3:
|
||||||
|
return "application/x-metaverse-landmark";
|
||||||
|
case 5:
|
||||||
|
return "application/x-metaverse-clothing";
|
||||||
|
case 6:
|
||||||
|
return "application/x-metaverse-primitive";
|
||||||
|
case 7:
|
||||||
|
return "application/x-metaverse-notecard";
|
||||||
|
case 8:
|
||||||
|
return "application/x-metaverse-folder";
|
||||||
|
case 10:
|
||||||
|
return "application/x-metaverse-lsl";
|
||||||
|
case 11:
|
||||||
|
return "application/x-metaverse-lso";
|
||||||
|
case 12:
|
||||||
|
return "image/tga";
|
||||||
|
case 13:
|
||||||
|
return "application/x-metaverse-bodypart";
|
||||||
|
case 17:
|
||||||
|
return "audio/x-wav";
|
||||||
|
case 19:
|
||||||
|
return "image/jpeg";
|
||||||
|
case 20:
|
||||||
|
return "application/x-metaverse-animation";
|
||||||
|
case 21:
|
||||||
|
return "application/x-metaverse-gesture";
|
||||||
|
case 22:
|
||||||
|
return "application/x-metaverse-simstate";
|
||||||
|
default:
|
||||||
|
return "application/octet-stream";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.Collections;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public abstract class BaseHTTPHandler : BaseRequestHandler, IGenericHTTPHandler
|
||||||
|
{
|
||||||
|
public abstract Hashtable Handle(string path, Hashtable Request);
|
||||||
|
|
||||||
|
protected BaseHTTPHandler(string httpMethod, string path)
|
||||||
|
: base(httpMethod, path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public class BaseRequestHandler
|
||||||
|
{
|
||||||
|
public virtual string ContentType
|
||||||
|
{
|
||||||
|
get { return "application/xml"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly string m_httpMethod;
|
||||||
|
|
||||||
|
public virtual string HttpMethod
|
||||||
|
{
|
||||||
|
get { return m_httpMethod; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly string m_path;
|
||||||
|
|
||||||
|
protected BaseRequestHandler(string httpMethod, string path)
|
||||||
|
{
|
||||||
|
m_httpMethod = httpMethod;
|
||||||
|
m_path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual string Path
|
||||||
|
{
|
||||||
|
get { return m_path; }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected string GetParam(string path)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return path.Substring(m_path.Length);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.IO;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public abstract class BaseStreamHandler : BaseRequestHandler, IStreamedRequestHandler
|
||||||
|
{
|
||||||
|
public abstract byte[] Handle(string path, Stream request,
|
||||||
|
OSHttpRequest httpRequest, OSHttpResponse httpResponse);
|
||||||
|
|
||||||
|
protected BaseStreamHandler(string httpMethod, string path) : base(httpMethod, path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public delegate string BinaryMethod(byte[] data, string path, string param);
|
||||||
|
|
||||||
|
public class BinaryStreamHandler : BaseStreamHandler
|
||||||
|
{
|
||||||
|
private BinaryMethod m_method;
|
||||||
|
|
||||||
|
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
byte[] data = ReadFully(request);
|
||||||
|
string param = GetParam(path);
|
||||||
|
string responseString = m_method(data, path, param);
|
||||||
|
|
||||||
|
return Encoding.UTF8.GetBytes(responseString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod)
|
||||||
|
: base(httpMethod, path)
|
||||||
|
{
|
||||||
|
m_method = binaryMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] ReadFully(Stream stream)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[32768];
|
||||||
|
using (MemoryStream ms = new MemoryStream())
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int read = stream.Read(buffer, 0, buffer.Length);
|
||||||
|
|
||||||
|
if (read <= 0)
|
||||||
|
{
|
||||||
|
return ms.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
ms.Write(buffer, 0, read);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.Collections;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public delegate Hashtable GenericHTTPMethod(Hashtable request);
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public interface IHttpAgentHandler
|
||||||
|
{
|
||||||
|
bool Handle(OSHttpRequest req, OSHttpResponse resp);
|
||||||
|
bool Match(OSHttpRequest req, OSHttpResponse resp);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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 Nwc.XmlRpc;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interface to OpenSimulator's built in HTTP server. Use this to register handlers (http, llsd, xmlrpc, etc.)
|
||||||
|
/// for given URLs.
|
||||||
|
/// </summary>
|
||||||
|
public interface IHttpServer
|
||||||
|
{
|
||||||
|
uint SSLPort { get; }
|
||||||
|
string SSLCommonName { get; }
|
||||||
|
|
||||||
|
uint Port { get; }
|
||||||
|
bool UseSSL { get; }
|
||||||
|
|
||||||
|
// Note that the agent string is provided simply to differentiate
|
||||||
|
// the handlers - it is NOT required to be an actual agent header
|
||||||
|
// value.
|
||||||
|
bool AddAgentHandler(string agent, IHttpAgentHandler handler);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add a handler for an HTTP request
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
/// This handler can actually be invoked either as
|
||||||
|
///
|
||||||
|
/// http://<hostname>:<port>/?method=<methodName>
|
||||||
|
///
|
||||||
|
/// or
|
||||||
|
///
|
||||||
|
/// http://<hostname>:<port><method>
|
||||||
|
///
|
||||||
|
/// if the method name starts with a slash. For example, AddHTTPHandler("/object/", ...) on a standalone region
|
||||||
|
/// server will register a handler that can be invoked with either
|
||||||
|
///
|
||||||
|
/// http://localhost:9000/?method=/object/
|
||||||
|
///
|
||||||
|
/// or
|
||||||
|
///
|
||||||
|
/// http://localhost:9000/object/
|
||||||
|
///
|
||||||
|
/// <param name="methodName"></param>
|
||||||
|
/// <param name="handler"></param>
|
||||||
|
/// <returns>
|
||||||
|
/// true if the handler was successfully registered, false if a handler with the same name already existed.
|
||||||
|
/// </returns>
|
||||||
|
bool AddHTTPHandler(string methodName, GenericHTTPMethod handler);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a LLSD handler, yay.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">/resource/ path</param>
|
||||||
|
/// <param name="handler">handle the LLSD response</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool AddLLSDHandler(string path, LLSDMethod handler);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add a stream handler to the http server. If the handler already exists, then nothing happens.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handler"></param>
|
||||||
|
void AddStreamHandler(IRequestHandler handler);
|
||||||
|
|
||||||
|
bool AddXmlRPCHandler(string method, XmlRpcMethod handler);
|
||||||
|
bool AddXmlRPCHandler(string method, XmlRpcMethod handler, bool keepAlive);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the XML RPC handler for given method name
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="method">Name of the method</param>
|
||||||
|
/// <returns>Returns null if not found</returns>
|
||||||
|
XmlRpcMethod GetXmlRPCHandler(string method);
|
||||||
|
|
||||||
|
bool SetDefaultLLSDHandler(DefaultLLSDMethod handler);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove the agent if it is registered.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="agent"></param>
|
||||||
|
/// <param name="handler"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool RemoveAgentHandler(string agent, IHttpAgentHandler handler);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove an HTTP handler
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="httpMethod"></param>
|
||||||
|
/// <param name="path"></param>
|
||||||
|
void RemoveHTTPHandler(string httpMethod, string path);
|
||||||
|
|
||||||
|
bool RemoveLLSDHandler(string path, LLSDMethod handler);
|
||||||
|
|
||||||
|
void RemoveStreamHandler(string httpMethod, string path);
|
||||||
|
|
||||||
|
string GetHTTP404(string host);
|
||||||
|
|
||||||
|
string GetHTTP500();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.Collections;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public interface IRequestHandler
|
||||||
|
{
|
||||||
|
// Return response content type
|
||||||
|
string ContentType { get; }
|
||||||
|
|
||||||
|
// Return required http method
|
||||||
|
string HttpMethod { get; }
|
||||||
|
|
||||||
|
// Return path
|
||||||
|
string Path { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IStreamedRequestHandler : IRequestHandler
|
||||||
|
{
|
||||||
|
// Handle request stream, return byte array
|
||||||
|
byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IStreamHandler : IRequestHandler
|
||||||
|
{
|
||||||
|
// Handle request stream, return byte array
|
||||||
|
void Handle(string path, Stream request, Stream response, OSHttpRequest httpReqbuest, OSHttpResponse httpResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IGenericHTTPHandler : IRequestHandler
|
||||||
|
{
|
||||||
|
Hashtable Handle(string path, Hashtable request);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,120 @@
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
|
||||||
|
<PropertyGroup>
|
||||||
|
<ProjectType>Local</ProjectType>
|
||||||
|
<ProductVersion>8.0.50727</ProductVersion>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<ProjectGuid>{8673D009-0000-0000-0000-000000000000}</ProjectGuid>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ApplicationIcon></ApplicationIcon>
|
||||||
|
<AssemblyKeyContainerName>
|
||||||
|
</AssemblyKeyContainerName>
|
||||||
|
<AssemblyName>OpenSim.Framework.Servers.Interfaces</AssemblyName>
|
||||||
|
<DefaultClientScript>JScript</DefaultClientScript>
|
||||||
|
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
|
||||||
|
<DefaultTargetSchema>IE50</DefaultTargetSchema>
|
||||||
|
<DelaySign>false</DelaySign>
|
||||||
|
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder></AppDesignerFolder>
|
||||||
|
<RootNamespace>OpenSim.Framework.Servers.Interfaces</RootNamespace>
|
||||||
|
<StartupObject></StartupObject>
|
||||||
|
<StartArguments></StartArguments>
|
||||||
|
<FileUpgradeFlags>
|
||||||
|
</FileUpgradeFlags>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
|
||||||
|
<BaseAddress>285212672</BaseAddress>
|
||||||
|
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
||||||
|
<ConfigurationOverrideFile>
|
||||||
|
</ConfigurationOverrideFile>
|
||||||
|
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
||||||
|
<DocumentationFile></DocumentationFile>
|
||||||
|
<DebugSymbols>True</DebugSymbols>
|
||||||
|
<FileAlignment>4096</FileAlignment>
|
||||||
|
<Optimize>False</Optimize>
|
||||||
|
<OutputPath>../../../../bin/</OutputPath>
|
||||||
|
<RegisterForComInterop>False</RegisterForComInterop>
|
||||||
|
<RemoveIntegerChecks>False</RemoveIntegerChecks>
|
||||||
|
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<NoStdLib>False</NoStdLib>
|
||||||
|
<NoWarn></NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
|
||||||
|
<BaseAddress>285212672</BaseAddress>
|
||||||
|
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
||||||
|
<ConfigurationOverrideFile>
|
||||||
|
</ConfigurationOverrideFile>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<DocumentationFile></DocumentationFile>
|
||||||
|
<DebugSymbols>False</DebugSymbols>
|
||||||
|
<FileAlignment>4096</FileAlignment>
|
||||||
|
<Optimize>True</Optimize>
|
||||||
|
<OutputPath>../../../../bin/</OutputPath>
|
||||||
|
<RegisterForComInterop>False</RegisterForComInterop>
|
||||||
|
<RemoveIntegerChecks>False</RemoveIntegerChecks>
|
||||||
|
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<NoStdLib>False</NoStdLib>
|
||||||
|
<NoWarn></NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="HttpServer_OpenSim.dll" >
|
||||||
|
<Name>HttpServer_OpenSim.dll</Name>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="log4net.dll" >
|
||||||
|
<Name>log4net.dll</Name>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="OpenMetaverse.StructuredData.dll" >
|
||||||
|
<Name>OpenMetaverse.StructuredData.dll</Name>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="OpenMetaverseTypes.dll" >
|
||||||
|
<Name>OpenMetaverseTypes.dll</Name>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" >
|
||||||
|
<Name>System</Name>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml" >
|
||||||
|
<Name>System.Xml</Name>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="XMLRPC.dll" >
|
||||||
|
<Name>XMLRPC.dll</Name>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="../../../Data/OpenSim.Data.csproj">
|
||||||
|
<Name>OpenSim.Data</Name>
|
||||||
|
<Project>{B75A430B-0000-0000-0000-000000000000}</Project>
|
||||||
|
<Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
|
||||||
|
<Private>False</Private>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="IHttpAgentHandler.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="IHttpServer.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="IStreamHandler.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<PreBuildEvent>
|
||||||
|
</PreBuildEvent>
|
||||||
|
<PostBuildEvent>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ReferencePath>/root/opensim-commit/bin/</ReferencePath>
|
||||||
|
<LastOpenVersion>8.0.50727</LastOpenVersion>
|
||||||
|
<ProjectView>ProjectFiles</ProjectView>
|
||||||
|
<ProjectTrust>0</ProjectTrust>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition = " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
|
||||||
|
<PropertyGroup Condition = " '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
|
||||||
|
</Project>
|
|
@ -0,0 +1,54 @@
|
||||||
|
<?xml version="1.0" ?>
|
||||||
|
<project name="OpenSim.Framework.Servers.Interfaces" default="build">
|
||||||
|
<target name="build">
|
||||||
|
<echo message="Build Directory is ${project::get-base-directory()}/${build.dir}" />
|
||||||
|
<mkdir dir="${project::get-base-directory()}/${build.dir}" />
|
||||||
|
<copy todir="${project::get-base-directory()}/${build.dir}" flatten="true">
|
||||||
|
<fileset basedir="${project::get-base-directory()}">
|
||||||
|
</fileset>
|
||||||
|
</copy>
|
||||||
|
<copy todir="${project::get-base-directory()}/${build.dir}">
|
||||||
|
<fileset basedir=".">
|
||||||
|
</fileset>
|
||||||
|
</copy>
|
||||||
|
<csc target="library" debug="${build.debug}" unsafe="False" warnaserror="False" define="TRACE;DEBUG" nostdlib="False" main="" output="${project::get-base-directory()}/${build.dir}/${project::get-name()}.dll">
|
||||||
|
<resources prefix="OpenSim.Framework.Servers.Interfaces" dynamicprefix="true" >
|
||||||
|
</resources>
|
||||||
|
<sources failonempty="true">
|
||||||
|
<include name="IHttpAgentHandler.cs" />
|
||||||
|
<include name="IHttpServer.cs" />
|
||||||
|
<include name="IStreamHandler.cs" />
|
||||||
|
</sources>
|
||||||
|
<references basedir="${project::get-base-directory()}">
|
||||||
|
<lib>
|
||||||
|
<include name="${project::get-base-directory()}" />
|
||||||
|
<include name="${project::get-base-directory()}/../../../../bin" />
|
||||||
|
</lib>
|
||||||
|
<include name="../../../../bin/HttpServer_OpenSim.dll" />
|
||||||
|
<include name="../../../../bin/log4net.dll" />
|
||||||
|
<include name="../../../../bin/OpenMetaverse.StructuredData.dll" />
|
||||||
|
<include name="../../../../bin/OpenMetaverseTypes.dll" />
|
||||||
|
<include name="OpenSim.Data.dll" />
|
||||||
|
<include name="System.dll" />
|
||||||
|
<include name="System.Xml.dll" />
|
||||||
|
<include name="../../../../bin/XMLRPC.dll" />
|
||||||
|
</references>
|
||||||
|
</csc>
|
||||||
|
<echo message="Copying from [${project::get-base-directory()}/${build.dir}/] to [${project::get-base-directory()}/../../../../bin/" />
|
||||||
|
<mkdir dir="${project::get-base-directory()}/../../../../bin/"/>
|
||||||
|
<copy todir="${project::get-base-directory()}/../../../../bin/">
|
||||||
|
<fileset basedir="${project::get-base-directory()}/${build.dir}/" >
|
||||||
|
<include name="*.dll"/>
|
||||||
|
<include name="*.exe"/>
|
||||||
|
<include name="*.mdb" if='${build.debug}'/>
|
||||||
|
<include name="*.pdb" if='${build.debug}'/>
|
||||||
|
</fileset>
|
||||||
|
</copy>
|
||||||
|
</target>
|
||||||
|
<target name="clean">
|
||||||
|
<delete dir="${bin.dir}" failonerror="false" />
|
||||||
|
<delete dir="${obj.dir}" failonerror="false" />
|
||||||
|
</target>
|
||||||
|
<target name="doc" description="Creates documentation.">
|
||||||
|
</target>
|
||||||
|
</project>
|
|
@ -0,0 +1,34 @@
|
||||||
|
<Project name="OpenSim.Framework.Servers.Interfaces" description="" standardNamespace="OpenSim.Framework.Servers.Interfaces" newfilesearch="None" enableviewstate="True" fileversion="2.0" language="C#" clr-version="Net_2_0" ctype="DotNetProject">
|
||||||
|
<Configurations active="Debug">
|
||||||
|
<Configuration name="Debug" ctype="DotNetProjectConfiguration">
|
||||||
|
<Output directory="./../../../../bin/" assembly="OpenSim.Framework.Servers.Interfaces" executeScript="" executeBeforeBuild="" executeAfterBuild="" executeBeforeBuildArguments="" executeAfterBuildArguments="" />
|
||||||
|
<Build debugmode="True" target="Library" />
|
||||||
|
<Execution runwithwarnings="True" consolepause="True" runtime="MsNet" clr-version="Net_2_0" />
|
||||||
|
<CodeGeneration compiler="Csc" warninglevel="4" nowarn="" includedebuginformation="True" optimize="False" unsafecodeallowed="False" generateoverflowchecks="False" mainclass="" target="Library" definesymbols="TRACE;DEBUG" generatexmldocumentation="False" win32Icon="" ctype="CSharpCompilerParameters" />
|
||||||
|
</Configuration>
|
||||||
|
<Configuration name="Release" ctype="DotNetProjectConfiguration">
|
||||||
|
<Output directory="./../../../../bin/" assembly="OpenSim.Framework.Servers.Interfaces" executeScript="" executeBeforeBuild="" executeAfterBuild="" executeBeforeBuildArguments="" executeAfterBuildArguments="" />
|
||||||
|
<Build debugmode="True" target="Library" />
|
||||||
|
<Execution runwithwarnings="True" consolepause="True" runtime="MsNet" clr-version="Net_2_0" />
|
||||||
|
<CodeGeneration compiler="Csc" warninglevel="4" nowarn="" includedebuginformation="False" optimize="True" unsafecodeallowed="False" generateoverflowchecks="False" mainclass="" target="Library" definesymbols="TRACE" generatexmldocumentation="False" win32Icon="" ctype="CSharpCompilerParameters" />
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<DeploymentInformation target="" script="" strategy="File">
|
||||||
|
<excludeFiles />
|
||||||
|
</DeploymentInformation>
|
||||||
|
<Contents>
|
||||||
|
<File name="./IHttpAgentHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./IHttpServer.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./IStreamHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
</Contents>
|
||||||
|
<References>
|
||||||
|
<ProjectReference type="Assembly" refto="../../../../bin/HttpServer_OpenSim.dll" localcopy="False" />
|
||||||
|
<ProjectReference type="Assembly" refto="../../../../bin/log4net.dll" localcopy="False" />
|
||||||
|
<ProjectReference type="Assembly" refto="../../../../bin/OpenMetaverse.StructuredData.dll" localcopy="False" />
|
||||||
|
<ProjectReference type="Assembly" refto="../../../../bin/OpenMetaverseTypes.dll" localcopy="False" />
|
||||||
|
<ProjectReference type="Project" localcopy="False" refto="OpenSim.Data" />
|
||||||
|
<ProjectReference type="Gac" localcopy="False" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||||
|
<ProjectReference type="Gac" localcopy="False" refto="System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||||
|
<ProjectReference type="Assembly" refto="../../../../bin/XMLRPC.dll" localcopy="False" />
|
||||||
|
</References>
|
||||||
|
</Project>
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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 OpenMetaverse.StructuredData;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public delegate OSD LLSDMethod( string path, OSD request, string endpoint );
|
||||||
|
public delegate OSD DefaultLLSDMethod(OSD request);
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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 OpenMetaverse.StructuredData;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public delegate OSD LLSDMethodString(OSD request, string thePath);
|
||||||
|
}
|
|
@ -0,0 +1,183 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
/// <sumary>
|
||||||
|
/// Any OSHttpHandler must return one of the following results:
|
||||||
|
/// <list type = "table">
|
||||||
|
/// <listheader>
|
||||||
|
/// <term>result code</term>
|
||||||
|
/// <description>meaning</description>
|
||||||
|
/// </listheader>
|
||||||
|
/// <item>
|
||||||
|
/// <term>Pass</term>
|
||||||
|
/// <description>handler did not process the request</request>
|
||||||
|
/// </item>
|
||||||
|
/// <item>
|
||||||
|
/// <term>Done</term>
|
||||||
|
/// <description>handler did process the request, OSHttpServer
|
||||||
|
/// can clean up and close the request</request>
|
||||||
|
/// </item>
|
||||||
|
/// </list>
|
||||||
|
/// </summary>
|
||||||
|
public enum OSHttpHandlerResult
|
||||||
|
{
|
||||||
|
Unprocessed,
|
||||||
|
Pass,
|
||||||
|
Done,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An OSHttpHandler that matches on the "content-type" header can
|
||||||
|
/// supply an OSHttpContentTypeChecker delegate which will be
|
||||||
|
/// invoked by the request matcher in OSHttpRequestPump.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>true if the handler is interested in the content;
|
||||||
|
/// false otherwise</returns>
|
||||||
|
public delegate bool OSHttpContentTypeChecker(OSHttpRequest req);
|
||||||
|
|
||||||
|
public abstract class OSHttpHandler
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Regular expression used to match against method of
|
||||||
|
/// the incoming HTTP request. If you want to match any string
|
||||||
|
/// either use '.*' or null. To match on the empty string use
|
||||||
|
/// '^$'.
|
||||||
|
/// </summary>
|
||||||
|
public virtual Regex Method
|
||||||
|
{
|
||||||
|
get { return _method; }
|
||||||
|
}
|
||||||
|
protected Regex _method;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Regular expression used to match against path of the
|
||||||
|
/// incoming HTTP request. If you want to match any string
|
||||||
|
/// either use '.*' or null. To match on the emtpy string use
|
||||||
|
/// '^$'.
|
||||||
|
/// </summary>
|
||||||
|
public virtual Regex Path
|
||||||
|
{
|
||||||
|
get { return _path; }
|
||||||
|
}
|
||||||
|
protected Regex _path;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dictionary of (query name, regular expression) tuples,
|
||||||
|
/// allowing us to match on URI query fields.
|
||||||
|
/// </summary>
|
||||||
|
public virtual Dictionary<string, Regex> Query
|
||||||
|
{
|
||||||
|
get { return _query; }
|
||||||
|
}
|
||||||
|
protected Dictionary<string, Regex> _query;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dictionary of (header name, regular expression) tuples,
|
||||||
|
/// allowing us to match on HTTP header fields.
|
||||||
|
/// </summary>
|
||||||
|
public virtual Dictionary<string, Regex> Headers
|
||||||
|
{
|
||||||
|
get { return _headers; }
|
||||||
|
}
|
||||||
|
protected Dictionary<string, Regex> _headers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dictionary of (header name, regular expression) tuples,
|
||||||
|
/// allowing us to match on HTTP header fields.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This feature is currently not implemented as it requires
|
||||||
|
/// (trivial) changes to HttpServer.HttpListener that have not
|
||||||
|
/// been implemented.
|
||||||
|
/// </remarks>
|
||||||
|
public virtual Regex IPEndPointWhitelist
|
||||||
|
{
|
||||||
|
get { return _ipEndPointRegex; }
|
||||||
|
}
|
||||||
|
protected Regex _ipEndPointRegex;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Base class constructor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">null or path regex</param>
|
||||||
|
/// <param name="headers">null or dictionary of header
|
||||||
|
/// regexs</param>
|
||||||
|
/// <param name="contentType">null or content type
|
||||||
|
/// regex</param>
|
||||||
|
/// <param name="whitelist">null or IP address regex</param>
|
||||||
|
public OSHttpHandler(Regex method, Regex path, Dictionary<string, Regex> query,
|
||||||
|
Dictionary<string, Regex> headers, Regex contentType, Regex whitelist)
|
||||||
|
{
|
||||||
|
_method = method;
|
||||||
|
_path = path;
|
||||||
|
_query = query;
|
||||||
|
_ipEndPointRegex = whitelist;
|
||||||
|
|
||||||
|
if (null == _headers && null != contentType)
|
||||||
|
{
|
||||||
|
_headers = new Dictionary<string, Regex>();
|
||||||
|
_headers.Add("content-type", contentType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Process an incoming OSHttpRequest that matched our
|
||||||
|
/// requirements.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// OSHttpHandlerResult.Pass if we are after all not
|
||||||
|
/// interested in the request; OSHttpHandlerResult.Done if we
|
||||||
|
/// did process the request.
|
||||||
|
/// </returns>
|
||||||
|
public abstract OSHttpHandlerResult Process(OSHttpRequest request);
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
sw.WriteLine("{0}", base.ToString());
|
||||||
|
sw.WriteLine(" method regex {0}", null == Method ? "null" : Method.ToString());
|
||||||
|
sw.WriteLine(" path regex {0}", null == Path ? "null": Path.ToString());
|
||||||
|
foreach (string tag in Headers.Keys)
|
||||||
|
{
|
||||||
|
sw.WriteLine(" header {0} : {1}", tag, Headers[tag].ToString());
|
||||||
|
}
|
||||||
|
sw.WriteLine(" IP whitelist {0}", null == IPEndPointWhitelist ? "null" : IPEndPointWhitelist.ToString());
|
||||||
|
sw.WriteLine();
|
||||||
|
sw.Close();
|
||||||
|
return sw.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,145 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Xml;
|
||||||
|
using log4net;
|
||||||
|
using Nwc.XmlRpc;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public delegate XmlRpcResponse OSHttpHttpProcessor(XmlRpcRequest request);
|
||||||
|
|
||||||
|
public class OSHttpHttpHandler: OSHttpHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
// contains handler for processing HTTP Request
|
||||||
|
private GenericHTTPMethod _handler;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiate an HTTP handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handler">a GenericHTTPMethod</param>
|
||||||
|
/// <param name="method">null or HTTP method regex</param>
|
||||||
|
/// <param name="path">null or path regex</param>
|
||||||
|
/// <param name="query">null or dictionary with query regexs</param>
|
||||||
|
/// <param name="headers">null or dictionary with header
|
||||||
|
/// regexs</param>
|
||||||
|
/// <param name="whitelist">null or IP address whitelist</param>
|
||||||
|
public OSHttpHttpHandler(GenericHTTPMethod handler, Regex method, Regex path,
|
||||||
|
Dictionary<string, Regex> query,
|
||||||
|
Dictionary<string, Regex> headers, Regex whitelist)
|
||||||
|
: base(method, path, query, headers, new Regex(@"^text/html", RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
whitelist)
|
||||||
|
{
|
||||||
|
_handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiate an HTTP handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handler">a GenericHTTPMethod</param>
|
||||||
|
public OSHttpHttpHandler(GenericHTTPMethod handler)
|
||||||
|
: this(handler, new Regex(@"^GET$", RegexOptions.IgnoreCase | RegexOptions.Compiled), null, null, null, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked by OSHttpRequestPump.
|
||||||
|
/// </summary>
|
||||||
|
public override OSHttpHandlerResult Process(OSHttpRequest request)
|
||||||
|
{
|
||||||
|
// call handler method
|
||||||
|
Hashtable responseData = _handler(request.Query);
|
||||||
|
|
||||||
|
int responseCode = (int)responseData["int_response_code"];
|
||||||
|
string responseString = (string)responseData["str_response_string"];
|
||||||
|
string contentType = (string)responseData["content_type"];
|
||||||
|
|
||||||
|
//Even though only one other part of the entire code uses HTTPHandlers, we shouldn't expect this
|
||||||
|
//and should check for NullReferenceExceptions
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(contentType))
|
||||||
|
{
|
||||||
|
contentType = "text/html";
|
||||||
|
}
|
||||||
|
|
||||||
|
OSHttpResponse response = new OSHttpResponse(request);
|
||||||
|
|
||||||
|
// We're forgoing the usual error status codes here because the client
|
||||||
|
// ignores anything but 200 and 301
|
||||||
|
|
||||||
|
response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
|
||||||
|
|
||||||
|
if (responseCode == (int)OSHttpStatusCode.RedirectMovedPermanently)
|
||||||
|
{
|
||||||
|
response.RedirectLocation = (string)responseData["str_redirect_location"];
|
||||||
|
response.StatusCode = responseCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
response.AddHeader("Content-type", contentType);
|
||||||
|
|
||||||
|
byte[] buffer;
|
||||||
|
|
||||||
|
if (!contentType.Contains("image"))
|
||||||
|
{
|
||||||
|
buffer = Encoding.UTF8.GetBytes(responseString);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer = Convert.FromBase64String(responseString);
|
||||||
|
}
|
||||||
|
|
||||||
|
response.SendChunked = false;
|
||||||
|
response.ContentLength64 = buffer.Length;
|
||||||
|
response.ContentEncoding = Encoding.UTF8;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
response.Body.Write(buffer, 0, buffer.Length);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.ErrorFormat("[OSHttpHttpHandler]: Error: {0}", ex.Message);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
response.Send();
|
||||||
|
}
|
||||||
|
|
||||||
|
return OSHttpHandlerResult.Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,228 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using HttpServer;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public class OSHttpRequest
|
||||||
|
{
|
||||||
|
private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
protected IHttpRequest _request = null;
|
||||||
|
protected IHttpClientContext _context = null;
|
||||||
|
|
||||||
|
public string[] AcceptTypes
|
||||||
|
{
|
||||||
|
get { return _request.AcceptTypes; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Encoding ContentEncoding
|
||||||
|
{
|
||||||
|
get { return _contentEncoding; }
|
||||||
|
}
|
||||||
|
private Encoding _contentEncoding;
|
||||||
|
|
||||||
|
public long ContentLength
|
||||||
|
{
|
||||||
|
get { return _request.ContentLength; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public long ContentLength64
|
||||||
|
{
|
||||||
|
get { return ContentLength; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ContentType
|
||||||
|
{
|
||||||
|
get { return _contentType; }
|
||||||
|
}
|
||||||
|
private string _contentType;
|
||||||
|
|
||||||
|
public bool HasEntityBody
|
||||||
|
{
|
||||||
|
get { return _request.ContentLength != 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public NameValueCollection Headers
|
||||||
|
{
|
||||||
|
get { return _request.Headers; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string HttpMethod
|
||||||
|
{
|
||||||
|
get { return _request.Method; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream InputStream
|
||||||
|
{
|
||||||
|
get { return _request.Body; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSecured
|
||||||
|
{
|
||||||
|
get { return _context.Secured; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool KeepAlive
|
||||||
|
{
|
||||||
|
get { return ConnectionType.KeepAlive == _request.Connection; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public NameValueCollection QueryString
|
||||||
|
{
|
||||||
|
get { return _queryString; }
|
||||||
|
}
|
||||||
|
private NameValueCollection _queryString;
|
||||||
|
|
||||||
|
public Hashtable Query
|
||||||
|
{
|
||||||
|
get { return _query; }
|
||||||
|
}
|
||||||
|
private Hashtable _query;
|
||||||
|
|
||||||
|
public string RawUrl
|
||||||
|
{
|
||||||
|
get { return _request.Uri.AbsolutePath; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPEndPoint RemoteIPEndPoint
|
||||||
|
{
|
||||||
|
get { return _remoteIPEndPoint; }
|
||||||
|
}
|
||||||
|
private IPEndPoint _remoteIPEndPoint;
|
||||||
|
|
||||||
|
public Uri Url
|
||||||
|
{
|
||||||
|
get { return _request.Uri; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string UserAgent
|
||||||
|
{
|
||||||
|
get { return _userAgent; }
|
||||||
|
}
|
||||||
|
private string _userAgent;
|
||||||
|
|
||||||
|
internal IHttpRequest IHttpRequest
|
||||||
|
{
|
||||||
|
get { return _request; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal IHttpClientContext IHttpClientContext
|
||||||
|
{
|
||||||
|
get { return _context; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Internal whiteboard for handlers to store temporary stuff
|
||||||
|
/// into.
|
||||||
|
/// </summary>
|
||||||
|
internal Dictionary<string, object> Whiteboard
|
||||||
|
{
|
||||||
|
get { return _whiteboard; }
|
||||||
|
}
|
||||||
|
private Dictionary<string, object> _whiteboard = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
|
||||||
|
public OSHttpRequest() {}
|
||||||
|
|
||||||
|
public OSHttpRequest(IHttpClientContext context, IHttpRequest req)
|
||||||
|
{
|
||||||
|
_request = req;
|
||||||
|
_context = context;
|
||||||
|
|
||||||
|
if (null != req.Headers["content-encoding"])
|
||||||
|
_contentEncoding = Encoding.GetEncoding(_request.Headers["content-encoding"]);
|
||||||
|
if (null != req.Headers["content-type"])
|
||||||
|
_contentType = _request.Headers["content-type"];
|
||||||
|
if (null != req.Headers["user-agent"])
|
||||||
|
_userAgent = req.Headers["user-agent"];
|
||||||
|
if (null != req.Headers["remote_addr"])
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IPAddress addr = IPAddress.Parse(req.Headers["remote_addr"]);
|
||||||
|
int port = Int32.Parse(req.Headers["remote_port"]);
|
||||||
|
_remoteIPEndPoint = new IPEndPoint(addr, port);
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
_log.ErrorFormat("[OSHttpRequest]: format exception on addr/port {0}:{1}, ignoring",
|
||||||
|
req.Headers["remote_addr"], req.Headers["remote_port"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_queryString = new NameValueCollection();
|
||||||
|
_query = new Hashtable();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (HttpInputItem item in req.QueryString)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_queryString.Add(item.Name, item.Value);
|
||||||
|
_query[item.Name] = item.Value;
|
||||||
|
}
|
||||||
|
catch (InvalidCastException)
|
||||||
|
{
|
||||||
|
_log.DebugFormat("[OSHttpRequest]: error parsing {0} query item, skipping it", item.Name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
_log.ErrorFormat("[OSHttpRequest]: Error parsing querystring");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
StringBuilder me = new StringBuilder();
|
||||||
|
me.Append(String.Format("OSHttpRequest: {0} {1}\n", HttpMethod, RawUrl));
|
||||||
|
foreach (string k in Headers.AllKeys)
|
||||||
|
{
|
||||||
|
me.Append(String.Format(" {0}: {1}\n", k, Headers[k]));
|
||||||
|
}
|
||||||
|
if (null != RemoteIPEndPoint)
|
||||||
|
{
|
||||||
|
me.Append(String.Format(" IP: {0}\n", RemoteIPEndPoint));
|
||||||
|
}
|
||||||
|
|
||||||
|
return me.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,298 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// #define DEBUGGING
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading;
|
||||||
|
using log4net;
|
||||||
|
using HttpServer;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An OSHttpRequestPump fetches incoming OSHttpRequest objects
|
||||||
|
/// from the OSHttpRequestQueue and feeds them to all subscribed
|
||||||
|
/// parties. Each OSHttpRequestPump encapsulates one thread to do
|
||||||
|
/// the work and there is a fixed number of pumps for each
|
||||||
|
/// OSHttpServer object.
|
||||||
|
/// </summary>
|
||||||
|
public class OSHttpRequestPump
|
||||||
|
{
|
||||||
|
private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
protected OSHttpServer _server;
|
||||||
|
protected OSHttpRequestQueue _queue;
|
||||||
|
protected Thread _engine;
|
||||||
|
|
||||||
|
private int _id;
|
||||||
|
|
||||||
|
public string EngineID
|
||||||
|
{
|
||||||
|
get { return String.Format("{0} pump {1}", _server.EngineID, _id); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public OSHttpRequestPump(OSHttpServer server, OSHttpRequestQueue queue, int id)
|
||||||
|
{
|
||||||
|
_server = server;
|
||||||
|
_queue = queue;
|
||||||
|
_id = id;
|
||||||
|
|
||||||
|
_engine = new Thread(new ThreadStart(Engine));
|
||||||
|
_engine.Name = EngineID;
|
||||||
|
_engine.IsBackground = true;
|
||||||
|
_engine.Start();
|
||||||
|
|
||||||
|
ThreadTracker.Add(_engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OSHttpRequestPump[] Pumps(OSHttpServer server, OSHttpRequestQueue queue, int poolSize)
|
||||||
|
{
|
||||||
|
OSHttpRequestPump[] pumps = new OSHttpRequestPump[poolSize];
|
||||||
|
for (int i = 0; i < pumps.Length; i++)
|
||||||
|
{
|
||||||
|
pumps[i] = new OSHttpRequestPump(server, queue, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pumps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
_engine = new Thread(new ThreadStart(Engine));
|
||||||
|
_engine.Name = EngineID;
|
||||||
|
_engine.IsBackground = true;
|
||||||
|
_engine.Start();
|
||||||
|
|
||||||
|
ThreadTracker.Add(_engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Engine()
|
||||||
|
{
|
||||||
|
OSHttpRequest req = null;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// dequeue an OSHttpRequest from OSHttpServer's
|
||||||
|
// request queue
|
||||||
|
req = _queue.Dequeue();
|
||||||
|
|
||||||
|
// get a copy of the list of registered handlers
|
||||||
|
List<OSHttpHandler> handlers = _server.OSHttpHandlers;
|
||||||
|
|
||||||
|
// prune list and have it sorted from most
|
||||||
|
// specific to least specific
|
||||||
|
handlers = MatchHandlers(req, handlers);
|
||||||
|
|
||||||
|
// process req: we try each handler in turn until
|
||||||
|
// we are either out of handlers or get back a
|
||||||
|
// Pass or Done
|
||||||
|
OSHttpHandlerResult rc = OSHttpHandlerResult.Unprocessed;
|
||||||
|
foreach (OSHttpHandler h in handlers)
|
||||||
|
{
|
||||||
|
rc = h.Process(req);
|
||||||
|
|
||||||
|
// Pass: handler did not process the request,
|
||||||
|
// try next handler
|
||||||
|
if (OSHttpHandlerResult.Pass == rc) continue;
|
||||||
|
|
||||||
|
// Handled: handler has processed the request
|
||||||
|
if (OSHttpHandlerResult.Done == rc) break;
|
||||||
|
|
||||||
|
// hmm, something went wrong
|
||||||
|
throw new Exception(String.Format("[{0}] got unexpected OSHttpHandlerResult {1}", EngineID, rc));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OSHttpHandlerResult.Unprocessed == rc)
|
||||||
|
{
|
||||||
|
_log.InfoFormat("[{0}] OSHttpHandler: no handler registered for {1}", EngineID, req);
|
||||||
|
|
||||||
|
// set up response header
|
||||||
|
OSHttpResponse resp = new OSHttpResponse(req);
|
||||||
|
resp.StatusCode = (int)OSHttpStatusCode.ClientErrorNotFound;
|
||||||
|
resp.StatusDescription = String.Format("no handler on call for {0}", req);
|
||||||
|
resp.ContentType = "text/html";
|
||||||
|
|
||||||
|
// add explanatory message
|
||||||
|
StreamWriter body = new StreamWriter(resp.Body);
|
||||||
|
body.WriteLine("<html>");
|
||||||
|
body.WriteLine("<header><title>Ooops...</title><header>");
|
||||||
|
body.WriteLine(String.Format("<body><p>{0}</p></body>", resp.StatusDescription));
|
||||||
|
body.WriteLine("</html>");
|
||||||
|
body.Flush();
|
||||||
|
|
||||||
|
// and ship it back
|
||||||
|
resp.Send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_log.DebugFormat("[{0}] OSHttpHandler problem: {1}", EngineID, e.ToString());
|
||||||
|
_log.ErrorFormat("[{0}] OSHttpHandler problem: {1}", EngineID, e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<OSHttpHandler> MatchHandlers(OSHttpRequest req, List<OSHttpHandler> handlers)
|
||||||
|
{
|
||||||
|
Dictionary<OSHttpHandler, int> scoredHandlers = new Dictionary<OSHttpHandler, int>();
|
||||||
|
|
||||||
|
_log.DebugFormat("[{0}] MatchHandlers for {1}", EngineID, req);
|
||||||
|
foreach (OSHttpHandler h in handlers)
|
||||||
|
{
|
||||||
|
// initial anchor
|
||||||
|
scoredHandlers[h] = 0;
|
||||||
|
|
||||||
|
// first, check whether IPEndPointWhitelist applies
|
||||||
|
// and, if it does, whether client is on that white
|
||||||
|
// list.
|
||||||
|
if (null != h.IPEndPointWhitelist)
|
||||||
|
{
|
||||||
|
// TODO: following code requires code changes to
|
||||||
|
// HttpServer.HttpRequest to become functional
|
||||||
|
|
||||||
|
IPEndPoint remote = req.RemoteIPEndPoint;
|
||||||
|
if (null != remote)
|
||||||
|
{
|
||||||
|
Match epm = h.IPEndPointWhitelist.Match(remote.ToString());
|
||||||
|
if (!epm.Success)
|
||||||
|
{
|
||||||
|
scoredHandlers.Remove(h);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null != h.Method)
|
||||||
|
{
|
||||||
|
Match m = h.Method.Match(req.HttpMethod);
|
||||||
|
if (!m.Success)
|
||||||
|
{
|
||||||
|
scoredHandlers.Remove(h);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
scoredHandlers[h]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// whitelist ok, now check path
|
||||||
|
if (null != h.Path)
|
||||||
|
{
|
||||||
|
Match m = h.Path.Match(req.RawUrl);
|
||||||
|
if (!m.Success)
|
||||||
|
{
|
||||||
|
scoredHandlers.Remove(h);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
scoredHandlers[h] += m.ToString().Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// whitelist & path ok, now check query string
|
||||||
|
if (null != h.Query)
|
||||||
|
{
|
||||||
|
int queriesMatch = MatchOnNameValueCollection(req.QueryString, h.Query);
|
||||||
|
if (0 == queriesMatch)
|
||||||
|
{
|
||||||
|
_log.DebugFormat("[{0}] request {1}", EngineID, req);
|
||||||
|
_log.DebugFormat("[{0}] dropping handler {1}", EngineID, h);
|
||||||
|
|
||||||
|
scoredHandlers.Remove(h);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
scoredHandlers[h] += queriesMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
// whitelist, path, query string ok, now check headers
|
||||||
|
if (null != h.Headers)
|
||||||
|
{
|
||||||
|
int headersMatch = MatchOnNameValueCollection(req.Headers, h.Headers);
|
||||||
|
if (0 == headersMatch)
|
||||||
|
{
|
||||||
|
_log.DebugFormat("[{0}] request {1}", EngineID, req);
|
||||||
|
_log.DebugFormat("[{0}] dropping handler {1}", EngineID, h);
|
||||||
|
|
||||||
|
scoredHandlers.Remove(h);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
scoredHandlers[h] += headersMatch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<OSHttpHandler> matchingHandlers = new List<OSHttpHandler>(scoredHandlers.Keys);
|
||||||
|
matchingHandlers.Sort(delegate(OSHttpHandler x, OSHttpHandler y)
|
||||||
|
{
|
||||||
|
return scoredHandlers[x] - scoredHandlers[y];
|
||||||
|
});
|
||||||
|
LogDumpHandlerList(matchingHandlers);
|
||||||
|
return matchingHandlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int MatchOnNameValueCollection(NameValueCollection collection, Dictionary<string, Regex> regexs)
|
||||||
|
{
|
||||||
|
int matched = 0;
|
||||||
|
|
||||||
|
foreach (string tag in regexs.Keys)
|
||||||
|
{
|
||||||
|
// do we have a header "tag"?
|
||||||
|
if (null == collection[tag])
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// does the content of collection[tag] match
|
||||||
|
// the supplied regex?
|
||||||
|
Match cm = regexs[tag].Match(collection[tag]);
|
||||||
|
if (!cm.Success)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ok: matches
|
||||||
|
matched++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return matched;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalAttribute("DEBUGGING")]
|
||||||
|
private void LogDumpHandlerList(List<OSHttpHandler> l)
|
||||||
|
{
|
||||||
|
_log.DebugFormat("[{0}] OSHttpHandlerList dump:", EngineID);
|
||||||
|
foreach (OSHttpHandler h in l)
|
||||||
|
_log.DebugFormat(" ", h.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using HttpServer;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// OSHttpRequestQueues are used to hand over incoming HTTP
|
||||||
|
/// requests to OSHttpRequestPump objects.
|
||||||
|
/// </summary>
|
||||||
|
public class OSHttpRequestQueue : Queue<OSHttpRequest>
|
||||||
|
{
|
||||||
|
private object _syncObject = new object();
|
||||||
|
|
||||||
|
new public void Enqueue(OSHttpRequest req)
|
||||||
|
{
|
||||||
|
lock (_syncObject)
|
||||||
|
{
|
||||||
|
base.Enqueue(req);
|
||||||
|
Monitor.Pulse(_syncObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new public OSHttpRequest Dequeue()
|
||||||
|
{
|
||||||
|
OSHttpRequest req = null;
|
||||||
|
|
||||||
|
lock (_syncObject)
|
||||||
|
{
|
||||||
|
while (null == req)
|
||||||
|
{
|
||||||
|
Monitor.Wait(_syncObject);
|
||||||
|
if (0 != this.Count) req = base.Dequeue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,302 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using HttpServer;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// OSHttpResponse is the OpenSim representation of an HTTP
|
||||||
|
/// response.
|
||||||
|
/// </summary>
|
||||||
|
public class OSHttpResponse
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Content type property.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Setting this property will also set IsContentTypeSet to
|
||||||
|
/// true.
|
||||||
|
/// </remarks>
|
||||||
|
public string ContentType
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _httpResponse.ContentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_httpResponse.ContentType = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Boolean property indicating whether the content type
|
||||||
|
/// property actively has been set.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// IsContentTypeSet will go away together with .NET base.
|
||||||
|
/// </remarks>
|
||||||
|
// public bool IsContentTypeSet
|
||||||
|
// {
|
||||||
|
// get { return _contentTypeSet; }
|
||||||
|
// }
|
||||||
|
// private bool _contentTypeSet;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Length of the body content; 0 if there is no body.
|
||||||
|
/// </summary>
|
||||||
|
public long ContentLength
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _httpResponse.ContentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_httpResponse.ContentLength = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Alias for ContentLength.
|
||||||
|
/// </summary>
|
||||||
|
public long ContentLength64
|
||||||
|
{
|
||||||
|
get { return ContentLength; }
|
||||||
|
set { ContentLength = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Encoding of the body content.
|
||||||
|
/// </summary>
|
||||||
|
public Encoding ContentEncoding
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _httpResponse.Encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_httpResponse.Encoding = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool KeepAlive
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _httpResponse.Connection == ConnectionType.KeepAlive;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
_httpResponse.Connection = ConnectionType.KeepAlive;
|
||||||
|
else
|
||||||
|
_httpResponse.Connection = ConnectionType.Close;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get or set the keep alive timeout property (default is
|
||||||
|
/// 20). Setting this to 0 also disables KeepAlive. Setting
|
||||||
|
/// this to something else but 0 also enable KeepAlive.
|
||||||
|
/// </summary>
|
||||||
|
public int KeepAliveTimeout
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _httpResponse.KeepAlive;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == 0)
|
||||||
|
{
|
||||||
|
_httpResponse.Connection = ConnectionType.Close;
|
||||||
|
_httpResponse.KeepAlive = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_httpResponse.Connection = ConnectionType.KeepAlive;
|
||||||
|
_httpResponse.KeepAlive = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the output stream feeding the body.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// On its way out...
|
||||||
|
/// </remarks>
|
||||||
|
public Stream OutputStream
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _httpResponse.Body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ProtocolVersion
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _httpResponse.ProtocolVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_httpResponse.ProtocolVersion = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the output stream feeding the body.
|
||||||
|
/// </summary>
|
||||||
|
public Stream Body
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _httpResponse.Body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set a redirct location.
|
||||||
|
/// </summary>
|
||||||
|
public string RedirectLocation
|
||||||
|
{
|
||||||
|
// get { return _redirectLocation; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_httpResponse.Redirect(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Chunk transfers.
|
||||||
|
/// </summary>
|
||||||
|
public bool SendChunked
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _httpResponse.Chunked;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_httpResponse.Chunked = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// HTTP status code.
|
||||||
|
/// </summary>
|
||||||
|
public int StatusCode
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (int)_httpResponse.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_httpResponse.Status = (HttpStatusCode)value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// HTTP status description.
|
||||||
|
/// </summary>
|
||||||
|
public string StatusDescription
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _httpResponse.Reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_httpResponse.Reason = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected IHttpResponse _httpResponse;
|
||||||
|
|
||||||
|
public OSHttpResponse() {}
|
||||||
|
|
||||||
|
public OSHttpResponse(IHttpResponse resp)
|
||||||
|
{
|
||||||
|
_httpResponse = resp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiate an OSHttpResponse object from an OSHttpRequest
|
||||||
|
/// object.
|
||||||
|
/// </summary
|
||||||
|
/// <param name="req">Incoming OSHttpRequest to which we are
|
||||||
|
/// replying</param>
|
||||||
|
public OSHttpResponse(OSHttpRequest req)
|
||||||
|
{
|
||||||
|
_httpResponse = new HttpResponse(req.IHttpClientContext, req.IHttpRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add a header field and content to the response.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">string containing the header field
|
||||||
|
/// name</param>
|
||||||
|
/// <param name="value">string containing the header field
|
||||||
|
/// value</param>
|
||||||
|
public void AddHeader(string key, string value)
|
||||||
|
{
|
||||||
|
_httpResponse.AddHeader(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Send the response back to the remote client
|
||||||
|
/// </summary>
|
||||||
|
public void Send()
|
||||||
|
{
|
||||||
|
_httpResponse.Body.Flush();
|
||||||
|
_httpResponse.Send();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,210 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.Collections.Generic;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
using log4net;
|
||||||
|
using HttpServer;
|
||||||
|
|
||||||
|
using HttpListener = HttpServer.HttpListener;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// OSHttpServer provides an HTTP server bound to a specific
|
||||||
|
/// port. When instantiated with just address and port it uses
|
||||||
|
/// normal HTTP, when instantiated with address, port, and X509
|
||||||
|
/// certificate, it uses HTTPS.
|
||||||
|
/// </summary>
|
||||||
|
public class OSHttpServer
|
||||||
|
{
|
||||||
|
private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private object _syncObject = new object();
|
||||||
|
|
||||||
|
// underlying HttpServer.HttpListener
|
||||||
|
protected HttpListener _listener;
|
||||||
|
// underlying core/engine thread
|
||||||
|
protected Thread _engine;
|
||||||
|
|
||||||
|
// Queue containing (OS)HttpRequests
|
||||||
|
protected OSHttpRequestQueue _queue;
|
||||||
|
|
||||||
|
// OSHttpRequestPumps "pumping" incoming OSHttpRequests
|
||||||
|
// upwards
|
||||||
|
protected OSHttpRequestPump[] _pumps;
|
||||||
|
|
||||||
|
// thread identifier
|
||||||
|
protected string _engineId;
|
||||||
|
public string EngineID
|
||||||
|
{
|
||||||
|
get { return _engineId; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// True if this is an HTTPS connection; false otherwise.
|
||||||
|
/// </summary>
|
||||||
|
protected bool _isSecure;
|
||||||
|
public bool IsSecure
|
||||||
|
{
|
||||||
|
get { return _isSecure; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int QueueSize
|
||||||
|
{
|
||||||
|
get { return _pumps.Length; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of registered OSHttpHandlers for this OSHttpServer instance.
|
||||||
|
/// </summary>
|
||||||
|
protected List<OSHttpHandler> _httpHandlers = new List<OSHttpHandler>();
|
||||||
|
public List<OSHttpHandler> OSHttpHandlers
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (_httpHandlers)
|
||||||
|
{
|
||||||
|
return new List<OSHttpHandler>(_httpHandlers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiate an HTTP server.
|
||||||
|
/// </summary>
|
||||||
|
public OSHttpServer(IPAddress address, int port, int poolSize)
|
||||||
|
{
|
||||||
|
_engineId = String.Format("OSHttpServer (HTTP:{0})", port);
|
||||||
|
_isSecure = false;
|
||||||
|
_log.DebugFormat("[{0}] HTTP server instantiated", EngineID);
|
||||||
|
|
||||||
|
_listener = new HttpListener(address, port);
|
||||||
|
_queue = new OSHttpRequestQueue();
|
||||||
|
_pumps = OSHttpRequestPump.Pumps(this, _queue, poolSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiate an HTTPS server.
|
||||||
|
/// </summary>
|
||||||
|
public OSHttpServer(IPAddress address, int port, X509Certificate certificate, int poolSize)
|
||||||
|
{
|
||||||
|
_engineId = String.Format("OSHttpServer [HTTPS:{0}/ps:{1}]", port, poolSize);
|
||||||
|
_isSecure = true;
|
||||||
|
_log.DebugFormat("[{0}] HTTPS server instantiated", EngineID);
|
||||||
|
|
||||||
|
_listener = new HttpListener(address, port, certificate);
|
||||||
|
_queue = new OSHttpRequestQueue();
|
||||||
|
_pumps = OSHttpRequestPump.Pumps(this, _queue, poolSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turn an HttpRequest into an OSHttpRequestItem and place it
|
||||||
|
/// in the queue. The OSHttpRequestQueue object will pulse the
|
||||||
|
/// next available idle pump.
|
||||||
|
/// </summary>
|
||||||
|
protected void OnHttpRequest(HttpClientContext client, HttpRequest request)
|
||||||
|
{
|
||||||
|
// turn request into OSHttpRequest
|
||||||
|
OSHttpRequest req = new OSHttpRequest(client, request);
|
||||||
|
|
||||||
|
// place OSHttpRequest into _httpRequestQueue, will
|
||||||
|
// trigger Pulse to idle waiting pumps
|
||||||
|
_queue.Enqueue(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Start the HTTP server engine.
|
||||||
|
/// </summary>
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
_engine = new Thread(new ThreadStart(Engine));
|
||||||
|
_engine.Name = _engineId;
|
||||||
|
_engine.IsBackground = true;
|
||||||
|
_engine.Start();
|
||||||
|
|
||||||
|
ThreadTracker.Add(_engine);
|
||||||
|
|
||||||
|
// start the pumps...
|
||||||
|
for (int i = 0; i < _pumps.Length; i++)
|
||||||
|
_pumps[i].Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
lock (_syncObject) Monitor.Pulse(_syncObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Engine keeps the HTTP server running.
|
||||||
|
/// </summary>
|
||||||
|
private void Engine()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
_listener.RequestHandler += OnHttpRequest;
|
||||||
|
_listener.Start(QueueSize);
|
||||||
|
_log.InfoFormat("[{0}] HTTP server started", EngineID);
|
||||||
|
|
||||||
|
lock (_syncObject) Monitor.Wait(_syncObject);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.DebugFormat("[{0}] HTTP server startup failed: {1}", EngineID, ex.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
_log.InfoFormat("[{0}] HTTP server terminated", EngineID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add an HTTP request handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handler">OSHttpHandler delegate</param>
|
||||||
|
/// <param name="path">regex object for path matching</parm>
|
||||||
|
/// <param name="headers">dictionary containing header names
|
||||||
|
/// and regular expressions to match against header values</param>
|
||||||
|
public void AddHandler(OSHttpHandler handler)
|
||||||
|
{
|
||||||
|
lock (_httpHandlers)
|
||||||
|
{
|
||||||
|
if (_httpHandlers.Contains(handler))
|
||||||
|
{
|
||||||
|
_log.DebugFormat("[OSHttpServer] attempt to add already existing handler ignored");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_httpHandlers.Add(handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,170 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// HTTP status codes (almost) as defined by W3C in
|
||||||
|
/// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
||||||
|
/// </summary>
|
||||||
|
public enum OSHttpStatusCode: int
|
||||||
|
{
|
||||||
|
// 1xx Informational status codes providing a provisional
|
||||||
|
// response.
|
||||||
|
// 100 Tells client that to keep on going sending its request
|
||||||
|
InfoContinue = 100,
|
||||||
|
// 101 Server understands request, proposes to switch to different
|
||||||
|
// application level protocol
|
||||||
|
InfoSwitchingProtocols = 101,
|
||||||
|
|
||||||
|
|
||||||
|
// 2xx Success codes
|
||||||
|
// 200 Request successful
|
||||||
|
SuccessOk = 200,
|
||||||
|
// 201 Request successful, new resource created
|
||||||
|
SuccessOkCreated = 201,
|
||||||
|
// 202 Request accepted, processing still on-going
|
||||||
|
SuccessOkAccepted = 202,
|
||||||
|
// 203 Request successful, meta information not authoritative
|
||||||
|
SuccessOkNonAuthoritativeInformation = 203,
|
||||||
|
// 204 Request successful, nothing to return in the body
|
||||||
|
SuccessOkNoContent = 204,
|
||||||
|
// 205 Request successful, reset displayed content
|
||||||
|
SuccessOkResetContent = 205,
|
||||||
|
// 206 Request successful, partial content returned
|
||||||
|
SuccessOkPartialContent = 206,
|
||||||
|
|
||||||
|
// 3xx Redirect code: user agent needs to go somewhere else
|
||||||
|
// 300 Redirect: different presentation forms available, take
|
||||||
|
// a pick
|
||||||
|
RedirectMultipleChoices = 300,
|
||||||
|
// 301 Redirect: requested resource has moved and now lives
|
||||||
|
// somewhere else
|
||||||
|
RedirectMovedPermanently = 301,
|
||||||
|
// 302 Redirect: Resource temporarily somewhere else, location
|
||||||
|
// might change
|
||||||
|
RedirectFound = 302,
|
||||||
|
// 303 Redirect: See other as result of a POST
|
||||||
|
RedirectSeeOther = 303,
|
||||||
|
// 304 Redirect: Resource still the same as before
|
||||||
|
RedirectNotModified = 304,
|
||||||
|
// 305 Redirect: Resource must be accessed via proxy provided
|
||||||
|
// in location field
|
||||||
|
RedirectUseProxy = 305,
|
||||||
|
// 307 Redirect: Resource temporarily somewhere else, location
|
||||||
|
// might change
|
||||||
|
RedirectMovedTemporarily = 307,
|
||||||
|
|
||||||
|
// 4xx Client error: the client borked the request
|
||||||
|
// 400 Client error: bad request, server does not grok what
|
||||||
|
// the client wants
|
||||||
|
ClientErrorBadRequest = 400,
|
||||||
|
// 401 Client error: the client is not authorized, response
|
||||||
|
// provides WWW-Authenticate header field with a challenge
|
||||||
|
ClientErrorUnauthorized = 401,
|
||||||
|
// 402 Client error: Payment required (reserved for future use)
|
||||||
|
ClientErrorPaymentRequired = 402,
|
||||||
|
// 403 Client error: Server understood request, will not
|
||||||
|
// deliver, do not try again.
|
||||||
|
ClientErrorForbidden = 403,
|
||||||
|
// 404 Client error: Server cannot find anything matching the
|
||||||
|
// client request.
|
||||||
|
ClientErrorNotFound = 404,
|
||||||
|
// 405 Client error: The method specified by the client in the
|
||||||
|
// request is not allowed for the resource requested
|
||||||
|
ClientErrorMethodNotAllowed = 405,
|
||||||
|
// 406 Client error: Server cannot generate suitable response
|
||||||
|
// for the resource and content characteristics requested by
|
||||||
|
// the client
|
||||||
|
ClientErrorNotAcceptable = 406,
|
||||||
|
// 407 Client error: Similar to 401, Server requests that
|
||||||
|
// client authenticate itself with the proxy first
|
||||||
|
ClientErrorProxyAuthRequired = 407,
|
||||||
|
// 408 Client error: Server got impatient with client and
|
||||||
|
// decided to give up waiting for the client's request to
|
||||||
|
// arrive
|
||||||
|
ClientErrorRequestTimeout = 408,
|
||||||
|
// 409 Client error: Server could not fulfill the request for
|
||||||
|
// a resource as there is a conflict with the current state of
|
||||||
|
// the resource but thinks client can do something about this
|
||||||
|
ClientErrorConflict = 409,
|
||||||
|
// 410 Client error: The resource has moved somewhere else,
|
||||||
|
// but server has no clue where.
|
||||||
|
ClientErrorGone = 410,
|
||||||
|
// 411 Client error: The server is picky again and insists on
|
||||||
|
// having a content-length header field in the request
|
||||||
|
ClientErrorLengthRequired = 411,
|
||||||
|
// 412 Client error: one or more preconditions supplied in the
|
||||||
|
// client's request is false
|
||||||
|
ClientErrorPreconditionFailed = 412,
|
||||||
|
// 413 Client error: For fear of reflux, the server refuses to
|
||||||
|
// swallow that much data.
|
||||||
|
ClientErrorRequestEntityToLarge = 413,
|
||||||
|
// 414 Client error: The server considers the Request-URI to
|
||||||
|
// be indecently long and refuses to even look at it.
|
||||||
|
ClientErrorRequestURITooLong = 414,
|
||||||
|
// 415 Client error: The server has no clue about the media
|
||||||
|
// type requested by the client (contrary to popular belief it
|
||||||
|
// is not a warez server)
|
||||||
|
ClientErrorUnsupportedMediaType = 415,
|
||||||
|
// 416 Client error: The requested range cannot be delivered
|
||||||
|
// by the server.
|
||||||
|
ClientErrorRequestRangeNotSatisfiable = 416,
|
||||||
|
// 417 Client error: The expectations of the client as
|
||||||
|
// expressed in one or more Expect header fields cannot be met
|
||||||
|
// by the server, the server is awfully sorry about this.
|
||||||
|
ClientErrorExpectationFailed = 417,
|
||||||
|
// 499 Client error: Wildcard error.
|
||||||
|
ClientErrorJoker = 499,
|
||||||
|
|
||||||
|
// 5xx Server errors (rare)
|
||||||
|
// 500 Server error: something really strange and unexpected
|
||||||
|
// happened
|
||||||
|
ServerErrorInternalError = 500,
|
||||||
|
// 501 Server error: The server does not do the functionality
|
||||||
|
// required to carry out the client request. not at
|
||||||
|
// all. certainly not before breakfast. but also not after
|
||||||
|
// breakfast.
|
||||||
|
ServerErrorNotImplemented = 501,
|
||||||
|
// 502 Server error: While acting as a proxy or a gateway, the
|
||||||
|
// server got ditched by the upstream server and as a
|
||||||
|
// consequence regretfully cannot fulfill the client's request
|
||||||
|
ServerErrorBadGateway = 502,
|
||||||
|
// 503 Server error: Due to unforseen circumstances the server
|
||||||
|
// cannot currently deliver the service requested. Retry-After
|
||||||
|
// header might indicate when to try again.
|
||||||
|
ServerErrorServiceUnavailable = 503,
|
||||||
|
// 504 Server error: The server blames the upstream server
|
||||||
|
// for not being able to deliver the service requested and
|
||||||
|
// claims that the upstream server is too slow delivering the
|
||||||
|
// goods.
|
||||||
|
ServerErrorGatewayTimeout = 504,
|
||||||
|
// 505 Server error: The server does not support the HTTP
|
||||||
|
// version conveyed in the client's request.
|
||||||
|
ServerErrorHttpVersionNotSupported = 505,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,180 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Xml;
|
||||||
|
using log4net;
|
||||||
|
using Nwc.XmlRpc;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public delegate XmlRpcResponse OSHttpXmlRpcProcessor(XmlRpcRequest request);
|
||||||
|
|
||||||
|
public class OSHttpXmlRpcHandler: OSHttpHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// XmlRpcMethodMatch tries to reify (deserialize) an incoming
|
||||||
|
/// XmlRpc request (and posts it to the "whiteboard") and
|
||||||
|
/// checks whether the method name is one we are interested
|
||||||
|
/// in.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>true if the handler is interested in the content;
|
||||||
|
/// false otherwise</returns>
|
||||||
|
protected bool XmlRpcMethodMatch(OSHttpRequest req)
|
||||||
|
{
|
||||||
|
XmlRpcRequest xmlRpcRequest = null;
|
||||||
|
|
||||||
|
// check whether req is already reified
|
||||||
|
// if not: reify (and post to whiteboard)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (req.Whiteboard.ContainsKey("xmlrequest"))
|
||||||
|
{
|
||||||
|
xmlRpcRequest = req.Whiteboard["xmlrequest"] as XmlRpcRequest;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StreamReader body = new StreamReader(req.InputStream);
|
||||||
|
string requestBody = body.ReadToEnd();
|
||||||
|
xmlRpcRequest = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody);
|
||||||
|
req.Whiteboard["xmlrequest"] = xmlRpcRequest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (XmlException)
|
||||||
|
{
|
||||||
|
_log.ErrorFormat("[OSHttpXmlRpcHandler] failed to deserialize XmlRpcRequest from {0}", req.ToString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check against methodName
|
||||||
|
if ((null != xmlRpcRequest)
|
||||||
|
&& !String.IsNullOrEmpty(xmlRpcRequest.MethodName)
|
||||||
|
&& xmlRpcRequest.MethodName == _methodName)
|
||||||
|
{
|
||||||
|
_log.DebugFormat("[OSHttpXmlRpcHandler] located handler {0} for {1}", _methodName, req.ToString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// contains handler for processing XmlRpc Request
|
||||||
|
private XmlRpcMethod _handler;
|
||||||
|
|
||||||
|
// contains XmlRpc method name
|
||||||
|
private string _methodName;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiate an XmlRpc handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handler">XmlRpcMethod
|
||||||
|
/// delegate</param>
|
||||||
|
/// <param name="methodName">XmlRpc method name</param>
|
||||||
|
/// <param name="path">XmlRpc path prefix (regular expression)</param>
|
||||||
|
/// <param name="headers">Dictionary with header names and
|
||||||
|
/// regular expressions to match content of headers</param>
|
||||||
|
/// <param name="whitelist">IP whitelist of remote end points
|
||||||
|
/// to accept (regular expression)</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// Except for handler and methodName, all other parameters
|
||||||
|
/// can be null, in which case they are not taken into account
|
||||||
|
/// when the handler is being looked up.
|
||||||
|
/// </remarks>
|
||||||
|
public OSHttpXmlRpcHandler(XmlRpcMethod handler, string methodName, Regex path,
|
||||||
|
Dictionary<string, Regex> headers, Regex whitelist)
|
||||||
|
: base(new Regex(@"^POST$", RegexOptions.IgnoreCase | RegexOptions.Compiled), path, null, headers,
|
||||||
|
new Regex(@"^(text|application)/xml", RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
whitelist)
|
||||||
|
{
|
||||||
|
_handler = handler;
|
||||||
|
_methodName = methodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Instantiate an XmlRpc handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handler">XmlRpcMethod
|
||||||
|
/// delegate</param>
|
||||||
|
/// <param name="methodName">XmlRpc method name</param>
|
||||||
|
public OSHttpXmlRpcHandler(XmlRpcMethod handler, string methodName)
|
||||||
|
: this(handler, methodName, null, null, null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked by OSHttpRequestPump.
|
||||||
|
/// </summary>
|
||||||
|
public override OSHttpHandlerResult Process(OSHttpRequest request)
|
||||||
|
{
|
||||||
|
XmlRpcResponse xmlRpcResponse;
|
||||||
|
string responseString;
|
||||||
|
|
||||||
|
// check whether we are interested in this request
|
||||||
|
if (!XmlRpcMethodMatch(request)) return OSHttpHandlerResult.Pass;
|
||||||
|
|
||||||
|
|
||||||
|
OSHttpResponse resp = new OSHttpResponse(request);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// reified XmlRpcRequest must still be on the whiteboard
|
||||||
|
XmlRpcRequest xmlRpcRequest = request.Whiteboard["xmlrequest"] as XmlRpcRequest;
|
||||||
|
xmlRpcResponse = _handler(xmlRpcRequest);
|
||||||
|
responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse);
|
||||||
|
|
||||||
|
resp.ContentType = "text/xml";
|
||||||
|
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
|
||||||
|
|
||||||
|
resp.SendChunked = false;
|
||||||
|
resp.ContentLength = buffer.Length;
|
||||||
|
resp.ContentEncoding = Encoding.UTF8;
|
||||||
|
|
||||||
|
resp.Body.Write(buffer, 0, buffer.Length);
|
||||||
|
resp.Body.Flush();
|
||||||
|
|
||||||
|
resp.Send();
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_log.WarnFormat("[OSHttpXmlRpcHandler]: Error: {0}", ex.Message);
|
||||||
|
return OSHttpHandlerResult.Pass;
|
||||||
|
}
|
||||||
|
return OSHttpHandlerResult.Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,180 @@
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
|
||||||
|
<PropertyGroup>
|
||||||
|
<ProjectType>Local</ProjectType>
|
||||||
|
<ProductVersion>8.0.50727</ProductVersion>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<ProjectGuid>{1CBD339A-0000-0000-0000-000000000000}</ProjectGuid>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ApplicationIcon></ApplicationIcon>
|
||||||
|
<AssemblyKeyContainerName>
|
||||||
|
</AssemblyKeyContainerName>
|
||||||
|
<AssemblyName>OpenSim.Framework.Servers.HttpServer</AssemblyName>
|
||||||
|
<DefaultClientScript>JScript</DefaultClientScript>
|
||||||
|
<DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
|
||||||
|
<DefaultTargetSchema>IE50</DefaultTargetSchema>
|
||||||
|
<DelaySign>false</DelaySign>
|
||||||
|
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder></AppDesignerFolder>
|
||||||
|
<RootNamespace>OpenSim.Framework.Servers.HttpServer</RootNamespace>
|
||||||
|
<StartupObject></StartupObject>
|
||||||
|
<StartArguments></StartArguments>
|
||||||
|
<FileUpgradeFlags>
|
||||||
|
</FileUpgradeFlags>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
|
||||||
|
<BaseAddress>285212672</BaseAddress>
|
||||||
|
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
||||||
|
<ConfigurationOverrideFile>
|
||||||
|
</ConfigurationOverrideFile>
|
||||||
|
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
||||||
|
<DocumentationFile></DocumentationFile>
|
||||||
|
<DebugSymbols>True</DebugSymbols>
|
||||||
|
<FileAlignment>4096</FileAlignment>
|
||||||
|
<Optimize>False</Optimize>
|
||||||
|
<OutputPath>../../../../bin/</OutputPath>
|
||||||
|
<RegisterForComInterop>False</RegisterForComInterop>
|
||||||
|
<RemoveIntegerChecks>False</RemoveIntegerChecks>
|
||||||
|
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<NoStdLib>False</NoStdLib>
|
||||||
|
<NoWarn></NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
|
||||||
|
<BaseAddress>285212672</BaseAddress>
|
||||||
|
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
||||||
|
<ConfigurationOverrideFile>
|
||||||
|
</ConfigurationOverrideFile>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<DocumentationFile></DocumentationFile>
|
||||||
|
<DebugSymbols>False</DebugSymbols>
|
||||||
|
<FileAlignment>4096</FileAlignment>
|
||||||
|
<Optimize>True</Optimize>
|
||||||
|
<OutputPath>../../../../bin/</OutputPath>
|
||||||
|
<RegisterForComInterop>False</RegisterForComInterop>
|
||||||
|
<RemoveIntegerChecks>False</RemoveIntegerChecks>
|
||||||
|
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<NoStdLib>False</NoStdLib>
|
||||||
|
<NoWarn></NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="HttpServer_OpenSim.dll" >
|
||||||
|
<Name>HttpServer_OpenSim.dll</Name>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="log4net.dll" >
|
||||||
|
<Name>log4net.dll</Name>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="OpenMetaverse.StructuredData.dll" >
|
||||||
|
<Name>OpenMetaverse.StructuredData.dll</Name>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="OpenMetaverseTypes.dll" >
|
||||||
|
<Name>OpenMetaverseTypes.dll</Name>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" >
|
||||||
|
<Name>System</Name>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml" >
|
||||||
|
<Name>System.Xml</Name>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="XMLRPC.dll" >
|
||||||
|
<Name>XMLRPC.dll</Name>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="../../../Data/OpenSim.Data.csproj">
|
||||||
|
<Name>OpenSim.Data</Name>
|
||||||
|
<Project>{B75A430B-0000-0000-0000-000000000000}</Project>
|
||||||
|
<Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>
|
||||||
|
<Private>False</Private>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="BaseHTTPHandler.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="BaseHttpServer.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="BaseRequestHandler.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="BaseStreamHandler.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="BinaryStreamHandler.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="GenericHTTPMethod.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="LLSDMethod.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="LLSDMethodString.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="OSHttpRequest.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="OSHttpResponse.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="OSHttpStatusCodes.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="RestDeserialiseHandler.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="RestHTTPHandler.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="RestMethod.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="RestObjectPoster.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="RestObjectPosterResponse.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="RestSessionService.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="RestStreamHandler.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="SynchronousRestObjectPoster.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="XmlRpcMethod.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Interfaces/IHttpAgentHandler.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Interfaces/IHttpServer.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Interfaces/IStreamHandler.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<PreBuildEvent>
|
||||||
|
</PreBuildEvent>
|
||||||
|
<PostBuildEvent>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ReferencePath>/root/opensim-commit/bin/</ReferencePath>
|
||||||
|
<LastOpenVersion>8.0.50727</LastOpenVersion>
|
||||||
|
<ProjectView>ProjectFiles</ProjectView>
|
||||||
|
<ProjectTrust>0</ProjectTrust>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition = " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
|
||||||
|
<PropertyGroup Condition = " '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
|
||||||
|
</Project>
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?xml version="1.0" ?>
|
||||||
|
<project name="OpenSim.Framework.Servers.HttpServer" default="build">
|
||||||
|
<target name="build">
|
||||||
|
<echo message="Build Directory is ${project::get-base-directory()}/${build.dir}" />
|
||||||
|
<mkdir dir="${project::get-base-directory()}/${build.dir}" />
|
||||||
|
<copy todir="${project::get-base-directory()}/${build.dir}" flatten="true">
|
||||||
|
<fileset basedir="${project::get-base-directory()}">
|
||||||
|
</fileset>
|
||||||
|
</copy>
|
||||||
|
<copy todir="${project::get-base-directory()}/${build.dir}">
|
||||||
|
<fileset basedir=".">
|
||||||
|
</fileset>
|
||||||
|
</copy>
|
||||||
|
<csc target="library" debug="${build.debug}" unsafe="False" warnaserror="False" define="TRACE;DEBUG" nostdlib="False" main="" output="${project::get-base-directory()}/${build.dir}/${project::get-name()}.dll">
|
||||||
|
<resources prefix="OpenSim.Framework.Servers.HttpServer" dynamicprefix="true" >
|
||||||
|
</resources>
|
||||||
|
<sources failonempty="true">
|
||||||
|
<include name="BaseHTTPHandler.cs" />
|
||||||
|
<include name="BaseHttpServer.cs" />
|
||||||
|
<include name="BaseRequestHandler.cs" />
|
||||||
|
<include name="BaseStreamHandler.cs" />
|
||||||
|
<include name="BinaryStreamHandler.cs" />
|
||||||
|
<include name="GenericHTTPMethod.cs" />
|
||||||
|
<include name="LLSDMethod.cs" />
|
||||||
|
<include name="LLSDMethodString.cs" />
|
||||||
|
<include name="OSHttpRequest.cs" />
|
||||||
|
<include name="OSHttpResponse.cs" />
|
||||||
|
<include name="OSHttpStatusCodes.cs" />
|
||||||
|
<include name="RestDeserialiseHandler.cs" />
|
||||||
|
<include name="RestHTTPHandler.cs" />
|
||||||
|
<include name="RestMethod.cs" />
|
||||||
|
<include name="RestObjectPoster.cs" />
|
||||||
|
<include name="RestObjectPosterResponse.cs" />
|
||||||
|
<include name="RestSessionService.cs" />
|
||||||
|
<include name="RestStreamHandler.cs" />
|
||||||
|
<include name="SynchronousRestObjectPoster.cs" />
|
||||||
|
<include name="XmlRpcMethod.cs" />
|
||||||
|
<include name="Interfaces/IHttpAgentHandler.cs" />
|
||||||
|
<include name="Interfaces/IHttpServer.cs" />
|
||||||
|
<include name="Interfaces/IStreamHandler.cs" />
|
||||||
|
</sources>
|
||||||
|
<references basedir="${project::get-base-directory()}">
|
||||||
|
<lib>
|
||||||
|
<include name="${project::get-base-directory()}" />
|
||||||
|
<include name="${project::get-base-directory()}/../../../../bin" />
|
||||||
|
</lib>
|
||||||
|
<include name="../../../../bin/HttpServer_OpenSim.dll" />
|
||||||
|
<include name="../../../../bin/log4net.dll" />
|
||||||
|
<include name="../../../../bin/OpenMetaverse.StructuredData.dll" />
|
||||||
|
<include name="../../../../bin/OpenMetaverseTypes.dll" />
|
||||||
|
<include name="OpenSim.Data.dll" />
|
||||||
|
<include name="System.dll" />
|
||||||
|
<include name="System.Xml.dll" />
|
||||||
|
<include name="../../../../bin/XMLRPC.dll" />
|
||||||
|
</references>
|
||||||
|
</csc>
|
||||||
|
<echo message="Copying from [${project::get-base-directory()}/${build.dir}/] to [${project::get-base-directory()}/../../../../bin/" />
|
||||||
|
<mkdir dir="${project::get-base-directory()}/../../../../bin/"/>
|
||||||
|
<copy todir="${project::get-base-directory()}/../../../../bin/">
|
||||||
|
<fileset basedir="${project::get-base-directory()}/${build.dir}/" >
|
||||||
|
<include name="*.dll"/>
|
||||||
|
<include name="*.exe"/>
|
||||||
|
<include name="*.mdb" if='${build.debug}'/>
|
||||||
|
<include name="*.pdb" if='${build.debug}'/>
|
||||||
|
</fileset>
|
||||||
|
</copy>
|
||||||
|
</target>
|
||||||
|
<target name="clean">
|
||||||
|
<delete dir="${bin.dir}" failonerror="false" />
|
||||||
|
<delete dir="${obj.dir}" failonerror="false" />
|
||||||
|
</target>
|
||||||
|
<target name="doc" description="Creates documentation.">
|
||||||
|
</target>
|
||||||
|
</project>
|
|
@ -0,0 +1,54 @@
|
||||||
|
<Project name="OpenSim.Framework.Servers.HttpServer" description="" standardNamespace="OpenSim.Framework.Servers.HttpServer" newfilesearch="None" enableviewstate="True" fileversion="2.0" language="C#" clr-version="Net_2_0" ctype="DotNetProject">
|
||||||
|
<Configurations active="Debug">
|
||||||
|
<Configuration name="Debug" ctype="DotNetProjectConfiguration">
|
||||||
|
<Output directory="./../../../../bin/" assembly="OpenSim.Framework.Servers.HttpServer" executeScript="" executeBeforeBuild="" executeAfterBuild="" executeBeforeBuildArguments="" executeAfterBuildArguments="" />
|
||||||
|
<Build debugmode="True" target="Library" />
|
||||||
|
<Execution runwithwarnings="True" consolepause="True" runtime="MsNet" clr-version="Net_2_0" />
|
||||||
|
<CodeGeneration compiler="Csc" warninglevel="4" nowarn="" includedebuginformation="True" optimize="False" unsafecodeallowed="False" generateoverflowchecks="False" mainclass="" target="Library" definesymbols="TRACE;DEBUG" generatexmldocumentation="False" win32Icon="" ctype="CSharpCompilerParameters" />
|
||||||
|
</Configuration>
|
||||||
|
<Configuration name="Release" ctype="DotNetProjectConfiguration">
|
||||||
|
<Output directory="./../../../../bin/" assembly="OpenSim.Framework.Servers.HttpServer" executeScript="" executeBeforeBuild="" executeAfterBuild="" executeBeforeBuildArguments="" executeAfterBuildArguments="" />
|
||||||
|
<Build debugmode="True" target="Library" />
|
||||||
|
<Execution runwithwarnings="True" consolepause="True" runtime="MsNet" clr-version="Net_2_0" />
|
||||||
|
<CodeGeneration compiler="Csc" warninglevel="4" nowarn="" includedebuginformation="False" optimize="True" unsafecodeallowed="False" generateoverflowchecks="False" mainclass="" target="Library" definesymbols="TRACE" generatexmldocumentation="False" win32Icon="" ctype="CSharpCompilerParameters" />
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<DeploymentInformation target="" script="" strategy="File">
|
||||||
|
<excludeFiles />
|
||||||
|
</DeploymentInformation>
|
||||||
|
<Contents>
|
||||||
|
<File name="./BaseHTTPHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./BaseHttpServer.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./BaseRequestHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./BaseStreamHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./BinaryStreamHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./GenericHTTPMethod.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./LLSDMethod.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./LLSDMethodString.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./OSHttpRequest.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./OSHttpResponse.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./OSHttpStatusCodes.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./RestDeserialiseHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./RestHTTPHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./RestMethod.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./RestObjectPoster.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./RestObjectPosterResponse.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./RestSessionService.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./RestStreamHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./SynchronousRestObjectPoster.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./XmlRpcMethod.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./Interfaces/IHttpAgentHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./Interfaces/IHttpServer.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
<File name="./Interfaces/IStreamHandler.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||||
|
</Contents>
|
||||||
|
<References>
|
||||||
|
<ProjectReference type="Assembly" refto="../../../../bin/HttpServer_OpenSim.dll" localcopy="False" />
|
||||||
|
<ProjectReference type="Assembly" refto="../../../../bin/log4net.dll" localcopy="False" />
|
||||||
|
<ProjectReference type="Assembly" refto="../../../../bin/OpenMetaverse.StructuredData.dll" localcopy="False" />
|
||||||
|
<ProjectReference type="Assembly" refto="../../../../bin/OpenMetaverseTypes.dll" localcopy="False" />
|
||||||
|
<ProjectReference type="Project" localcopy="False" refto="OpenSim.Data" />
|
||||||
|
<ProjectReference type="Gac" localcopy="False" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||||
|
<ProjectReference type="Gac" localcopy="False" refto="System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||||
|
<ProjectReference type="Assembly" refto="../../../../bin/XMLRPC.dll" localcopy="False" />
|
||||||
|
</References>
|
||||||
|
</Project>
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.IO;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public delegate TResponse RestDeserialiseMethod<TRequest, TResponse>(TRequest request);
|
||||||
|
|
||||||
|
public class RestDeserialiseHandler<TRequest, TResponse> : BaseRequestHandler, IStreamHandler
|
||||||
|
where TRequest : new()
|
||||||
|
{
|
||||||
|
private RestDeserialiseMethod<TRequest, TResponse> m_method;
|
||||||
|
|
||||||
|
public RestDeserialiseHandler(string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method)
|
||||||
|
: base(httpMethod, path)
|
||||||
|
{
|
||||||
|
m_method = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(string path, Stream request, Stream responseStream,
|
||||||
|
OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
TRequest deserial;
|
||||||
|
using (XmlTextReader xmlReader = new XmlTextReader(request))
|
||||||
|
{
|
||||||
|
XmlSerializer deserializer = new XmlSerializer(typeof (TRequest));
|
||||||
|
deserial = (TRequest) deserializer.Deserialize(xmlReader);
|
||||||
|
}
|
||||||
|
|
||||||
|
TResponse response = m_method(deserial);
|
||||||
|
|
||||||
|
using (XmlWriter xmlWriter = XmlTextWriter.Create(responseStream))
|
||||||
|
{
|
||||||
|
XmlSerializer serializer = new XmlSerializer(typeof (TResponse));
|
||||||
|
serializer.Serialize(xmlWriter, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.Collections;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public class RestHTTPHandler : BaseHTTPHandler
|
||||||
|
{
|
||||||
|
private GenericHTTPMethod m_dhttpMethod;
|
||||||
|
|
||||||
|
public GenericHTTPMethod Method
|
||||||
|
{
|
||||||
|
get { return m_dhttpMethod; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Hashtable Handle(string path, Hashtable request)
|
||||||
|
{
|
||||||
|
|
||||||
|
string param = GetParam(path);
|
||||||
|
request.Add("param", param);
|
||||||
|
request.Add("path", path);
|
||||||
|
return m_dhttpMethod(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RestHTTPHandler(string httpMethod, string path, GenericHTTPMethod dhttpMethod)
|
||||||
|
: base(httpMethod, path)
|
||||||
|
{
|
||||||
|
m_dhttpMethod = dhttpMethod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public delegate string RestMethod(string request, string path, string param,
|
||||||
|
OSHttpRequest httpRequest, OSHttpResponse httpResponse);
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.Xml;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Makes an asynchronous REST request which doesn't require us to do anything with the response.
|
||||||
|
/// </summary>
|
||||||
|
public class RestObjectPoster
|
||||||
|
{
|
||||||
|
public static void BeginPostObject<TRequest>(string requestUrl, TRequest obj)
|
||||||
|
{
|
||||||
|
BeginPostObject("POST", requestUrl, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void BeginPostObject<TRequest>(string verb, string requestUrl, TRequest obj)
|
||||||
|
{
|
||||||
|
Type type = typeof (TRequest);
|
||||||
|
|
||||||
|
WebRequest request = WebRequest.Create(requestUrl);
|
||||||
|
request.Method = verb;
|
||||||
|
request.ContentType = "text/xml";
|
||||||
|
|
||||||
|
MemoryStream buffer = new MemoryStream();
|
||||||
|
|
||||||
|
XmlWriterSettings settings = new XmlWriterSettings();
|
||||||
|
settings.Encoding = Encoding.UTF8;
|
||||||
|
|
||||||
|
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
|
||||||
|
{
|
||||||
|
XmlSerializer serializer = new XmlSerializer(type);
|
||||||
|
serializer.Serialize(writer, obj);
|
||||||
|
writer.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = (int) buffer.Length;
|
||||||
|
request.ContentLength = length;
|
||||||
|
|
||||||
|
Stream requestStream = request.GetRequestStream();
|
||||||
|
requestStream.Write(buffer.ToArray(), 0, length);
|
||||||
|
// IAsyncResult result = request.BeginGetResponse(AsyncCallback, request);
|
||||||
|
request.BeginGetResponse(AsyncCallback, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AsyncCallback(IAsyncResult result)
|
||||||
|
{
|
||||||
|
WebRequest request = (WebRequest) result.AsyncState;
|
||||||
|
using (WebResponse resp = request.EndGetResponse(result))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.Xml;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public delegate void ReturnResponse<T>(T reponse);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Makes an asynchronous REST request with a callback to invoke with the response.
|
||||||
|
/// </summary>
|
||||||
|
public class RestObjectPosterResponse<TResponse>
|
||||||
|
{
|
||||||
|
// private static readonly log4net.ILog m_log
|
||||||
|
// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
public ReturnResponse<TResponse> ResponseCallback;
|
||||||
|
|
||||||
|
public void BeginPostObject<TRequest>(string requestUrl, TRequest obj)
|
||||||
|
{
|
||||||
|
BeginPostObject("POST", requestUrl, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BeginPostObject<TRequest>(string verb, string requestUrl, TRequest obj)
|
||||||
|
{
|
||||||
|
Type type = typeof (TRequest);
|
||||||
|
|
||||||
|
WebRequest request = WebRequest.Create(requestUrl);
|
||||||
|
request.Method = verb;
|
||||||
|
request.ContentType = "text/xml";
|
||||||
|
request.Timeout = 10000;
|
||||||
|
|
||||||
|
MemoryStream buffer = new MemoryStream();
|
||||||
|
|
||||||
|
XmlWriterSettings settings = new XmlWriterSettings();
|
||||||
|
settings.Encoding = Encoding.UTF8;
|
||||||
|
|
||||||
|
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
|
||||||
|
{
|
||||||
|
XmlSerializer serializer = new XmlSerializer(type);
|
||||||
|
serializer.Serialize(writer, obj);
|
||||||
|
writer.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = (int) buffer.Length;
|
||||||
|
request.ContentLength = length;
|
||||||
|
|
||||||
|
Stream requestStream = request.GetRequestStream();
|
||||||
|
requestStream.Write(buffer.ToArray(), 0, length);
|
||||||
|
requestStream.Close();
|
||||||
|
// IAsyncResult result = request.BeginGetResponse(AsyncCallback, request);
|
||||||
|
request.BeginGetResponse(AsyncCallback, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AsyncCallback(IAsyncResult result)
|
||||||
|
{
|
||||||
|
WebRequest request = (WebRequest) result.AsyncState;
|
||||||
|
using (WebResponse resp = request.EndGetResponse(result))
|
||||||
|
{
|
||||||
|
TResponse deserial;
|
||||||
|
XmlSerializer deserializer = new XmlSerializer(typeof (TResponse));
|
||||||
|
Stream stream = resp.GetResponseStream();
|
||||||
|
|
||||||
|
// This is currently a bad debug stanza since it gobbles us the response...
|
||||||
|
// StreamReader reader = new StreamReader(stream);
|
||||||
|
// m_log.DebugFormat("[REST OBJECT POSTER RESPONSE]: Received {0}", reader.ReadToEnd());
|
||||||
|
|
||||||
|
deserial = (TResponse) deserializer.Deserialize(stream);
|
||||||
|
|
||||||
|
if (deserial != null && ResponseCallback != null)
|
||||||
|
{
|
||||||
|
ResponseCallback(deserial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,291 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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 OpenSimulator 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.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public class RestSessionObject<TRequest>
|
||||||
|
{
|
||||||
|
private string sid;
|
||||||
|
private string aid;
|
||||||
|
private TRequest request_body;
|
||||||
|
|
||||||
|
public string SessionID
|
||||||
|
{
|
||||||
|
get { return sid; }
|
||||||
|
set { sid = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string AvatarID
|
||||||
|
{
|
||||||
|
get { return aid; }
|
||||||
|
set { aid = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public TRequest Body
|
||||||
|
{
|
||||||
|
get { return request_body; }
|
||||||
|
set { request_body = value; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SynchronousRestSessionObjectPoster<TRequest, TResponse>
|
||||||
|
{
|
||||||
|
public static TResponse BeginPostObject(string verb, string requestUrl, TRequest obj, string sid, string aid)
|
||||||
|
{
|
||||||
|
RestSessionObject<TRequest> sobj = new RestSessionObject<TRequest>();
|
||||||
|
sobj.SessionID = sid;
|
||||||
|
sobj.AvatarID = aid;
|
||||||
|
sobj.Body = obj;
|
||||||
|
|
||||||
|
Type type = typeof(RestSessionObject<TRequest>);
|
||||||
|
|
||||||
|
WebRequest request = WebRequest.Create(requestUrl);
|
||||||
|
request.Method = verb;
|
||||||
|
request.ContentType = "text/xml";
|
||||||
|
|
||||||
|
MemoryStream buffer = new MemoryStream();
|
||||||
|
|
||||||
|
XmlWriterSettings settings = new XmlWriterSettings();
|
||||||
|
settings.Encoding = Encoding.UTF8;
|
||||||
|
|
||||||
|
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
|
||||||
|
{
|
||||||
|
XmlSerializer serializer = new XmlSerializer(type);
|
||||||
|
serializer.Serialize(writer, sobj);
|
||||||
|
writer.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = (int)buffer.Length;
|
||||||
|
request.ContentLength = length;
|
||||||
|
|
||||||
|
Stream requestStream = request.GetRequestStream();
|
||||||
|
requestStream.Write(buffer.ToArray(), 0, length);
|
||||||
|
TResponse deserial = default(TResponse);
|
||||||
|
using (WebResponse resp = request.GetResponse())
|
||||||
|
{
|
||||||
|
XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
|
||||||
|
deserial = (TResponse)deserializer.Deserialize(resp.GetResponseStream());
|
||||||
|
}
|
||||||
|
return deserial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RestSessionObjectPosterResponse<TRequest, TResponse>
|
||||||
|
{
|
||||||
|
public ReturnResponse<TResponse> ResponseCallback;
|
||||||
|
|
||||||
|
public void BeginPostObject(string requestUrl, TRequest obj, string sid, string aid)
|
||||||
|
{
|
||||||
|
BeginPostObject("POST", requestUrl, obj, sid, aid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BeginPostObject(string verb, string requestUrl, TRequest obj, string sid, string aid)
|
||||||
|
{
|
||||||
|
RestSessionObject<TRequest> sobj = new RestSessionObject<TRequest>();
|
||||||
|
sobj.SessionID = sid;
|
||||||
|
sobj.AvatarID = aid;
|
||||||
|
sobj.Body = obj;
|
||||||
|
|
||||||
|
Type type = typeof(RestSessionObject<TRequest>);
|
||||||
|
|
||||||
|
WebRequest request = WebRequest.Create(requestUrl);
|
||||||
|
request.Method = verb;
|
||||||
|
request.ContentType = "text/xml";
|
||||||
|
request.Timeout = 10000;
|
||||||
|
|
||||||
|
MemoryStream buffer = new MemoryStream();
|
||||||
|
|
||||||
|
XmlWriterSettings settings = new XmlWriterSettings();
|
||||||
|
settings.Encoding = Encoding.UTF8;
|
||||||
|
|
||||||
|
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
|
||||||
|
{
|
||||||
|
XmlSerializer serializer = new XmlSerializer(type);
|
||||||
|
serializer.Serialize(writer, sobj);
|
||||||
|
writer.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = (int)buffer.Length;
|
||||||
|
request.ContentLength = length;
|
||||||
|
|
||||||
|
Stream requestStream = request.GetRequestStream();
|
||||||
|
requestStream.Write(buffer.ToArray(), 0, length);
|
||||||
|
requestStream.Close();
|
||||||
|
// IAsyncResult result = request.BeginGetResponse(AsyncCallback, request);
|
||||||
|
request.BeginGetResponse(AsyncCallback, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AsyncCallback(IAsyncResult result)
|
||||||
|
{
|
||||||
|
WebRequest request = (WebRequest)result.AsyncState;
|
||||||
|
using (WebResponse resp = request.EndGetResponse(result))
|
||||||
|
{
|
||||||
|
TResponse deserial;
|
||||||
|
XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
|
||||||
|
Stream stream = resp.GetResponseStream();
|
||||||
|
|
||||||
|
// This is currently a bad debug stanza since it gobbles us the response...
|
||||||
|
// StreamReader reader = new StreamReader(stream);
|
||||||
|
// m_log.DebugFormat("[REST OBJECT POSTER RESPONSE]: Received {0}", reader.ReadToEnd());
|
||||||
|
|
||||||
|
deserial = (TResponse)deserializer.Deserialize(stream);
|
||||||
|
|
||||||
|
if (deserial != null && ResponseCallback != null)
|
||||||
|
{
|
||||||
|
ResponseCallback(deserial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate bool CheckIdentityMethod(string sid, string aid);
|
||||||
|
|
||||||
|
public class RestDeserialiseSecureHandler<TRequest, TResponse> : BaseRequestHandler, IStreamHandler
|
||||||
|
where TRequest : new()
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log
|
||||||
|
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private RestDeserialiseMethod<TRequest, TResponse> m_method;
|
||||||
|
private CheckIdentityMethod m_smethod;
|
||||||
|
|
||||||
|
public RestDeserialiseSecureHandler(
|
||||||
|
string httpMethod, string path,
|
||||||
|
RestDeserialiseMethod<TRequest, TResponse> method, CheckIdentityMethod smethod)
|
||||||
|
: base(httpMethod, path)
|
||||||
|
{
|
||||||
|
m_smethod = smethod;
|
||||||
|
m_method = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(string path, Stream request, Stream responseStream,
|
||||||
|
OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
RestSessionObject<TRequest> deserial = default(RestSessionObject<TRequest>);
|
||||||
|
bool fail = false;
|
||||||
|
|
||||||
|
using (XmlTextReader xmlReader = new XmlTextReader(request))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
XmlSerializer deserializer = new XmlSerializer(typeof(RestSessionObject<TRequest>));
|
||||||
|
deserial = (RestSessionObject<TRequest>)deserializer.Deserialize(xmlReader);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.Error("[REST]: Deserialization problem. Ignoring request. " + e);
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TResponse response = default(TResponse);
|
||||||
|
if (!fail && m_smethod(deserial.SessionID, deserial.AvatarID))
|
||||||
|
{
|
||||||
|
response = m_method(deserial.Body);
|
||||||
|
}
|
||||||
|
|
||||||
|
using (XmlWriter xmlWriter = XmlTextWriter.Create(responseStream))
|
||||||
|
{
|
||||||
|
XmlSerializer serializer = new XmlSerializer(typeof(TResponse));
|
||||||
|
serializer.Serialize(xmlWriter, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate bool CheckTrustedSourceMethod(IPEndPoint peer);
|
||||||
|
|
||||||
|
public class RestDeserialiseTrustedHandler<TRequest, TResponse> : BaseRequestHandler, IStreamHandler
|
||||||
|
where TRequest : new()
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log
|
||||||
|
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The operation to perform once trust has been established.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="httpMethod"></param>
|
||||||
|
/// <param name="path"></param>
|
||||||
|
/// <param name="method"></param>
|
||||||
|
/// <param name="tmethod"></param>
|
||||||
|
private RestDeserialiseMethod<TRequest, TResponse> m_method;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The method used to check whether a request is trusted.
|
||||||
|
/// </summary>
|
||||||
|
private CheckTrustedSourceMethod m_tmethod;
|
||||||
|
|
||||||
|
public RestDeserialiseTrustedHandler(string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method, CheckTrustedSourceMethod tmethod)
|
||||||
|
: base(httpMethod, path)
|
||||||
|
{
|
||||||
|
m_tmethod = tmethod;
|
||||||
|
m_method = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(string path, Stream request, Stream responseStream,
|
||||||
|
OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
TRequest deserial = default(TRequest);
|
||||||
|
bool fail = false;
|
||||||
|
|
||||||
|
using (XmlTextReader xmlReader = new XmlTextReader(request))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
XmlSerializer deserializer = new XmlSerializer(typeof(TRequest));
|
||||||
|
deserial = (TRequest)deserializer.Deserialize(xmlReader);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.Error("[REST]: Deserialization problem. Ignoring request. " + e);
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TResponse response = default(TResponse);
|
||||||
|
if (!fail && m_tmethod(httpRequest.RemoteIPEndPoint))
|
||||||
|
{
|
||||||
|
response = m_method(deserial);
|
||||||
|
}
|
||||||
|
|
||||||
|
using (XmlWriter xmlWriter = XmlTextWriter.Create(responseStream))
|
||||||
|
{
|
||||||
|
XmlSerializer serializer = new XmlSerializer(typeof(TResponse));
|
||||||
|
serializer.Serialize(xmlWriter, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public class RestStreamHandler : BaseStreamHandler
|
||||||
|
{
|
||||||
|
private RestMethod m_restMethod;
|
||||||
|
|
||||||
|
public RestMethod Method
|
||||||
|
{
|
||||||
|
get { return m_restMethod; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
Encoding encoding = Encoding.UTF8;
|
||||||
|
StreamReader streamReader = new StreamReader(request, encoding);
|
||||||
|
|
||||||
|
string requestBody = streamReader.ReadToEnd();
|
||||||
|
streamReader.Close();
|
||||||
|
|
||||||
|
string param = GetParam(path);
|
||||||
|
string responseString = m_restMethod(requestBody, path, param, httpRequest, httpResponse);
|
||||||
|
|
||||||
|
return Encoding.UTF8.GetBytes(responseString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RestStreamHandler(string httpMethod, string path, RestMethod restMethod) : base(httpMethod, path)
|
||||||
|
{
|
||||||
|
m_restMethod = restMethod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.Xml;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public class SynchronousRestObjectPoster
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Perform a synchronous REST request.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="verb"></param>
|
||||||
|
/// <param name="requestUrl"></param>
|
||||||
|
/// <param name="obj"> </param>
|
||||||
|
/// <returns></returns>
|
||||||
|
///
|
||||||
|
/// <exception cref="System.Net.WebException">Thrown if we encounter a network issue while posting
|
||||||
|
/// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
|
||||||
|
public static TResponse BeginPostObject<TRequest, TResponse>(string verb, string requestUrl, TRequest obj)
|
||||||
|
{
|
||||||
|
Type type = typeof (TRequest);
|
||||||
|
|
||||||
|
WebRequest request = WebRequest.Create(requestUrl);
|
||||||
|
request.Method = verb;
|
||||||
|
request.ContentType = "text/xml";
|
||||||
|
|
||||||
|
MemoryStream buffer = new MemoryStream();
|
||||||
|
|
||||||
|
XmlWriterSettings settings = new XmlWriterSettings();
|
||||||
|
settings.Encoding = Encoding.UTF8;
|
||||||
|
|
||||||
|
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
|
||||||
|
{
|
||||||
|
XmlSerializer serializer = new XmlSerializer(type);
|
||||||
|
serializer.Serialize(writer, obj);
|
||||||
|
writer.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = (int) buffer.Length;
|
||||||
|
request.ContentLength = length;
|
||||||
|
|
||||||
|
Stream requestStream = request.GetRequestStream();
|
||||||
|
requestStream.Write(buffer.ToArray(), 0, length);
|
||||||
|
TResponse deserial = default(TResponse);
|
||||||
|
using (WebResponse resp = request.GetResponse())
|
||||||
|
{
|
||||||
|
XmlSerializer deserializer = new XmlSerializer(typeof (TResponse));
|
||||||
|
deserial = (TResponse) deserializer.Deserialize(resp.GetResponseStream());
|
||||||
|
}
|
||||||
|
return deserial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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 Nwc.XmlRpc;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
{
|
||||||
|
public delegate XmlRpcResponse XmlRpcMethod(XmlRpcRequest request);
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.Collections.Generic;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers
|
||||||
|
{
|
||||||
|
public class MessageServerInfo
|
||||||
|
{
|
||||||
|
public string URI;
|
||||||
|
public string sendkey;
|
||||||
|
public string recvkey;
|
||||||
|
public List<ulong> responsibleForRegions;
|
||||||
|
|
||||||
|
public MessageServerInfo()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return URI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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 OpenSimulator 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.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using log4net;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Data;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers
|
||||||
|
{
|
||||||
|
public class PostAssetStreamHandler : BaseStreamHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
// private OpenAsset_Main m_assetManager;
|
||||||
|
private IAssetDataPlugin m_assetProvider;
|
||||||
|
|
||||||
|
public override byte[] Handle(string path, Stream request,
|
||||||
|
OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
string param = GetParam(path);
|
||||||
|
|
||||||
|
UUID assetId;
|
||||||
|
if (param.Length > 0)
|
||||||
|
UUID.TryParse(param, out assetId);
|
||||||
|
// byte[] txBuffer = new byte[4096];
|
||||||
|
|
||||||
|
XmlSerializer xs = new XmlSerializer(typeof (AssetBase));
|
||||||
|
AssetBase asset = (AssetBase) xs.Deserialize(request);
|
||||||
|
|
||||||
|
m_log.InfoFormat("[REST]: Creating asset {0}", asset.FullID);
|
||||||
|
m_assetProvider.CreateAsset(asset);
|
||||||
|
|
||||||
|
return new byte[] {};
|
||||||
|
}
|
||||||
|
|
||||||
|
public PostAssetStreamHandler(IAssetDataPlugin assetProvider)
|
||||||
|
: base("POST", "/assets")
|
||||||
|
{
|
||||||
|
// m_assetManager = assetManager;
|
||||||
|
m_assetProvider = assetProvider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,394 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.Collections.Specialized;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
using HttpServer;
|
||||||
|
using HttpServer.FormDecoders;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NUnit.Framework.SyntaxHelpers;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Servers.Tests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class OSHttpTests
|
||||||
|
{
|
||||||
|
// we need an IHttpClientContext for our tests
|
||||||
|
public class TestHttpClientContext: IHttpClientContext
|
||||||
|
{
|
||||||
|
private bool _secured;
|
||||||
|
public bool Secured
|
||||||
|
{
|
||||||
|
get { return _secured; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestHttpClientContext(bool secured)
|
||||||
|
{
|
||||||
|
_secured = secured;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Disconnect(SocketError error) {}
|
||||||
|
public void Respond(string httpVersion, HttpStatusCode statusCode, string reason, string body) {}
|
||||||
|
public void Respond(string httpVersion, HttpStatusCode statusCode, string reason) {}
|
||||||
|
public void Respond(string body) {}
|
||||||
|
public void Send(byte[] buffer) {}
|
||||||
|
public void Send(byte[] buffer, int offset, int size) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestHttpRequest: IHttpRequest
|
||||||
|
{
|
||||||
|
public bool BodyIsComplete
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
public string[] AcceptTypes
|
||||||
|
{
|
||||||
|
get {return _acceptTypes; }
|
||||||
|
}
|
||||||
|
private string[] _acceptTypes;
|
||||||
|
public Stream Body
|
||||||
|
{
|
||||||
|
get { return _body; }
|
||||||
|
set { _body = value;}
|
||||||
|
}
|
||||||
|
private Stream _body;
|
||||||
|
public ConnectionType Connection
|
||||||
|
{
|
||||||
|
get { return _connection; }
|
||||||
|
set { _connection = value; }
|
||||||
|
}
|
||||||
|
private ConnectionType _connection;
|
||||||
|
public int ContentLength
|
||||||
|
{
|
||||||
|
get { return _contentLength; }
|
||||||
|
set { _contentLength = value; }
|
||||||
|
}
|
||||||
|
private int _contentLength;
|
||||||
|
public NameValueCollection Headers
|
||||||
|
{
|
||||||
|
get { return _headers; }
|
||||||
|
}
|
||||||
|
private NameValueCollection _headers = new NameValueCollection();
|
||||||
|
public string HttpVersion
|
||||||
|
{
|
||||||
|
get { return _httpVersion; }
|
||||||
|
set { _httpVersion = value; }
|
||||||
|
}
|
||||||
|
private string _httpVersion = null;
|
||||||
|
public string Method
|
||||||
|
{
|
||||||
|
get { return _method; }
|
||||||
|
set { _method = value; }
|
||||||
|
}
|
||||||
|
private string _method = null;
|
||||||
|
public HttpInput QueryString
|
||||||
|
{
|
||||||
|
get { return _queryString; }
|
||||||
|
}
|
||||||
|
private HttpInput _queryString = null;
|
||||||
|
public Uri Uri
|
||||||
|
{
|
||||||
|
get { return _uri; }
|
||||||
|
set { _uri = value; }
|
||||||
|
}
|
||||||
|
private Uri _uri = null;
|
||||||
|
public string[] UriParts
|
||||||
|
{
|
||||||
|
get { return _uri.Segments; }
|
||||||
|
}
|
||||||
|
public HttpParam Param
|
||||||
|
{
|
||||||
|
get { return null; }
|
||||||
|
}
|
||||||
|
public HttpForm Form
|
||||||
|
{
|
||||||
|
get { return null; }
|
||||||
|
}
|
||||||
|
public bool IsAjax
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
}
|
||||||
|
public RequestCookies Cookies
|
||||||
|
{
|
||||||
|
get { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestHttpRequest() {}
|
||||||
|
|
||||||
|
public TestHttpRequest(string contentEncoding, string contentType, string userAgent,
|
||||||
|
string remoteAddr, string remotePort, string[] acceptTypes,
|
||||||
|
ConnectionType connectionType, int contentLength, Uri uri)
|
||||||
|
{
|
||||||
|
_headers["content-encoding"] = contentEncoding;
|
||||||
|
_headers["content-type"] = contentType;
|
||||||
|
_headers["user-agent"] = userAgent;
|
||||||
|
_headers["remote_addr"] = remoteAddr;
|
||||||
|
_headers["remote_port"] = remotePort;
|
||||||
|
|
||||||
|
_acceptTypes = acceptTypes;
|
||||||
|
_connection = connectionType;
|
||||||
|
_contentLength = contentLength;
|
||||||
|
_uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DecodeBody(FormDecoderProvider providers) {}
|
||||||
|
public void SetCookies(RequestCookies cookies) {}
|
||||||
|
public void AddHeader(string name, string value)
|
||||||
|
{
|
||||||
|
_headers.Add(name, value);
|
||||||
|
}
|
||||||
|
public int AddToBody(byte[] bytes, int offset, int length)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
public void Clear() {}
|
||||||
|
|
||||||
|
public object Clone()
|
||||||
|
{
|
||||||
|
TestHttpRequest clone = new TestHttpRequest();
|
||||||
|
clone._acceptTypes = _acceptTypes;
|
||||||
|
clone._connection = _connection;
|
||||||
|
clone._contentLength = _contentLength;
|
||||||
|
clone._uri = _uri;
|
||||||
|
clone._headers = new NameValueCollection(_headers);
|
||||||
|
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TestHttpResponse: IHttpResponse
|
||||||
|
{
|
||||||
|
public Stream Body
|
||||||
|
{
|
||||||
|
get { return _body; }
|
||||||
|
|
||||||
|
set { _body = value; }
|
||||||
|
}
|
||||||
|
private Stream _body;
|
||||||
|
|
||||||
|
public string ProtocolVersion
|
||||||
|
{
|
||||||
|
get { return _protocolVersion; }
|
||||||
|
set { _protocolVersion = value; }
|
||||||
|
}
|
||||||
|
private string _protocolVersion;
|
||||||
|
|
||||||
|
public bool Chunked
|
||||||
|
{
|
||||||
|
get { return _chunked; }
|
||||||
|
|
||||||
|
set { _chunked = value; }
|
||||||
|
}
|
||||||
|
private bool _chunked;
|
||||||
|
|
||||||
|
public ConnectionType Connection
|
||||||
|
{
|
||||||
|
get { return _connection; }
|
||||||
|
|
||||||
|
set { _connection = value; }
|
||||||
|
}
|
||||||
|
private ConnectionType _connection;
|
||||||
|
|
||||||
|
public Encoding Encoding
|
||||||
|
{
|
||||||
|
get { return _encoding; }
|
||||||
|
|
||||||
|
set { _encoding = value; }
|
||||||
|
}
|
||||||
|
private Encoding _encoding;
|
||||||
|
|
||||||
|
public int KeepAlive
|
||||||
|
{
|
||||||
|
get { return _keepAlive; }
|
||||||
|
|
||||||
|
set { _keepAlive = value; }
|
||||||
|
}
|
||||||
|
private int _keepAlive;
|
||||||
|
|
||||||
|
public HttpStatusCode Status
|
||||||
|
{
|
||||||
|
get { return _status; }
|
||||||
|
|
||||||
|
set { _status = value; }
|
||||||
|
}
|
||||||
|
private HttpStatusCode _status;
|
||||||
|
|
||||||
|
public string Reason
|
||||||
|
{
|
||||||
|
get { return _reason; }
|
||||||
|
|
||||||
|
set { _reason = value; }
|
||||||
|
}
|
||||||
|
private string _reason;
|
||||||
|
|
||||||
|
public long ContentLength
|
||||||
|
{
|
||||||
|
get { return _contentLength; }
|
||||||
|
|
||||||
|
set { _contentLength = value; }
|
||||||
|
}
|
||||||
|
private long _contentLength;
|
||||||
|
|
||||||
|
public string ContentType
|
||||||
|
{
|
||||||
|
get { return _contentType; }
|
||||||
|
|
||||||
|
set { _contentType = value; }
|
||||||
|
}
|
||||||
|
private string _contentType;
|
||||||
|
|
||||||
|
public bool HeadersSent
|
||||||
|
{
|
||||||
|
get { return _headersSent; }
|
||||||
|
}
|
||||||
|
private bool _headersSent;
|
||||||
|
|
||||||
|
public bool Sent
|
||||||
|
{
|
||||||
|
get { return _sent; }
|
||||||
|
}
|
||||||
|
private bool _sent;
|
||||||
|
|
||||||
|
public ResponseCookies Cookies
|
||||||
|
{
|
||||||
|
get { return _cookies; }
|
||||||
|
}
|
||||||
|
private ResponseCookies _cookies = null;
|
||||||
|
|
||||||
|
public TestHttpResponse()
|
||||||
|
{
|
||||||
|
_headersSent = false;
|
||||||
|
_sent = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddHeader(string name, string value) {}
|
||||||
|
public void Send()
|
||||||
|
{
|
||||||
|
if (!_headersSent) SendHeaders();
|
||||||
|
if (_sent) throw new InvalidOperationException("stuff already sent");
|
||||||
|
_sent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendBody(byte[] buffer, int offset, int count)
|
||||||
|
{
|
||||||
|
if (!_headersSent) SendHeaders();
|
||||||
|
_sent = true;
|
||||||
|
}
|
||||||
|
public void SendBody(byte[] buffer)
|
||||||
|
{
|
||||||
|
if (!_headersSent) SendHeaders();
|
||||||
|
_sent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendHeaders()
|
||||||
|
{
|
||||||
|
if (_headersSent) throw new InvalidOperationException("headers already sent");
|
||||||
|
_headersSent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Redirect(Uri uri) {}
|
||||||
|
public void Redirect(string url) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public OSHttpRequest req0;
|
||||||
|
public OSHttpRequest req1;
|
||||||
|
|
||||||
|
public OSHttpResponse rsp0;
|
||||||
|
|
||||||
|
public IPEndPoint ipEP0;
|
||||||
|
|
||||||
|
[TestFixtureSetUp]
|
||||||
|
public void Init()
|
||||||
|
{
|
||||||
|
TestHttpRequest threq0 = new TestHttpRequest("utf-8", "text/xml", "OpenSim Test Agent", "192.168.0.1", "4711",
|
||||||
|
new string[] {"text/xml"},
|
||||||
|
ConnectionType.KeepAlive, 4711,
|
||||||
|
new Uri("http://127.0.0.1/admin/inventory/Dr+Who/Tardis"));
|
||||||
|
threq0.Method = "GET";
|
||||||
|
threq0.HttpVersion = HttpHelper.HTTP10;
|
||||||
|
|
||||||
|
TestHttpRequest threq1 = new TestHttpRequest("utf-8", "text/xml", "OpenSim Test Agent", "192.168.0.1", "4711",
|
||||||
|
new string[] {"text/xml"},
|
||||||
|
ConnectionType.KeepAlive, 4711,
|
||||||
|
new Uri("http://127.0.0.1/admin/inventory/Dr+Who/Tardis?a=0&b=1&c=2"));
|
||||||
|
threq1.Method = "POST";
|
||||||
|
threq1.HttpVersion = HttpHelper.HTTP11;
|
||||||
|
threq1.Headers["x-wuff"] = "wuffwuff";
|
||||||
|
threq1.Headers["www-authenticate"] = "go away";
|
||||||
|
|
||||||
|
req0 = new OSHttpRequest(new TestHttpClientContext(false), threq0);
|
||||||
|
req1 = new OSHttpRequest(new TestHttpClientContext(false), threq1);
|
||||||
|
|
||||||
|
rsp0 = new OSHttpResponse(new TestHttpResponse());
|
||||||
|
|
||||||
|
ipEP0 = new IPEndPoint(IPAddress.Parse("192.168.0.1"), 4711);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void T000_OSHttpRequest()
|
||||||
|
{
|
||||||
|
Assert.That(req0.HttpMethod, Is.EqualTo("GET"));
|
||||||
|
Assert.That(req0.ContentType, Is.EqualTo("text/xml"));
|
||||||
|
Assert.That(req0.ContentLength, Is.EqualTo(4711));
|
||||||
|
|
||||||
|
Assert.That(req1.HttpMethod, Is.EqualTo("POST"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void T001_OSHttpRequestHeaderAccess()
|
||||||
|
{
|
||||||
|
Assert.That(req1.Headers["x-wuff"], Is.EqualTo("wuffwuff"));
|
||||||
|
Assert.That(req1.Headers.Get("x-wuff"), Is.EqualTo("wuffwuff"));
|
||||||
|
|
||||||
|
Assert.That(req1.Headers["www-authenticate"], Is.EqualTo("go away"));
|
||||||
|
Assert.That(req1.Headers.Get("www-authenticate"), Is.EqualTo("go away"));
|
||||||
|
|
||||||
|
Assert.That(req0.RemoteIPEndPoint, Is.EqualTo(ipEP0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void T002_OSHttpRequestUriParsing()
|
||||||
|
{
|
||||||
|
Assert.That(req0.RawUrl, Is.EqualTo("/admin/inventory/Dr+Who/Tardis"));
|
||||||
|
Assert.That(req1.Url.ToString(), Is.EqualTo("http://127.0.0.1/admin/inventory/Dr+Who/Tardis?a=0&b=1&c=2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void T100_OSHttpResponse()
|
||||||
|
{
|
||||||
|
rsp0.ContentType = "text/xml";
|
||||||
|
Assert.That(rsp0.ContentType, Is.EqualTo("text/xml"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OpenSim
|
||||||
|
{
|
||||||
|
public class VersionInfo
|
||||||
|
{
|
||||||
|
/// <value>
|
||||||
|
/// This is the OpenSim version string. Change this if you are releasing a new OpenSim version.
|
||||||
|
/// </value>
|
||||||
|
public readonly static string Version = "OpenSimulator Server 0.6.4"; // stay with 27 chars (used in regioninfo)
|
||||||
|
|
||||||
|
/// <value>
|
||||||
|
/// This is the external interface version. It is separate from the OpenSimulator project version.
|
||||||
|
///
|
||||||
|
/// This version number should be
|
||||||
|
/// increased by 1 every time a code change makes the previous OpenSimulator revision incompatible
|
||||||
|
/// with the new revision. This will usually be due to interregion or grid facing interface changes.
|
||||||
|
///
|
||||||
|
/// Changes which are compatible with an older revision (e.g. older revisions experience degraded functionality
|
||||||
|
/// but not outright failure) do not need a version number increment.
|
||||||
|
///
|
||||||
|
/// Having this version number allows the grid service to reject connections from regions running a version
|
||||||
|
/// of the code that is too old.
|
||||||
|
///
|
||||||
|
/// </value>
|
||||||
|
public readonly static int MajorInterfaceVersion = 3;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue