|
|
@ -1,7 +1,6 @@
|
|
|
|
using System;
|
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Diagnostics;
|
|
|
|
using System.Diagnostics;
|
|
|
|
using System.Globalization;
|
|
|
|
|
|
|
|
using System.IO;
|
|
|
|
using System.IO;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Net.Sockets;
|
|
|
|
using System.Net.Sockets;
|
|
|
@ -11,7 +10,6 @@ using System.Threading;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using Emby.Server.Implementations.Net;
|
|
|
|
using Emby.Server.Implementations.Net;
|
|
|
|
using Emby.Server.Implementations.Services;
|
|
|
|
using Emby.Server.Implementations.Services;
|
|
|
|
using Emby.Server.Implementations.SocketSharp;
|
|
|
|
|
|
|
|
using MediaBrowser.Common.Extensions;
|
|
|
|
using MediaBrowser.Common.Extensions;
|
|
|
|
using MediaBrowser.Common.Net;
|
|
|
|
using MediaBrowser.Common.Net;
|
|
|
|
using MediaBrowser.Controller;
|
|
|
|
using MediaBrowser.Controller;
|
|
|
@ -127,12 +125,12 @@ namespace Emby.Server.Implementations.HttpServer
|
|
|
|
|
|
|
|
|
|
|
|
private List<IHasRequestFilter> GetRequestFilterAttributes(Type requestDtoType)
|
|
|
|
private List<IHasRequestFilter> GetRequestFilterAttributes(Type requestDtoType)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var attributes = requestDtoType.GetTypeInfo().GetCustomAttributes(true).OfType<IHasRequestFilter>().ToList();
|
|
|
|
var attributes = requestDtoType.GetCustomAttributes(true).OfType<IHasRequestFilter>().ToList();
|
|
|
|
|
|
|
|
|
|
|
|
var serviceType = GetServiceTypeByRequest(requestDtoType);
|
|
|
|
var serviceType = GetServiceTypeByRequest(requestDtoType);
|
|
|
|
if (serviceType != null)
|
|
|
|
if (serviceType != null)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
attributes.AddRange(serviceType.GetTypeInfo().GetCustomAttributes(true).OfType<IHasRequestFilter>());
|
|
|
|
attributes.AddRange(serviceType.GetCustomAttributes(true).OfType<IHasRequestFilter>());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
attributes.Sort((x, y) => x.Priority - y.Priority);
|
|
|
|
attributes.Sort((x, y) => x.Priority - y.Priority);
|
|
|
@ -154,7 +152,7 @@ namespace Emby.Server.Implementations.HttpServer
|
|
|
|
QueryString = e.QueryString ?? new QueryCollection()
|
|
|
|
QueryString = e.QueryString ?? new QueryCollection()
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
connection.Closed += Connection_Closed;
|
|
|
|
connection.Closed += OnConnectionClosed;
|
|
|
|
|
|
|
|
|
|
|
|
lock (_webSocketConnections)
|
|
|
|
lock (_webSocketConnections)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -164,7 +162,7 @@ namespace Emby.Server.Implementations.HttpServer
|
|
|
|
WebSocketConnected?.Invoke(this, new GenericEventArgs<IWebSocketConnection>(connection));
|
|
|
|
WebSocketConnected?.Invoke(this, new GenericEventArgs<IWebSocketConnection>(connection));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void Connection_Closed(object sender, EventArgs e)
|
|
|
|
private void OnConnectionClosed(object sender, EventArgs e)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
lock (_webSocketConnections)
|
|
|
|
lock (_webSocketConnections)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -322,14 +320,14 @@ namespace Emby.Server.Implementations.HttpServer
|
|
|
|
|
|
|
|
|
|
|
|
private static string NormalizeConfiguredLocalAddress(string address)
|
|
|
|
private static string NormalizeConfiguredLocalAddress(string address)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var index = address.Trim('/').IndexOf('/');
|
|
|
|
var add = address.AsSpan().Trim('/');
|
|
|
|
|
|
|
|
int index = add.IndexOf('/');
|
|
|
|
if (index != -1)
|
|
|
|
if (index != -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
address = address.Substring(index + 1);
|
|
|
|
add = add.Slice(index + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return address.Trim('/');
|
|
|
|
return add.TrimStart('/').ToString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool ValidateHost(string host)
|
|
|
|
private bool ValidateHost(string host)
|
|
|
@ -399,8 +397,8 @@ namespace Emby.Server.Implementations.HttpServer
|
|
|
|
if (urlString.IndexOf("https://", StringComparison.OrdinalIgnoreCase) == -1)
|
|
|
|
if (urlString.IndexOf("https://", StringComparison.OrdinalIgnoreCase) == -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// These are hacks, but if these ever occur on ipv6 in the local network they could be incorrectly redirected
|
|
|
|
// These are hacks, but if these ever occur on ipv6 in the local network they could be incorrectly redirected
|
|
|
|
if (urlString.IndexOf("system/ping", StringComparison.OrdinalIgnoreCase) != -1 ||
|
|
|
|
if (urlString.IndexOf("system/ping", StringComparison.OrdinalIgnoreCase) != -1
|
|
|
|
urlString.IndexOf("dlna/", StringComparison.OrdinalIgnoreCase) != -1)
|
|
|
|
|| urlString.IndexOf("dlna/", StringComparison.OrdinalIgnoreCase) != -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -572,7 +570,7 @@ namespace Emby.Server.Implementations.HttpServer
|
|
|
|
|
|
|
|
|
|
|
|
if (handler != null)
|
|
|
|
if (handler != null)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
await handler.ProcessRequestAsync(this, httpReq, httpRes, Logger, httpReq.OperationName, cancellationToken).ConfigureAwait(false);
|
|
|
|
await handler.ProcessRequestAsync(this, httpReq, httpRes, Logger, cancellationToken).ConfigureAwait(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -613,21 +611,11 @@ namespace Emby.Server.Implementations.HttpServer
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var pathInfo = httpReq.PathInfo;
|
|
|
|
var pathInfo = httpReq.PathInfo;
|
|
|
|
|
|
|
|
|
|
|
|
var pathParts = pathInfo.TrimStart('/').Split('/');
|
|
|
|
pathInfo = ServiceHandler.GetSanitizedPathInfo(pathInfo, out string contentType);
|
|
|
|
if (pathParts.Length == 0)
|
|
|
|
var restPath = ServiceController.GetRestPathForRequest(httpReq.HttpMethod, pathInfo);
|
|
|
|
{
|
|
|
|
|
|
|
|
Logger.LogError("Path parts empty for PathInfo: {PathInfo}, Url: {RawUrl}", pathInfo, httpReq.RawUrl);
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var restPath = ServiceHandler.FindMatchingRestPath(httpReq.HttpMethod, pathInfo, out string contentType);
|
|
|
|
|
|
|
|
if (restPath != null)
|
|
|
|
if (restPath != null)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return new ServiceHandler
|
|
|
|
return new ServiceHandler(restPath, contentType);
|
|
|
|
{
|
|
|
|
|
|
|
|
RestPath = restPath,
|
|
|
|
|
|
|
|
ResponseContentType = contentType
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Logger.LogError("Could not find handler for {PathInfo}", pathInfo);
|
|
|
|
Logger.LogError("Could not find handler for {PathInfo}", pathInfo);
|
|
|
@ -655,11 +643,6 @@ namespace Emby.Server.Implementations.HttpServer
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// TODO what is this?
|
|
|
|
|
|
|
|
var httpsUrl = url
|
|
|
|
|
|
|
|
.Replace("http://", "https://", StringComparison.OrdinalIgnoreCase)
|
|
|
|
|
|
|
|
.Replace(":" + _config.Configuration.PublicPort.ToString(CultureInfo.InvariantCulture), ":" + _config.Configuration.PublicHttpsPort.ToString(CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RedirectToUrl(httpRes, url);
|
|
|
|
RedirectToUrl(httpRes, url);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -684,10 +667,7 @@ namespace Emby.Server.Implementations.HttpServer
|
|
|
|
UrlPrefixes = urlPrefixes.ToArray();
|
|
|
|
UrlPrefixes = urlPrefixes.ToArray();
|
|
|
|
ServiceController = new ServiceController();
|
|
|
|
ServiceController = new ServiceController();
|
|
|
|
|
|
|
|
|
|
|
|
Logger.LogInformation("Calling ServiceStack AppHost.Init");
|
|
|
|
var types = services.Select(r => r.GetType());
|
|
|
|
|
|
|
|
|
|
|
|
var types = services.Select(r => r.GetType()).ToArray();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ServiceController.Init(this, types);
|
|
|
|
ServiceController.Init(this, types);
|
|
|
|
|
|
|
|
|
|
|
|
ResponseFilters = new Action<IRequest, IResponse, object>[]
|
|
|
|
ResponseFilters = new Action<IRequest, IResponse, object>[]
|
|
|
|