parent
43f1d77b9f
commit
258847a83b
@ -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