diff options
Diffstat (limited to 'Emby.Dlna/Api/DlnaServerService.cs')
| -rw-r--r-- | Emby.Dlna/Api/DlnaServerService.cs | 121 |
1 files changed, 93 insertions, 28 deletions
diff --git a/Emby.Dlna/Api/DlnaServerService.cs b/Emby.Dlna/Api/DlnaServerService.cs index 8bf3797f85..a451bbcf91 100644 --- a/Emby.Dlna/Api/DlnaServerService.cs +++ b/Emby.Dlna/Api/DlnaServerService.cs @@ -1,11 +1,10 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text; using System.Threading.Tasks; using Emby.Dlna.Main; using MediaBrowser.Common.Extensions; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Services; @@ -108,12 +107,13 @@ namespace Emby.Dlna.Api public class DlnaServerService : IService, IRequiresRequest { - private readonly IDlnaManager _dlnaManager; - private const string XMLContentType = "text/xml; charset=UTF-8"; + private readonly IDlnaManager _dlnaManager; + private readonly IHttpResultFactory _resultFactory; + private readonly IServerConfigurationManager _configurationManager; + public IRequest Request { get; set; } - private IHttpResultFactory _resultFactory; private IContentDirectory ContentDirectory => DlnaEntryPoint.Current.ContentDirectory; @@ -121,10 +121,14 @@ namespace Emby.Dlna.Api private IMediaReceiverRegistrar MediaReceiverRegistrar => DlnaEntryPoint.Current.MediaReceiverRegistrar; - public DlnaServerService(IDlnaManager dlnaManager, IHttpResultFactory httpResultFactory) + public DlnaServerService( + IDlnaManager dlnaManager, + IHttpResultFactory httpResultFactory, + IServerConfigurationManager configurationManager) { _dlnaManager = dlnaManager; _resultFactory = httpResultFactory; + _configurationManager = configurationManager; } private string GetHeader(string name) @@ -189,7 +193,7 @@ namespace Emby.Dlna.Api private ControlResponse PostAsync(Stream requestStream, IUpnpService service) { - var id = GetPathValue(2); + var id = GetPathValue(2).ToString(); return service.ProcessControlRequest(new ControlRequest { @@ -200,38 +204,99 @@ namespace Emby.Dlna.Api }); } - protected string GetPathValue(int index) + // Copied from MediaBrowser.Api/BaseApiService.cs + // TODO: Remove code duplication + /// <summary> + /// Gets the path segment at the specified index. + /// </summary> + /// <param name="index">The index of the path segment.</param> + /// <returns>The path segment at the specified index.</returns> + /// <exception cref="IndexOutOfRangeException" >Path doesn't contain enough segments.</exception> + /// <exception cref="InvalidDataException" >Path doesn't start with the base url.</exception> + protected internal ReadOnlySpan<char> GetPathValue(int index) { - var pathInfo = Parse(Request.PathInfo); - var first = pathInfo[0]; - - // backwards compatibility - // TODO: Work out what this is doing. - if (string.Equals(first, "mediabrowser", StringComparison.OrdinalIgnoreCase) || - string.Equals(first, "emby", StringComparison.OrdinalIgnoreCase) || - string.Equals(first, "jellyfin", StringComparison.OrdinalIgnoreCase)) + static void ThrowIndexOutOfRangeException() + => throw new IndexOutOfRangeException("Path doesn't contain enough segments."); + + static void ThrowInvalidDataException() + => throw new InvalidDataException("Path doesn't start with the base url."); + + ReadOnlySpan<char> path = Request.PathInfo; + + // Remove the protocol part from the url + int pos = path.LastIndexOf("://"); + if (pos != -1) { - index++; + path = path.Slice(pos + 3); } - return pathInfo[index]; - } + // Remove the query string + pos = path.LastIndexOf('?'); + if (pos != -1) + { + path = path.Slice(0, pos); + } - private List<string> Parse(string pathUri) - { - var actionParts = pathUri.Split(new[] { "://" }, StringSplitOptions.None); + // Remove the domain + pos = path.IndexOf('/'); + if (pos != -1) + { + path = path.Slice(pos); + } - var pathInfo = actionParts[actionParts.Length - 1]; + // Remove base url + string baseUrl = _configurationManager.Configuration.BaseUrl; + int baseUrlLen = baseUrl.Length; + if (baseUrlLen != 0) + { + if (path.StartsWith(baseUrl, StringComparison.OrdinalIgnoreCase)) + { + path = path.Slice(baseUrlLen); + } + else + { + // The path doesn't start with the base url, + // how did we get here? + ThrowInvalidDataException(); + } + } + + // Remove leading / + path = path.Slice(1); - var optionsPos = pathInfo.LastIndexOf('?'); - if (optionsPos != -1) + // Backwards compatibility + const string Emby = "emby/"; + if (path.StartsWith(Emby, StringComparison.OrdinalIgnoreCase)) { - pathInfo = pathInfo.Substring(0, optionsPos); + path = path.Slice(Emby.Length); } - var args = pathInfo.Split('/'); + const string MediaBrowser = "mediabrowser/"; + if (path.StartsWith(MediaBrowser, StringComparison.OrdinalIgnoreCase)) + { + path = path.Slice(MediaBrowser.Length); + } + + // Skip segments until we are at the right index + for (int i = 0; i < index; i++) + { + pos = path.IndexOf('/'); + if (pos == -1) + { + ThrowIndexOutOfRangeException(); + } + + path = path.Slice(pos + 1); + } + + // Remove the rest + pos = path.IndexOf('/'); + if (pos != -1) + { + path = path.Slice(0, pos); + } - return args.Skip(1).ToList(); + return path; } public object Get(GetIcon request) |
