123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- using MediaBrowser.Controller.Configuration;
- using MediaBrowser.Controller.Dlna;
- using Emby.Dlna.Server;
- using MediaBrowser.Model.Logging;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Xml;
- using Emby.Dlna.Didl;
- using MediaBrowser.Model.Xml;
- namespace Emby.Dlna.Service
- {
- public abstract class BaseControlHandler
- {
- private const string NS_SOAPENV = "http://schemas.xmlsoap.org/soap/envelope/";
-
- protected readonly IServerConfigurationManager Config;
- protected readonly ILogger Logger;
- protected readonly IXmlReaderSettingsFactory XmlReaderSettingsFactory;
- protected BaseControlHandler(IServerConfigurationManager config, ILogger logger, IXmlReaderSettingsFactory xmlReaderSettingsFactory)
- {
- Config = config;
- Logger = logger;
- XmlReaderSettingsFactory = xmlReaderSettingsFactory;
- }
- public ControlResponse ProcessControlRequest(ControlRequest request)
- {
- try
- {
- var enableDebugLogging = Config.GetDlnaConfiguration().EnableDebugLog;
- if (enableDebugLogging)
- {
- LogRequest(request);
- }
- var response = ProcessControlRequestInternal(request);
- if (enableDebugLogging)
- {
- LogResponse(response);
- }
- return response;
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error processing control request", ex);
- return new ControlErrorHandler().GetResponse(ex);
- }
- }
- private ControlResponse ProcessControlRequestInternal(ControlRequest request)
- {
- ControlRequestInfo requestInfo = null;
- using (var streamReader = new StreamReader(request.InputXml))
- {
- var readerSettings = XmlReaderSettingsFactory.Create(false);
- readerSettings.CheckCharacters = false;
- readerSettings.IgnoreProcessingInstructions = true;
- readerSettings.IgnoreComments = true;
- using (var reader = XmlReader.Create(streamReader, readerSettings))
- {
- requestInfo = ParseRequest(reader);
- }
- }
- Logger.Debug("Received control request {0}", requestInfo.LocalName);
- var result = GetResult(requestInfo.LocalName, requestInfo.Headers);
- var settings = new XmlWriterSettings
- {
- Encoding = Encoding.UTF8,
- CloseOutput = false
- };
- StringWriter builder = new StringWriterWithEncoding(Encoding.UTF8);
- using (XmlWriter writer = XmlWriter.Create(builder, settings))
- {
- writer.WriteStartDocument(true);
- writer.WriteStartElement("SOAP-ENV", "Envelope", NS_SOAPENV);
- writer.WriteAttributeString(string.Empty, "encodingStyle", NS_SOAPENV, "http://schemas.xmlsoap.org/soap/encoding/");
- writer.WriteStartElement("SOAP-ENV", "Body", NS_SOAPENV);
- writer.WriteStartElement("u", requestInfo.LocalName + "Response", requestInfo.NamespaceURI);
- foreach (var i in result)
- {
- writer.WriteStartElement(i.Key);
- writer.WriteString(i.Value);
- writer.WriteEndElement();
- }
- writer.WriteEndElement();
- writer.WriteEndElement();
- writer.WriteEndElement();
- writer.WriteEndDocument();
- }
- var xml = builder.ToString().Replace("xmlns:m=", "xmlns:u=");
-
- var controlResponse = new ControlResponse
- {
- Xml = xml,
- IsSuccessful = true
- };
- //Logger.Debug(xml);
- controlResponse.Headers.Add("EXT", string.Empty);
- return controlResponse;
- }
- private ControlRequestInfo ParseRequest(XmlReader reader)
- {
- reader.MoveToContent();
- reader.Read();
- // Loop through each element
- while (!reader.EOF)
- {
- if (reader.NodeType == XmlNodeType.Element)
- {
- switch (reader.LocalName)
- {
- case "Body":
- {
- using (var subReader = reader.ReadSubtree())
- {
- return ParseBodyTag(subReader);
- }
- }
- default:
- {
- reader.Skip();
- break;
- }
- }
- }
- else
- {
- reader.Read();
- }
- }
- return new ControlRequestInfo();
- }
- private ControlRequestInfo ParseBodyTag(XmlReader reader)
- {
- var result = new ControlRequestInfo();
- reader.MoveToContent();
- reader.Read();
- // Loop through each element
- while (!reader.EOF)
- {
- if (reader.NodeType == XmlNodeType.Element)
- {
- result.LocalName = reader.LocalName;
- result.NamespaceURI = reader.NamespaceURI;
- using (var subReader = reader.ReadSubtree())
- {
- result.Headers = ParseFirstBodyChild(subReader);
- return result;
- }
- }
- else
- {
- reader.Read();
- }
- }
- return result;
- }
- private Headers ParseFirstBodyChild(XmlReader reader)
- {
- var result = new Headers();
- reader.MoveToContent();
- reader.Read();
- // Loop through each element
- while (!reader.EOF)
- {
- if (reader.NodeType == XmlNodeType.Element)
- {
- result.Add(reader.LocalName, reader.ReadElementContentAsString());
- }
- else
- {
- reader.Read();
- }
- }
- return result;
- }
- private class ControlRequestInfo
- {
- public string LocalName;
- public string NamespaceURI;
- public Headers Headers = new Headers();
- }
- protected abstract IEnumerable<KeyValuePair<string, string>> GetResult(string methodName, Headers methodParams);
- 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 void LogResponse(ControlResponse response)
- {
- var builder = new StringBuilder();
- var headers = string.Join(", ", response.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray());
- builder.AppendFormat("Headers: {0}", headers);
- builder.AppendLine();
- builder.Append(response.Xml);
- Logger.LogMultiline("Control response", LogSeverity.Debug, builder);
- }
- }
- }
|