From 3376b82501000692d6dac24b051af738cdaf2737 Mon Sep 17 00:00:00 2001
From: MW
Date: Thu, 24 May 2007 12:16:50 +0000
Subject: Some more code refactoring, plus a restructuring of the directories
so that the Grid servers can be a separate solution to the region server.
---
Common-Source/XmlRpcCS/XmlRpcServer.cs | 239 +++++++++++++++++++++++++++++++++
1 file changed, 239 insertions(+)
create mode 100644 Common-Source/XmlRpcCS/XmlRpcServer.cs
(limited to 'Common-Source/XmlRpcCS/XmlRpcServer.cs')
diff --git a/Common-Source/XmlRpcCS/XmlRpcServer.cs b/Common-Source/XmlRpcCS/XmlRpcServer.cs
new file mode 100644
index 0000000..1c226c1
--- /dev/null
+++ b/Common-Source/XmlRpcCS/XmlRpcServer.cs
@@ -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;
+
+ /// A restricted HTTP server for use with XML-RPC.
+ /// 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.
+ ///
+ 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
+
+ ///Constructor with port and address.
+ ///This constructor sets up a TcpListener listening on the
+ ///given port and address. It also calls a Thread on the method StartListen().
+ ///IPAddress value of the address to listen on.
+ ///Int value of the port to listen on.
+ public XmlRpcServer(IPAddress address, int port)
+ {
+ _port = port;
+ _address = address;
+ _handlers = new Hashtable();
+ _system = new XmlRpcSystemObject(this);
+ _wc = new WaitCallback(WaitCallback);
+ }
+
+ ///Basic constructor.
+ ///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.
+ ///Int value of the port to listen on.
+ public XmlRpcServer(int port) : this(IPAddress.Any, port) { }
+
+ /// Start the server.
+ 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);
+ }
+ }
+
+ /// Stop the server.
+ 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);
+ }
+ }
+
+ /// Get an enumeration of my XML-RPC handlers.
+ /// IEnumerable the handler enumeration.
+ public IEnumerator GetEnumerator()
+ {
+ return _handlers.GetEnumerator();
+ }
+
+ /// Retrieve a handler by name.
+ /// String naming a handler
+ /// Object that is the handler.
+ public Object this[String name]
+ {
+ get { return _handlers[name]; }
+ }
+
+ ///
+ ///This method Accepts new connections and dispatches them when appropriate.
+ ///
+ public void StartListen()
+ {
+ while (true && _myListener != null)
+ {
+ //Accept a new connection
+ XmlRpcResponder responder = new XmlRpcResponder(this, _myListener.AcceptTcpClient());
+ ThreadPool.QueueUserWorkItem(_wc, responder);
+ }
+ }
+
+
+ ///
+ ///Add an XML-RPC handler object by name.
+ ///
+ ///String XML-RPC dispatch name of this object.
+ ///Object The object that is the XML-RPC handler.
+ public void Add(String name, Object obj)
+ {
+ _handlers.Add(name, obj);
+ }
+
+ ///Return a C# object.method name for and XML-RPC object.method name pair.
+ ///The XML-RPC object.method.
+ ///String of form object.method for the underlying C# method.
+ 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);
+ }
+
+ ///Invoke a method described in a request.
+ ///XmlRpcRequest containing a method descriptions.
+ ///
+ ///
+ public Object Invoke(XmlRpcRequest req)
+ {
+ return Invoke(req.MethodNameObject, req.MethodNameMethod, req.Params);
+ }
+
+ ///Invoke a method on a named handler.
+ ///String The name of the handler.
+ ///String The name of the method to invoke on the handler.
+ ///IList The parameters to invoke the method with.
+ ///
+ 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);
+ }
+
+ /// The method the thread pool invokes when a thread is available to handle an HTTP request.
+ /// TcpClient from the socket accept.
+ 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();
+ }
+
+ ///
+ /// This function send the Header Information to the client (Browser)
+ ///
+ /// HTTP Version
+ /// Mime Type
+ /// Total Bytes to be sent in the body
+ ///
+ /// Socket reference
+ 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);
+ }
+ }
+}
--
cgit v1.1