|
@@ -1,15 +1,16 @@
|
|
|
using MediaBrowser.Common.Extensions;
|
|
|
using MediaBrowser.Controller.Configuration;
|
|
|
-using MediaBrowser.Controller.Dlna;
|
|
|
using MediaBrowser.Controller.Drawing;
|
|
|
+using MediaBrowser.Controller.Dto;
|
|
|
+using MediaBrowser.Controller.Entities;
|
|
|
using MediaBrowser.Controller.Entities.Audio;
|
|
|
using MediaBrowser.Controller.Entities.Movies;
|
|
|
using MediaBrowser.Controller.Entities.TV;
|
|
|
using MediaBrowser.Controller.Library;
|
|
|
using MediaBrowser.Dlna.Didl;
|
|
|
+using MediaBrowser.Dlna.Server;
|
|
|
+using MediaBrowser.Dlna.Service;
|
|
|
using MediaBrowser.Model.Dlna;
|
|
|
-using MediaBrowser.Controller.Dto;
|
|
|
-using MediaBrowser.Controller.Entities;
|
|
|
using MediaBrowser.Model.Entities;
|
|
|
using MediaBrowser.Model.Logging;
|
|
|
using MediaBrowser.Model.Querying;
|
|
@@ -21,20 +22,17 @@ using System.Text;
|
|
|
using System.Threading;
|
|
|
using System.Xml;
|
|
|
|
|
|
-namespace MediaBrowser.Dlna.Server
|
|
|
+namespace MediaBrowser.Dlna.ContentDirectory
|
|
|
{
|
|
|
- public class ControlHandler
|
|
|
+ public class ControlHandler : BaseControlHandler
|
|
|
{
|
|
|
- private readonly ILogger _logger;
|
|
|
private readonly ILibraryManager _libraryManager;
|
|
|
private readonly IUserDataManager _userDataManager;
|
|
|
- private readonly IServerConfigurationManager _config;
|
|
|
private readonly User _user;
|
|
|
|
|
|
private const string NS_DC = "http://purl.org/dc/elements/1.1/";
|
|
|
private const string NS_DIDL = "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/";
|
|
|
private const string NS_DLNA = "urn:schemas-dlna-org:metadata-1-0/";
|
|
|
- private const string NS_SOAPENV = "http://schemas.xmlsoap.org/soap/envelope/";
|
|
|
private const string NS_UPNP = "urn:schemas-upnp-org:metadata-1-0/upnp/";
|
|
|
|
|
|
private readonly int _systemUpdateId;
|
|
@@ -45,151 +43,45 @@ namespace MediaBrowser.Dlna.Server
|
|
|
private readonly DeviceProfile _profile;
|
|
|
|
|
|
public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, IDtoService dtoService, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config)
|
|
|
+ : base(config, logger)
|
|
|
{
|
|
|
- _logger = logger;
|
|
|
_libraryManager = libraryManager;
|
|
|
_userDataManager = userDataManager;
|
|
|
_user = user;
|
|
|
_systemUpdateId = systemUpdateId;
|
|
|
- _config = config;
|
|
|
_profile = profile;
|
|
|
|
|
|
_didlBuilder = new DidlBuilder(profile, imageProcessor, serverAddress, dtoService);
|
|
|
}
|
|
|
|
|
|
- public ControlResponse ProcessControlRequest(ControlRequest request)
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- if (_config.Configuration.DlnaOptions.EnableDebugLogging)
|
|
|
- {
|
|
|
- LogRequest(request);
|
|
|
- }
|
|
|
-
|
|
|
- return ProcessControlRequestInternal(request);
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
- _logger.ErrorException("Error processing control request", ex);
|
|
|
-
|
|
|
- return GetErrorResponse(ex);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void LogRequest(ControlRequest request)
|
|
|
- {
|
|
|
- var builder = new StringBuilder();
|
|
|
-
|
|
|
- var headers = string.Join(", ", request.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray());
|
|
|
- builder.AppendFormat("Headers: {0}", headers);
|
|
|
- builder.AppendLine();
|
|
|
- builder.Append(request.InputXml);
|
|
|
-
|
|
|
- _logger.LogMultiline("Control request", LogSeverity.Debug, builder);
|
|
|
- }
|
|
|
-
|
|
|
- private ControlResponse ProcessControlRequestInternal(ControlRequest request)
|
|
|
+ protected override IEnumerable<KeyValuePair<string, string>> GetResult(string methodName, Headers methodParams)
|
|
|
{
|
|
|
- var soap = new XmlDocument();
|
|
|
- soap.LoadXml(request.InputXml);
|
|
|
- var sparams = new Headers();
|
|
|
- var body = soap.GetElementsByTagName("Body", NS_SOAPENV).Item(0);
|
|
|
-
|
|
|
- var method = body.FirstChild;
|
|
|
-
|
|
|
- foreach (var p in method.ChildNodes)
|
|
|
- {
|
|
|
- var e = p as XmlElement;
|
|
|
- if (e == null)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- sparams.Add(e.LocalName, e.InnerText.Trim());
|
|
|
- }
|
|
|
-
|
|
|
var deviceId = "test";
|
|
|
|
|
|
- IEnumerable<KeyValuePair<string, string>> result;
|
|
|
-
|
|
|
- _logger.Debug("Received control request {0}", method.Name);
|
|
|
-
|
|
|
var user = _user;
|
|
|
|
|
|
- if (string.Equals(method.LocalName, "GetSearchCapabilities", StringComparison.OrdinalIgnoreCase))
|
|
|
- result = HandleGetSearchCapabilities();
|
|
|
- else if (string.Equals(method.LocalName, "GetSortCapabilities", StringComparison.OrdinalIgnoreCase))
|
|
|
- result = HandleGetSortCapabilities();
|
|
|
- else if (string.Equals(method.LocalName, "GetSystemUpdateID", StringComparison.OrdinalIgnoreCase))
|
|
|
- result = HandleGetSystemUpdateID();
|
|
|
- else if (string.Equals(method.LocalName, "Browse", StringComparison.OrdinalIgnoreCase))
|
|
|
- result = HandleBrowse(sparams, user, deviceId);
|
|
|
- else if (string.Equals(method.LocalName, "X_GetFeatureList", StringComparison.OrdinalIgnoreCase))
|
|
|
- result = HandleXGetFeatureList();
|
|
|
- else if (string.Equals(method.LocalName, "X_SetBookmark", StringComparison.OrdinalIgnoreCase))
|
|
|
- result = HandleXSetBookmark(sparams, user);
|
|
|
- else if (string.Equals(method.LocalName, "Search", StringComparison.OrdinalIgnoreCase))
|
|
|
- result = HandleSearch(sparams, user, deviceId);
|
|
|
- else
|
|
|
- throw new ResourceNotFoundException("Unexpected control request name: " + method.LocalName);
|
|
|
+ if (string.Equals(methodName, "GetSearchCapabilities", StringComparison.OrdinalIgnoreCase))
|
|
|
+ return HandleGetSearchCapabilities();
|
|
|
|
|
|
- var env = new XmlDocument();
|
|
|
- env.AppendChild(env.CreateXmlDeclaration("1.0", "utf-8", string.Empty));
|
|
|
- var envelope = env.CreateElement("SOAP-ENV", "Envelope", NS_SOAPENV);
|
|
|
- env.AppendChild(envelope);
|
|
|
- envelope.SetAttribute("encodingStyle", NS_SOAPENV, "http://schemas.xmlsoap.org/soap/encoding/");
|
|
|
+ if (string.Equals(methodName, "GetSortCapabilities", StringComparison.OrdinalIgnoreCase))
|
|
|
+ return HandleGetSortCapabilities();
|
|
|
|
|
|
- var rbody = env.CreateElement("SOAP-ENV:Body", NS_SOAPENV);
|
|
|
- env.DocumentElement.AppendChild(rbody);
|
|
|
+ if (string.Equals(methodName, "GetSystemUpdateID", StringComparison.OrdinalIgnoreCase))
|
|
|
+ return HandleGetSystemUpdateID();
|
|
|
|
|
|
- var response = env.CreateElement(String.Format("u:{0}Response", method.LocalName), method.NamespaceURI);
|
|
|
- rbody.AppendChild(response);
|
|
|
+ if (string.Equals(methodName, "Browse", StringComparison.OrdinalIgnoreCase))
|
|
|
+ return HandleBrowse(methodParams, user, deviceId);
|
|
|
|
|
|
- foreach (var i in result)
|
|
|
- {
|
|
|
- var ri = env.CreateElement(i.Key);
|
|
|
- ri.InnerText = i.Value;
|
|
|
- response.AppendChild(ri);
|
|
|
- }
|
|
|
-
|
|
|
- var controlResponse = new ControlResponse
|
|
|
- {
|
|
|
- Xml = env.OuterXml,
|
|
|
- IsSuccessful = true
|
|
|
- };
|
|
|
+ if (string.Equals(methodName, "X_GetFeatureList", StringComparison.OrdinalIgnoreCase))
|
|
|
+ return HandleXGetFeatureList();
|
|
|
|
|
|
- controlResponse.Headers.Add("EXT", string.Empty);
|
|
|
+ if (string.Equals(methodName, "X_SetBookmark", StringComparison.OrdinalIgnoreCase))
|
|
|
+ return HandleXSetBookmark(methodParams, user);
|
|
|
|
|
|
- return controlResponse;
|
|
|
- }
|
|
|
+ if (string.Equals(methodName, "Search", StringComparison.OrdinalIgnoreCase))
|
|
|
+ return HandleSearch(methodParams, user, deviceId);
|
|
|
|
|
|
- private ControlResponse GetErrorResponse(Exception ex)
|
|
|
- {
|
|
|
- var env = new XmlDocument();
|
|
|
- env.AppendChild(env.CreateXmlDeclaration("1.0", "utf-8", "yes"));
|
|
|
- var envelope = env.CreateElement("SOAP-ENV", "Envelope", NS_SOAPENV);
|
|
|
- env.AppendChild(envelope);
|
|
|
- envelope.SetAttribute("encodingStyle", NS_SOAPENV, "http://schemas.xmlsoap.org/soap/encoding/");
|
|
|
-
|
|
|
- var rbody = env.CreateElement("SOAP-ENV:Body", NS_SOAPENV);
|
|
|
- env.DocumentElement.AppendChild(rbody);
|
|
|
-
|
|
|
- var fault = env.CreateElement("SOAP-ENV", "Fault", NS_SOAPENV);
|
|
|
- var faultCode = env.CreateElement("faultcode");
|
|
|
- faultCode.InnerText = "500";
|
|
|
- fault.AppendChild(faultCode);
|
|
|
- var faultString = env.CreateElement("faultstring");
|
|
|
- faultString.InnerText = ex.ToString();
|
|
|
- fault.AppendChild(faultString);
|
|
|
- var detail = env.CreateDocumentFragment();
|
|
|
- detail.InnerXml = "<detail><UPnPError xmlns=\"urn:schemas-upnp-org:control-1-0\"><errorCode>401</errorCode><errorDescription>Invalid Action</errorDescription></UPnPError></detail>";
|
|
|
- fault.AppendChild(detail);
|
|
|
- rbody.AppendChild(fault);
|
|
|
-
|
|
|
- return new ControlResponse
|
|
|
- {
|
|
|
- Xml = env.OuterXml,
|
|
|
- IsSuccessful = false
|
|
|
- };
|
|
|
+ throw new ResourceNotFoundException("Unexpected control request name: " + methodName);
|
|
|
}
|
|
|
|
|
|
private IEnumerable<KeyValuePair<string, string>> HandleXSetBookmark(IDictionary<string, string> sparams, User user)
|
|
@@ -224,7 +116,7 @@ namespace MediaBrowser.Dlna.Server
|
|
|
{
|
|
|
var headers = new Headers(true);
|
|
|
headers.Add("Id", _systemUpdateId.ToString(_usCulture));
|
|
|
- return headers;
|
|
|
+ return headers;
|
|
|
}
|
|
|
|
|
|
private IEnumerable<KeyValuePair<string, string>> HandleXGetFeatureList()
|