mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-12-18 06:53:07 +03:00
* Add support for multi segment base urls
* Make baseurl case-insensitive
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
@@ -16,19 +18,35 @@ namespace MediaBrowser.Api
|
||||
/// <summary>
|
||||
/// Class BaseApiService
|
||||
/// </summary>
|
||||
public class BaseApiService : IService, IRequiresRequest
|
||||
public abstract class BaseApiService : IService, IRequiresRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the logger.
|
||||
/// </summary>
|
||||
/// <value>The logger.</value>
|
||||
public ILogger Logger => ApiEntryPoint.Instance.Logger;
|
||||
public BaseApiService(
|
||||
ILogger logger,
|
||||
IServerConfigurationManager serverConfigurationManager,
|
||||
IHttpResultFactory httpResultFactory)
|
||||
{
|
||||
Logger = logger;
|
||||
ServerConfigurationManager = serverConfigurationManager;
|
||||
ResultFactory = httpResultFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the HTTP result factory.
|
||||
/// Gets the logger.
|
||||
/// </summary>
|
||||
/// <value>The logger.</value>
|
||||
protected ILogger Logger { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the server configuration manager.
|
||||
/// </summary>
|
||||
/// <value>The server configuration manager.</value>
|
||||
protected IServerConfigurationManager ServerConfigurationManager { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the HTTP result factory.
|
||||
/// </summary>
|
||||
/// <value>The HTTP result factory.</value>
|
||||
public IHttpResultFactory ResultFactory => ApiEntryPoint.Instance.ResultFactory;
|
||||
protected IHttpResultFactory ResultFactory { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the request context.
|
||||
@@ -36,10 +54,7 @@ namespace MediaBrowser.Api
|
||||
/// <value>The request context.</value>
|
||||
public IRequest Request { get; set; }
|
||||
|
||||
public string GetHeader(string name)
|
||||
{
|
||||
return Request.Headers[name];
|
||||
}
|
||||
public string GetHeader(string name) => Request.Headers[name];
|
||||
|
||||
public static string[] SplitValue(string value, char delim)
|
||||
{
|
||||
@@ -292,51 +307,101 @@ namespace MediaBrowser.Api
|
||||
return result;
|
||||
}
|
||||
|
||||
protected string GetPathValue(int index)
|
||||
/// <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];
|
||||
|
||||
string baseUrl = ApiEntryPoint.Instance.ConfigurationManager.Configuration.BaseUrl;
|
||||
|
||||
// backwards compatibility
|
||||
if (baseUrl.Length == 0)
|
||||
static void ThrowIndexOutOfRangeException()
|
||||
{
|
||||
if (string.Equals(first, "mediabrowser", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(first, "emby", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
index++;
|
||||
}
|
||||
throw new IndexOutOfRangeException("Path doesn't contain enough segments.");
|
||||
}
|
||||
else if (string.Equals(first, baseUrl.Remove(0, 1)))
|
||||
|
||||
static void ThrowInvalidDataException()
|
||||
{
|
||||
index++;
|
||||
var second = pathInfo[1];
|
||||
if (string.Equals(second, "mediabrowser", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(second, "emby", StringComparison.OrdinalIgnoreCase))
|
||||
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)
|
||||
{
|
||||
path = path.Slice(pos + 3);
|
||||
}
|
||||
|
||||
// Remove the query string
|
||||
pos = path.LastIndexOf('?');
|
||||
if (pos != -1)
|
||||
{
|
||||
path = path.Slice(0, pos);
|
||||
}
|
||||
|
||||
// Remove the domain
|
||||
pos = path.IndexOf('/');
|
||||
if (pos != -1)
|
||||
{
|
||||
path = path.Slice(pos);
|
||||
}
|
||||
|
||||
// Remove base url
|
||||
string baseUrl = ServerConfigurationManager.Configuration.BaseUrl;
|
||||
int baseUrlLen = baseUrl.Length;
|
||||
if (baseUrlLen != 0)
|
||||
{
|
||||
if (path.StartsWith(baseUrl, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
index++;
|
||||
path = path.Slice(baseUrlLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The path doesn't start with the base url,
|
||||
// how did we get here?
|
||||
ThrowInvalidDataException();
|
||||
}
|
||||
}
|
||||
|
||||
return pathInfo[index];
|
||||
}
|
||||
// Remove leading /
|
||||
path = path.Slice(1);
|
||||
|
||||
private static string[] Parse(string pathUri)
|
||||
{
|
||||
var actionParts = pathUri.Split(new[] { "://" }, StringSplitOptions.None);
|
||||
|
||||
var pathInfo = actionParts[actionParts.Length - 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);
|
||||
}
|
||||
|
||||
return args.Skip(1).ToArray();
|
||||
// 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 path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user