parent
a33b861cec
commit
b626c5bbf0
@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Xml.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
|
||||
namespace NzbDrone.Common.Http
|
||||
{
|
||||
public class XmlRpcRequestBuilder : HttpRequestBuilder
|
||||
{
|
||||
public static string XmlRpcContentType = "text/xml";
|
||||
|
||||
private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(XmlRpcRequestBuilder));
|
||||
|
||||
public string XmlMethod { get; private set; }
|
||||
public List<object> XmlParameters { get; private set; }
|
||||
|
||||
public XmlRpcRequestBuilder(string baseUrl)
|
||||
: base(baseUrl)
|
||||
{
|
||||
Method = HttpMethod.Post;
|
||||
XmlParameters = new List<object>();
|
||||
}
|
||||
|
||||
public XmlRpcRequestBuilder(bool useHttps, string host, int port, string urlBase = null)
|
||||
: this(BuildBaseUrl(useHttps, host, port, urlBase))
|
||||
{
|
||||
}
|
||||
|
||||
public override HttpRequestBuilder Clone()
|
||||
{
|
||||
var clone = base.Clone() as XmlRpcRequestBuilder;
|
||||
clone.XmlParameters = new List<object>(XmlParameters);
|
||||
return clone;
|
||||
}
|
||||
|
||||
public XmlRpcRequestBuilder Call(string method, params object[] parameters)
|
||||
{
|
||||
var clone = Clone() as XmlRpcRequestBuilder;
|
||||
clone.XmlMethod = method;
|
||||
clone.XmlParameters = parameters.ToList();
|
||||
return clone;
|
||||
}
|
||||
|
||||
protected override void Apply(HttpRequest request)
|
||||
{
|
||||
base.Apply(request);
|
||||
|
||||
request.Headers.ContentType = XmlRpcContentType;
|
||||
|
||||
var methodCallElements = new List<XElement> { new XElement("methodName", XmlMethod) };
|
||||
|
||||
if (XmlParameters.Any())
|
||||
{
|
||||
var argElements = XmlParameters.Select(x => new XElement("param", ConvertParameter(x))).ToList();
|
||||
var paramsElement = new XElement("params", argElements);
|
||||
methodCallElements.Add(paramsElement);
|
||||
}
|
||||
|
||||
var message = new XDocument(
|
||||
new XDeclaration("1.0", "utf-8", "yes"),
|
||||
new XElement("methodCall", methodCallElements));
|
||||
|
||||
var body = message.ToString();
|
||||
|
||||
Logger.Debug($"Executing remote method: {XmlMethod}");
|
||||
|
||||
Logger.Trace($"methodCall {XmlMethod} body:\n{body}");
|
||||
|
||||
request.SetContent(body);
|
||||
}
|
||||
|
||||
private static XElement ConvertParameter(object value)
|
||||
{
|
||||
XElement data;
|
||||
|
||||
if (value is string s)
|
||||
{
|
||||
data = new XElement("string", s);
|
||||
}
|
||||
else if (value is List<string> l)
|
||||
{
|
||||
data = new XElement("array", new XElement("data", l.Select(x => new XElement("value", new XElement("string", x)))));
|
||||
}
|
||||
else if (value is int i)
|
||||
{
|
||||
data = new XElement("int", i);
|
||||
}
|
||||
else if (value is byte[] bytes)
|
||||
{
|
||||
data = new XElement("base64", Convert.ToBase64String(bytes));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException($"Unhandled argument type {value.GetType().Name}");
|
||||
}
|
||||
|
||||
return new XElement("value", data);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
using NzbDrone.Core.Download.Extensions;
|
||||
|
||||
namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||
{
|
||||
public class RTorrentFault
|
||||
{
|
||||
public RTorrentFault(XElement element)
|
||||
{
|
||||
foreach (var e in element.XPathSelectElements("./value/struct/member"))
|
||||
{
|
||||
var name = e.ElementAsString("name");
|
||||
if (name == "faultCode")
|
||||
{
|
||||
FaultCode = e.Element("value").GetIntValue();
|
||||
}
|
||||
else if (name == "faultString")
|
||||
{
|
||||
FaultString = e.Element("value").GetStringValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int FaultCode { get; set; }
|
||||
public string FaultString { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
|
||||
namespace NzbDrone.Core.Download.Extensions
|
||||
{
|
||||
internal static class XmlExtensions
|
||||
{
|
||||
public static string GetStringValue(this XElement element)
|
||||
{
|
||||
return element.ElementAsString("string");
|
||||
}
|
||||
|
||||
public static long GetLongValue(this XElement element)
|
||||
{
|
||||
return element.ElementAsLong("i8");
|
||||
}
|
||||
|
||||
public static int GetIntValue(this XElement element)
|
||||
{
|
||||
return element.ElementAsInt("i4");
|
||||
}
|
||||
|
||||
public static string ElementAsString(this XElement element, XName name, bool trim = false)
|
||||
{
|
||||
var el = element.Element(name);
|
||||
|
||||
return string.IsNullOrWhiteSpace(el?.Value)
|
||||
? null
|
||||
: (trim ? el.Value.Trim() : el.Value);
|
||||
}
|
||||
|
||||
public static long ElementAsLong(this XElement element, XName name)
|
||||
{
|
||||
var el = element.Element(name);
|
||||
return long.TryParse(el?.Value, out long value) ? value : default;
|
||||
}
|
||||
|
||||
public static int ElementAsInt(this XElement element, XName name)
|
||||
{
|
||||
var el = element.Element(name);
|
||||
return int.TryParse(el?.Value, out int value) ? value : default(int);
|
||||
}
|
||||
|
||||
public static int GetIntResponse(this XDocument document)
|
||||
{
|
||||
return document.XPathSelectElement("./methodResponse/params/param/value").GetIntValue();
|
||||
}
|
||||
|
||||
public static string GetStringResponse(this XDocument document)
|
||||
{
|
||||
return document.XPathSelectElement("./methodResponse/params/param/value").GetStringValue();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue