mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-11-16 10:29:01 -07:00
Merge pull request #2073 from Bond-009/networkcode
Minor improvements to network code
This commit is contained in:
commit
e44a7ae3f6
@ -7,8 +7,6 @@ using System.Net.NetworkInformation;
|
|||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Model.IO;
|
|
||||||
using MediaBrowser.Model.Net;
|
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.Networking
|
namespace Emby.Server.Implementations.Networking
|
||||||
@ -55,10 +53,7 @@ namespace Emby.Server.Implementations.Networking
|
|||||||
_macAddresses = null;
|
_macAddresses = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NetworkChanged != null)
|
NetworkChanged?.Invoke(this, EventArgs.Empty);
|
||||||
{
|
|
||||||
NetworkChanged(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface = true)
|
public IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface = true)
|
||||||
@ -261,10 +256,10 @@ namespace Emby.Server.Implementations.Networking
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalizedSubnet.IndexOf('/') != -1)
|
if (normalizedSubnet.Contains('/', StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
var ipnetwork = IPNetwork.Parse(normalizedSubnet);
|
var ipNetwork = IPNetwork.Parse(normalizedSubnet);
|
||||||
if (ipnetwork.Contains(address))
|
if (ipNetwork.Contains(address))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -455,9 +450,9 @@ namespace Emby.Server.Implementations.Networking
|
|||||||
|
|
||||||
public bool IsInSameSubnet(IPAddress address1, IPAddress address2, IPAddress subnetMask)
|
public bool IsInSameSubnet(IPAddress address1, IPAddress address2, IPAddress subnetMask)
|
||||||
{
|
{
|
||||||
IPAddress network1 = GetNetworkAddress(address1, subnetMask);
|
IPAddress network1 = GetNetworkAddress(address1, subnetMask);
|
||||||
IPAddress network2 = GetNetworkAddress(address2, subnetMask);
|
IPAddress network2 = GetNetworkAddress(address2, subnetMask);
|
||||||
return network1.Equals(network2);
|
return network1.Equals(network2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IPAddress GetNetworkAddress(IPAddress address, IPAddress subnetMask)
|
private IPAddress GetNetworkAddress(IPAddress address, IPAddress subnetMask)
|
||||||
@ -473,7 +468,7 @@ namespace Emby.Server.Implementations.Networking
|
|||||||
byte[] broadcastAddress = new byte[ipAdressBytes.Length];
|
byte[] broadcastAddress = new byte[ipAdressBytes.Length];
|
||||||
for (int i = 0; i < broadcastAddress.Length; i++)
|
for (int i = 0; i < broadcastAddress.Length; i++)
|
||||||
{
|
{
|
||||||
broadcastAddress[i] = (byte)(ipAdressBytes[i] & (subnetMaskBytes[i]));
|
broadcastAddress[i] = (byte)(ipAdressBytes[i] & subnetMaskBytes[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new IPAddress(broadcastAddress);
|
return new IPAddress(broadcastAddress);
|
||||||
@ -513,24 +508,5 @@ namespace Emby.Server.Implementations.Networking
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the network shares.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">The path.</param>
|
|
||||||
/// <returns>IEnumerable{NetworkShare}.</returns>
|
|
||||||
public virtual IEnumerable<NetworkShare> GetNetworkShares(string path)
|
|
||||||
{
|
|
||||||
return new List<NetworkShare>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets available devices within the domain
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>PC's in the Domain</returns>
|
|
||||||
public virtual IEnumerable<FileSystemEntryInfo> GetNetworkDevices()
|
|
||||||
{
|
|
||||||
return new List<FileSystemEntryInfo>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Net.Mime;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Http.Extensions;
|
using Microsoft.AspNetCore.Http.Extensions;
|
||||||
@ -14,9 +15,9 @@ namespace Emby.Server.Implementations.SocketSharp
|
|||||||
{
|
{
|
||||||
public class WebSocketSharpRequest : IHttpRequest
|
public class WebSocketSharpRequest : IHttpRequest
|
||||||
{
|
{
|
||||||
public const string FormUrlEncoded = "application/x-www-form-urlencoded";
|
private const string FormUrlEncoded = "application/x-www-form-urlencoded";
|
||||||
public const string MultiPartFormData = "multipart/form-data";
|
private const string MultiPartFormData = "multipart/form-data";
|
||||||
public const string Soap11 = "text/xml; charset=utf-8";
|
private const string Soap11 = "text/xml; charset=utf-8";
|
||||||
|
|
||||||
private string _remoteIp;
|
private string _remoteIp;
|
||||||
private Dictionary<string, object> _items;
|
private Dictionary<string, object> _items;
|
||||||
@ -77,7 +78,7 @@ namespace Emby.Server.Implementations.SocketSharp
|
|||||||
get =>
|
get =>
|
||||||
_responseContentType
|
_responseContentType
|
||||||
?? (_responseContentType = GetResponseContentType(Request));
|
?? (_responseContentType = GetResponseContentType(Request));
|
||||||
set => this._responseContentType = value;
|
set => _responseContentType = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string PathInfo => Request.Path.Value;
|
public string PathInfo => Request.Path.Value;
|
||||||
@ -90,7 +91,6 @@ namespace Emby.Server.Implementations.SocketSharp
|
|||||||
|
|
||||||
public bool IsLocal => Request.HttpContext.Connection.LocalIpAddress.Equals(Request.HttpContext.Connection.RemoteIpAddress);
|
public bool IsLocal => Request.HttpContext.Connection.LocalIpAddress.Equals(Request.HttpContext.Connection.RemoteIpAddress);
|
||||||
|
|
||||||
|
|
||||||
public string HttpMethod => Request.Method;
|
public string HttpMethod => Request.Method;
|
||||||
|
|
||||||
public string Verb => HttpMethod;
|
public string Verb => HttpMethod;
|
||||||
@ -123,24 +123,29 @@ namespace Emby.Server.Implementations.SocketSharp
|
|||||||
return specifiedContentType;
|
return specifiedContentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
const string serverDefaultContentType = "application/json";
|
const string ServerDefaultContentType = MediaTypeNames.Application.Json;
|
||||||
|
|
||||||
var acceptContentTypes = httpReq.Headers.GetCommaSeparatedValues(HeaderNames.Accept);
|
var acceptContentTypes = httpReq.Headers.GetCommaSeparatedValues(HeaderNames.Accept);
|
||||||
string defaultContentType = null;
|
string defaultContentType = null;
|
||||||
if (HasAnyOfContentTypes(httpReq, FormUrlEncoded, MultiPartFormData))
|
if (HasAnyOfContentTypes(httpReq, FormUrlEncoded, MultiPartFormData))
|
||||||
{
|
{
|
||||||
defaultContentType = serverDefaultContentType;
|
defaultContentType = ServerDefaultContentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
var acceptsAnything = false;
|
var acceptsAnything = false;
|
||||||
var hasDefaultContentType = defaultContentType != null;
|
var hasDefaultContentType = defaultContentType != null;
|
||||||
if (acceptContentTypes != null)
|
if (acceptContentTypes != null)
|
||||||
{
|
{
|
||||||
foreach (var acceptsType in acceptContentTypes)
|
foreach (ReadOnlySpan<char> acceptsType in acceptContentTypes)
|
||||||
{
|
{
|
||||||
// TODO: @bond move to Span when Span.Split lands
|
ReadOnlySpan<char> contentType = acceptsType;
|
||||||
// https://github.com/dotnet/corefx/issues/26528
|
var index = contentType.IndexOf(';');
|
||||||
var contentType = acceptsType?.Split(';')[0].Trim();
|
if (index != -1)
|
||||||
|
{
|
||||||
|
contentType = contentType.Slice(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
contentType = contentType.Trim();
|
||||||
acceptsAnything = contentType.Equals("*/*", StringComparison.OrdinalIgnoreCase);
|
acceptsAnything = contentType.Equals("*/*", StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
if (acceptsAnything)
|
if (acceptsAnything)
|
||||||
@ -157,7 +162,7 @@ namespace Emby.Server.Implementations.SocketSharp
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return serverDefaultContentType;
|
return ServerDefaultContentType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,7 +173,7 @@ namespace Emby.Server.Implementations.SocketSharp
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We could also send a '406 Not Acceptable', but this is allowed also
|
// We could also send a '406 Not Acceptable', but this is allowed also
|
||||||
return serverDefaultContentType;
|
return ServerDefaultContentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool HasAnyOfContentTypes(HttpRequest request, params string[] contentTypes)
|
public static bool HasAnyOfContentTypes(HttpRequest request, params string[] contentTypes)
|
||||||
@ -196,12 +201,12 @@ namespace Emby.Server.Implementations.SocketSharp
|
|||||||
|
|
||||||
private static string GetQueryStringContentType(HttpRequest httpReq)
|
private static string GetQueryStringContentType(HttpRequest httpReq)
|
||||||
{
|
{
|
||||||
ReadOnlySpan<char> format = httpReq.Query["format"].ToString().AsSpan();
|
ReadOnlySpan<char> format = httpReq.Query["format"].ToString();
|
||||||
if (format == null)
|
if (format == null)
|
||||||
{
|
{
|
||||||
const int formatMaxLength = 4;
|
const int FormatMaxLength = 4;
|
||||||
ReadOnlySpan<char> pi = httpReq.Path.ToString().AsSpan();
|
ReadOnlySpan<char> pi = httpReq.Path.ToString();
|
||||||
if (pi == null || pi.Length <= formatMaxLength)
|
if (pi == null || pi.Length <= FormatMaxLength)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -212,18 +217,18 @@ namespace Emby.Server.Implementations.SocketSharp
|
|||||||
}
|
}
|
||||||
|
|
||||||
format = LeftPart(pi, '/');
|
format = LeftPart(pi, '/');
|
||||||
if (format.Length > formatMaxLength)
|
if (format.Length > FormatMaxLength)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
format = LeftPart(format, '.');
|
format = LeftPart(format, '.');
|
||||||
if (format.Contains("json".AsSpan(), StringComparison.OrdinalIgnoreCase))
|
if (format.Contains("json", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return "application/json";
|
return "application/json";
|
||||||
}
|
}
|
||||||
else if (format.Contains("xml".AsSpan(), StringComparison.OrdinalIgnoreCase))
|
else if (format.Contains("xml", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return "application/xml";
|
return "application/xml";
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,7 @@ namespace MediaBrowser.Api
|
|||||||
public bool? IsFile { get; set; }
|
public bool? IsFile { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete]
|
||||||
[Route("/Environment/NetworkShares", "GET", Summary = "Gets shares from a network device")]
|
[Route("/Environment/NetworkShares", "GET", Summary = "Gets shares from a network device")]
|
||||||
public class GetNetworkShares : IReturn<List<FileSystemEntryInfo>>
|
public class GetNetworkShares : IReturn<List<FileSystemEntryInfo>>
|
||||||
{
|
{
|
||||||
@ -192,22 +193,18 @@ namespace MediaBrowser.Api
|
|||||||
|
|
||||||
var networkPrefix = UncSeparatorString + UncSeparatorString;
|
var networkPrefix = UncSeparatorString + UncSeparatorString;
|
||||||
|
|
||||||
if (path.StartsWith(networkPrefix, StringComparison.OrdinalIgnoreCase) && path.LastIndexOf(UncSeparator) == 1)
|
if (path.StartsWith(networkPrefix, StringComparison.OrdinalIgnoreCase)
|
||||||
|
&& path.LastIndexOf(UncSeparator) == 1)
|
||||||
{
|
{
|
||||||
return ToOptimizedResult(GetNetworkShares(path).OrderBy(i => i.Path).ToList());
|
return ToOptimizedResult(Array.Empty<FileSystemEntryInfo>());
|
||||||
}
|
}
|
||||||
|
|
||||||
return ToOptimizedResult(GetFileSystemEntries(request).ToList());
|
return ToOptimizedResult(GetFileSystemEntries(request).ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete]
|
||||||
public object Get(GetNetworkShares request)
|
public object Get(GetNetworkShares request)
|
||||||
{
|
=> ToOptimizedResult(Array.Empty<FileSystemEntryInfo>());
|
||||||
var path = request.Path;
|
|
||||||
|
|
||||||
var shares = GetNetworkShares(path).OrderBy(i => i.Path).ToList();
|
|
||||||
|
|
||||||
return ToOptimizedResult(shares);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the specified request.
|
/// Gets the specified request.
|
||||||
@ -241,26 +238,7 @@ namespace MediaBrowser.Api
|
|||||||
/// <param name="request">The request.</param>
|
/// <param name="request">The request.</param>
|
||||||
/// <returns>System.Object.</returns>
|
/// <returns>System.Object.</returns>
|
||||||
public object Get(GetNetworkDevices request)
|
public object Get(GetNetworkDevices request)
|
||||||
{
|
=> ToOptimizedResult(Array.Empty<FileSystemEntryInfo>());
|
||||||
var result = _networkManager.GetNetworkDevices().ToList();
|
|
||||||
|
|
||||||
return ToOptimizedResult(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the network shares.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">The path.</param>
|
|
||||||
/// <returns>IEnumerable{FileSystemEntryInfo}.</returns>
|
|
||||||
private IEnumerable<FileSystemEntryInfo> GetNetworkShares(string path)
|
|
||||||
{
|
|
||||||
return _networkManager.GetNetworkShares(path).Where(s => s.ShareType == NetworkShareType.Disk).Select(c => new FileSystemEntryInfo
|
|
||||||
{
|
|
||||||
Name = c.Name,
|
|
||||||
Path = Path.Combine(path, c.Name),
|
|
||||||
Type = FileSystemEntryType.NetworkShare
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the file system entries.
|
/// Gets the file system entries.
|
||||||
|
@ -4,8 +4,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using MediaBrowser.Model.IO;
|
|
||||||
using MediaBrowser.Model.Net;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Common.Net
|
namespace MediaBrowser.Common.Net
|
||||||
{
|
{
|
||||||
@ -36,19 +34,6 @@ namespace MediaBrowser.Common.Net
|
|||||||
/// <returns><c>true</c> if [is in private address space] [the specified endpoint]; otherwise, <c>false</c>.</returns>
|
/// <returns><c>true</c> if [is in private address space] [the specified endpoint]; otherwise, <c>false</c>.</returns>
|
||||||
bool IsInPrivateAddressSpace(string endpoint);
|
bool IsInPrivateAddressSpace(string endpoint);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the network shares.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">The path.</param>
|
|
||||||
/// <returns>IEnumerable{NetworkShare}.</returns>
|
|
||||||
IEnumerable<NetworkShare> GetNetworkShares(string path);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets available devices within the domain
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>PC's in the Domain</returns>
|
|
||||||
IEnumerable<FileSystemEntryInfo> GetNetworkDevices();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether [is in local network] [the specified endpoint].
|
/// Determines whether [is in local network] [the specified endpoint].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
Loading…
Reference in New Issue
Block a user