OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
OSHttpXmlRpcHandler.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Collections.Generic;
30 using System.IO;
31 using System.Net;
32 using System.Reflection;
33 using System.Text;
34 using System.Text.RegularExpressions;
35 using System.Xml;
36 using log4net;
37 using Nwc.XmlRpc;
38 
39 namespace OpenSim.Framework.Servers.HttpServer
40 {
41  public delegate XmlRpcResponse OSHttpXmlRpcProcessor(XmlRpcRequest request);
42 
44  {
45  private static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 
55  protected bool XmlRpcMethodMatch(OSHttpRequest req)
56  {
57  XmlRpcRequest xmlRpcRequest = null;
58 
59  // check whether req is already reified
60  // if not: reify (and post to whiteboard)
61  try
62  {
63  if (req.Whiteboard.ContainsKey("xmlrequest"))
64  {
65  xmlRpcRequest = req.Whiteboard["xmlrequest"] as XmlRpcRequest;
66  }
67  else
68  {
69  StreamReader body = new StreamReader(req.InputStream);
70  string requestBody = body.ReadToEnd();
71  xmlRpcRequest = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody);
72  req.Whiteboard["xmlrequest"] = xmlRpcRequest;
73  }
74  }
75  catch (XmlException)
76  {
77  _log.ErrorFormat("[OSHttpXmlRpcHandler] failed to deserialize XmlRpcRequest from {0}", req.ToString());
78  return false;
79  }
80 
81  // check against methodName
82  if ((null != xmlRpcRequest)
83  && !String.IsNullOrEmpty(xmlRpcRequest.MethodName)
84  && xmlRpcRequest.MethodName == _methodName)
85  {
86  _log.DebugFormat("[OSHttpXmlRpcHandler] located handler {0} for {1}", _methodName, req.ToString());
87  return true;
88  }
89 
90  return false;
91  }
92 
93  // contains handler for processing XmlRpc Request
94  private XmlRpcMethod _handler;
95 
96  // contains XmlRpc method name
97  private string _methodName;
98 
99 
116  public OSHttpXmlRpcHandler(XmlRpcMethod handler, string methodName, Regex path,
117  Dictionary<string, Regex> headers, Regex whitelist)
118  : base(new Regex(@"^POST$", RegexOptions.IgnoreCase | RegexOptions.Compiled), path, null, headers,
119  new Regex(@"^(text|application)/xml", RegexOptions.IgnoreCase | RegexOptions.Compiled),
120  whitelist)
121  {
122  _handler = handler;
123  _methodName = methodName;
124  }
125 
126 
133  public OSHttpXmlRpcHandler(XmlRpcMethod handler, string methodName)
134  : this(handler, methodName, null, null, null)
135  {
136  }
137 
138 
142  public override OSHttpHandlerResult Process(OSHttpRequest request)
143  {
144  XmlRpcResponse xmlRpcResponse;
145  string responseString;
146 
147  // check whether we are interested in this request
148  if (!XmlRpcMethodMatch(request)) return OSHttpHandlerResult.Pass;
149 
150 
151  OSHttpResponse resp = new OSHttpResponse(request);
152  try
153  {
154  // reified XmlRpcRequest must still be on the whiteboard
155  XmlRpcRequest xmlRpcRequest = request.Whiteboard["xmlrequest"] as XmlRpcRequest;
156  xmlRpcResponse = _handler(xmlRpcRequest);
157  responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse);
158 
159  resp.ContentType = "text/xml";
160  byte[] buffer = Encoding.UTF8.GetBytes(responseString);
161 
162  resp.SendChunked = false;
163  resp.ContentLength = buffer.Length;
164  resp.ContentEncoding = Encoding.UTF8;
165 
166  resp.Body.Write(buffer, 0, buffer.Length);
167  resp.Body.Flush();
168 
169  resp.Send();
170 
171  }
172  catch (Exception ex)
173  {
174  _log.WarnFormat("[OSHttpXmlRpcHandler]: Error: {0}", ex.Message);
175  return OSHttpHandlerResult.Pass;
176  }
177  return OSHttpHandlerResult.Done;
178  }
179  }
180 }
override OSHttpHandlerResult Process(OSHttpRequest request)
Invoked by OSHttpRequestPump.
OSHttpXmlRpcHandler(XmlRpcMethod handler, string methodName, Regex path, Dictionary< string, Regex > headers, Regex whitelist)
Instantiate an XmlRpc handler.
OSHttpResponse is the OpenSim representation of an HTTP response.
bool XmlRpcMethodMatch(OSHttpRequest req)
XmlRpcMethodMatch tries to reify (deserialize) an incoming XmlRpc request (and posts it to the "white...
delegate XmlRpcResponse OSHttpXmlRpcProcessor(XmlRpcRequest request)
delegate XmlRpcResponse XmlRpcMethod(XmlRpcRequest request, IPEndPoint client)
OSHttpXmlRpcHandler(XmlRpcMethod handler, string methodName)
Instantiate an XmlRpc handler.