Moved programs into the Programs folder
git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@1958 52acb1d6-8a22-11de-b505-999d5b087335
This commit is contained in:
239
Programs/SLProxy/XmlRpcCS/XmlRpcServer.cs
Normal file
239
Programs/SLProxy/XmlRpcCS/XmlRpcServer.cs
Normal file
@@ -0,0 +1,239 @@
|
||||
namespace Nwc.XmlRpc
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
|
||||
/// <summary>A restricted HTTP server for use with XML-RPC.</summary>
|
||||
/// <remarks>It only handles POST requests, and only POSTs representing XML-RPC calls.
|
||||
/// In addition to dispatching requests it also provides a registry for request handlers.
|
||||
/// </remarks>
|
||||
public class XmlRpcServer : IEnumerable
|
||||
{
|
||||
#pragma warning disable 0414 // disable "private field assigned but not used"
|
||||
const int RESPONDER_COUNT = 10;
|
||||
private TcpListener _myListener;
|
||||
private int _port;
|
||||
private IPAddress _address;
|
||||
private IDictionary _handlers;
|
||||
private XmlRpcSystemObject _system;
|
||||
private WaitCallback _wc;
|
||||
#pragma warning restore 0414
|
||||
|
||||
///<summary>Constructor with port and address.</summary>
|
||||
///<remarks>This constructor sets up a TcpListener listening on the
|
||||
///given port and address. It also calls a Thread on the method StartListen().</remarks>
|
||||
///<param name="address"><c>IPAddress</c> value of the address to listen on.</param>
|
||||
///<param name="port"><c>Int</c> value of the port to listen on.</param>
|
||||
public XmlRpcServer(IPAddress address, int port)
|
||||
{
|
||||
_port = port;
|
||||
_address = address;
|
||||
_handlers = new Hashtable();
|
||||
_system = new XmlRpcSystemObject(this);
|
||||
_wc = new WaitCallback(WaitCallback);
|
||||
}
|
||||
|
||||
///<summary>Basic constructor.</summary>
|
||||
///<remarks>This constructor sets up a TcpListener listening on the
|
||||
///given port. It also calls a Thread on the method StartListen(). IPAddress.Any
|
||||
///is assumed as the address here.</remarks>
|
||||
///<param name="port"><c>Int</c> value of the port to listen on.</param>
|
||||
public XmlRpcServer(int port) : this(IPAddress.Any, port) { }
|
||||
|
||||
/// <summary>Start the server.</summary>
|
||||
public void Start()
|
||||
{
|
||||
try
|
||||
{
|
||||
Stop();
|
||||
//start listing on the given port
|
||||
// IPAddress addr = IPAddress.Parse("127.0.0.1");
|
||||
lock (this)
|
||||
{
|
||||
_myListener = new TcpListener(IPAddress.Any, _port);
|
||||
_myListener.Start();
|
||||
//start the thread which calls the method 'StartListen'
|
||||
Thread th = new Thread(new ThreadStart(StartListen));
|
||||
th.Start();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.WriteEntry("An Exception Occurred while Listening :" + e.ToString(), LogLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Stop the server.</summary>
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_myListener != null)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
_myListener.Stop();
|
||||
_myListener = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.WriteEntry("An Exception Occurred while stopping :" +
|
||||
e.ToString(), LogLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Get an enumeration of my XML-RPC handlers.</summary>
|
||||
/// <returns><c>IEnumerable</c> the handler enumeration.</returns>
|
||||
public IEnumerator GetEnumerator()
|
||||
{
|
||||
return _handlers.GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>Retrieve a handler by name.</summary>
|
||||
/// <param name="name"><c>String</c> naming a handler</param>
|
||||
/// <returns><c>Object</c> that is the handler.</returns>
|
||||
public Object this[String name]
|
||||
{
|
||||
get { return _handlers[name]; }
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///This method Accepts new connections and dispatches them when appropriate.
|
||||
///</summary>
|
||||
public void StartListen()
|
||||
{
|
||||
while (true && _myListener != null)
|
||||
{
|
||||
//Accept a new connection
|
||||
XmlRpcResponder responder = new XmlRpcResponder(this, _myListener.AcceptTcpClient());
|
||||
ThreadPool.QueueUserWorkItem(_wc, responder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///<summary>
|
||||
///Add an XML-RPC handler object by name.
|
||||
///</summary>
|
||||
///<param name="name"><c>String</c> XML-RPC dispatch name of this object.</param>
|
||||
///<param name="obj"><c>Object</c> The object that is the XML-RPC handler.</param>
|
||||
public void Add(String name, Object obj)
|
||||
{
|
||||
_handlers.Add(name, obj);
|
||||
}
|
||||
|
||||
///<summary>Return a C# object.method name for and XML-RPC object.method name pair.</summary>
|
||||
///<param name="methodName">The XML-RPC object.method.</param>
|
||||
///<returns><c>String</c> of form object.method for the underlying C# method.</returns>
|
||||
public String MethodName(String methodName)
|
||||
{
|
||||
int dotAt = methodName.LastIndexOf('.');
|
||||
|
||||
if (dotAt == -1)
|
||||
{
|
||||
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_METHOD,
|
||||
XmlRpcErrorCodes.SERVER_ERROR_METHOD_MSG + ": Bad method name " + methodName);
|
||||
}
|
||||
|
||||
String objectName = methodName.Substring(0, dotAt);
|
||||
Object target = _handlers[objectName];
|
||||
|
||||
if (target == null)
|
||||
{
|
||||
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_METHOD,
|
||||
XmlRpcErrorCodes.SERVER_ERROR_METHOD_MSG + ": Object " + objectName + " not found");
|
||||
}
|
||||
|
||||
return target.GetType().FullName + "." + methodName.Substring(dotAt + 1);
|
||||
}
|
||||
|
||||
///<summary>Invoke a method described in a request.</summary>
|
||||
///<param name="req"><c>XmlRpcRequest</c> containing a method descriptions.</param>
|
||||
/// <seealso cref="XmlRpcSystemObject.Invoke"/>
|
||||
/// <seealso cref="XmlRpcServer.Invoke(String,String,IList)"/>
|
||||
public Object Invoke(XmlRpcRequest req)
|
||||
{
|
||||
return Invoke(req.MethodNameObject, req.MethodNameMethod, req.Params);
|
||||
}
|
||||
|
||||
///<summary>Invoke a method on a named handler.</summary>
|
||||
///<param name="objectName"><c>String</c> The name of the handler.</param>
|
||||
///<param name="methodName"><c>String</c> The name of the method to invoke on the handler.</param>
|
||||
///<param name="parameters"><c>IList</c> The parameters to invoke the method with.</param>
|
||||
/// <seealso cref="XmlRpcSystemObject.Invoke"/>
|
||||
public Object Invoke(String objectName, String methodName, IList parameters)
|
||||
{
|
||||
Object target = _handlers[objectName];
|
||||
|
||||
if (target == null)
|
||||
{
|
||||
throw new XmlRpcException(XmlRpcErrorCodes.SERVER_ERROR_METHOD,
|
||||
XmlRpcErrorCodes.SERVER_ERROR_METHOD_MSG + ": Object " + objectName + " not found");
|
||||
}
|
||||
|
||||
return XmlRpcSystemObject.Invoke(target, methodName, parameters);
|
||||
}
|
||||
|
||||
/// <summary>The method the thread pool invokes when a thread is available to handle an HTTP request.</summary>
|
||||
/// <param name="responder">TcpClient from the socket accept.</param>
|
||||
public void WaitCallback(object responder)
|
||||
{
|
||||
XmlRpcResponder resp = (XmlRpcResponder)responder;
|
||||
|
||||
if (resp.HttpReq.HttpMethod == "POST")
|
||||
{
|
||||
try
|
||||
{
|
||||
resp.Respond();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.WriteEntry("Failed on post: " + e, LogLevel.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.WriteEntry("Only POST methods are supported: " + resp.HttpReq.HttpMethod +
|
||||
" ignored", LogLevel.Error);
|
||||
}
|
||||
|
||||
resp.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function send the Header Information to the client (Browser)
|
||||
/// </summary>
|
||||
/// <param name="sHttpVersion">HTTP Version</param>
|
||||
/// <param name="sMIMEHeader">Mime Type</param>
|
||||
/// <param name="iTotBytes">Total Bytes to be sent in the body</param>
|
||||
/// <param name="sStatusCode"></param>
|
||||
/// <param name="output">Socket reference</param>
|
||||
static public void HttpHeader(string sHttpVersion, string sMIMEHeader, long iTotBytes, string sStatusCode, TextWriter output)
|
||||
{
|
||||
String sBuffer = "";
|
||||
|
||||
// if Mime type is not provided set default to text/html
|
||||
if (sMIMEHeader.Length == 0)
|
||||
{
|
||||
sMIMEHeader = "text/html"; // Default Mime Type is text/html
|
||||
}
|
||||
|
||||
sBuffer += sHttpVersion + sStatusCode + "\r\n";
|
||||
sBuffer += "Connection: close\r\n";
|
||||
if (iTotBytes > 0)
|
||||
sBuffer += "Content-Length: " + iTotBytes + "\r\n";
|
||||
sBuffer += "Server: XmlRpcServer \r\n";
|
||||
sBuffer += "Content-Type: " + sMIMEHeader + "\r\n";
|
||||
sBuffer += "\r\n";
|
||||
|
||||
output.Write(sBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user