From 7692f3e18f49fc57b63efbe54b7ac71de2fb7e16 Mon Sep 17 00:00:00 2001
From: Dr Scofield
Date: Mon, 14 Jul 2008 12:18:32 +0000
Subject: further work in progress on the HttpServer side: XmlRpc handler path
almost complete and soon to be ready for testing; OSHttpResponse code out.
---
OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs | 222 +++++++++++++++++++++++
1 file changed, 222 insertions(+)
create mode 100644 OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs
(limited to 'OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs')
diff --git a/OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs b/OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs
new file mode 100644
index 0000000..4205547
--- /dev/null
+++ b/OpenSim/Framework/Servers/OSHttpXmlRpcHandler.cs
@@ -0,0 +1,222 @@
+/*
+ * 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
+{
+ public delegate XmlRpcResponse OSHttpXmlRpcProcessor(XmlRpcRequest request);
+
+ public class OSHttpXmlRpcHandler: OSHttpHandler
+ {
+ private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ ///
+ /// Regular expression used to match against path of incoming
+ /// HTTP request. If you want to match any string either use
+ /// '.*' or null. To match for the emtpy string use '^$'
+ ///
+ public Regex Path
+ {
+ get { return _pathsRegex; }
+ }
+ private Regex _pathsRegex;
+
+ ///
+ /// Dictionary of (header name, regular expression) tuples,
+ /// allowing us to match on HTTP header fields.
+ ///
+ public Dictionary Headers
+ {
+ get { return _headers; }
+ }
+ private Dictionary _headers;
+
+ ///
+ /// Regex to whitelist IP end points. A null value disables
+ /// checking of IP end points.
+ ///
+ ///
+ /// This feature is currently not implemented as it requires
+ /// (trivial) changes to HttpServer.HttpListener that have not
+ /// been implemented.
+ ///
+ public Regex IPEndPointWhitelist
+ {
+ get { return _ipEndPointRegex; }
+ }
+ private Regex _ipEndPointRegex;
+
+ ///
+ /// An OSHttpHandler that matches on the "content-type" header can
+ /// supply an OSHttpContentTypeChecker delegate which will be
+ /// invoked by the request matcher in OSHttpRequestPump.
+ ///
+ /// true if the handler is interested in the content;
+ /// false otherwise
+ public OSHttpContentTypeChecker ContentTypeChecker
+ {
+ get
+ {
+ return delegate(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 OSHttpXmlRpcProcessor _handler;
+
+ // contains XmlRpc method name
+ private string _methodName;
+
+
+ ///
+ /// Instantiate an XmlRpc handler.
+ ///
+ /// OSHttpXmlRpcProcessor
+ /// delegate
+ /// XmlRpc method name
+ /// XmlRpc path prefix (regular expression)
+ /// Dictionary with header names and
+ /// regular expressions to match content of headers
+ /// IP whitelist of remote end points
+ /// to accept (regular expression)
+ ///
+ /// 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.
+ ///
+ public OSHttpXmlRpcHandler(OSHttpXmlRpcProcessor handler, string methodName, Regex path,
+ Dictionary headers, Regex whitelist)
+ {
+ _handler = handler;
+ _pathsRegex = path;
+ _methodName = methodName;
+
+ if (null == _headers) _headers = new Dictionary();
+ _headers.Add("content-type", new Regex(@"^(text|application)/xml", RegexOptions.IgnoreCase |
+ RegexOptions.Compiled));
+
+ _ipEndPointRegex = whitelist;
+ }
+
+
+ ///
+ /// Instantiate an XmlRpc handler.
+ ///
+ /// OSHttpXmlRpcProcessor
+ /// delegate
+ /// XmlRpc method name
+ public OSHttpXmlRpcHandler(OSHttpXmlRpcProcessor handler, string methodName)
+ : this(handler, methodName, null, null, null)
+ {
+ }
+
+
+ ///
+ /// Invoked by OSHttpRequestPump.
+ ///
+ public OSHttpHandlerResult Process(OSHttpRequest request)
+ {
+ XmlRpcResponse xmlRpcResponse;
+ string responseString;
+
+ 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;
+ }
+ }
+}
\ No newline at end of file
--
cgit v1.1