Merge pull request #2073 from Bond-009/networkcode

Minor improvements to network code
This commit is contained in:
Vasily 2019-12-04 20:03:10 +03:00 committed by GitHub
commit e44a7ae3f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 96 deletions

View File

@ -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>();
}
} }
} }

View File

@ -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";
} }

View File

@ -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.

View File

@ -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>