From 2aaecb8e148aef6cda67797fa4227a8ebcf7e5bb Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Tue, 28 Apr 2020 21:45:46 +0100 Subject: Whilst fixing issues with SSDP on devices with multiple interfaces, i came across a design issue in the current code - namely interfaces without a gateway were ignored. Fixing this required the removal of the code that attempted to detect virtual interfaces. Not wanting to remove functionality, but not able to keep the code in place, I implemented a work around solution (see 4 below). Whilst in the area, I also fixed a few minor bugs i encountered (1, 5, 6 below) and stopped SSDP messages from going out on non-LAN interfaces (3) All these changes are related. Changes 1 IsInPrivateAddressSpace - improved subnet code checking 2 interfaces with no gateway were being excluded from SSDP blasts 3 filtered SSDP blasts from not LAN addresses as defined on the network page. 4 removed #986 mod - as this was part of the issue of #2986. Interfaces can be excluded from the LAN by putting the LAN address in brackets. eg. [10.1.1.1] will exclude an interface with ip address 10.1.1.1 from SSDP 5 fixed a problem where an invalid LAN address causing the SSDP to crash 6 corrected local link filter (FilterIPAddress) to filter on 169.254. addresses --- MediaBrowser.Common/Net/INetworkManager.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Common/Net') diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index 3ba75abd8..b7ec1d122 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -41,10 +41,12 @@ namespace MediaBrowser.Common.Net /// true if [is in local network] [the specified endpoint]; otherwise, false. bool IsInLocalNetwork(string endpoint); - IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface); + IPAddress[] GetLocalIpAddresses(); bool IsAddressInSubnets(string addressString, string[] subnets); + bool IsAddressInSubnets(IPAddress address, bool excludeInterfaces, bool excludeRFC); + bool IsInSameSubnet(IPAddress address1, IPAddress address2, IPAddress subnetMask); IPAddress GetLocalIpSubnetMask(IPAddress address); -- cgit v1.2.3 From a3140f83c6461164658303d1bb7c1d992cfd9802 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Tue, 28 Apr 2020 21:51:49 +0100 Subject: Revert "Whilst fixing issues with SSDP on devices with multiple interfaces, i came across a design issue in the current code - namely interfaces without a gateway were ignored." This reverts commit 2aaecb8e148aef6cda67797fa4227a8ebcf7e5bb. --- Emby.Dlna/Main/DlnaEntryPoint.cs | 6 - Emby.Server.Implementations/ApplicationHost.cs | 2 +- .../Networking/NetworkManager.cs | 149 +++++++++------------ MediaBrowser.Common/Net/INetworkManager.cs | 4 +- RSSDP/SsdpCommunicationsServer.cs | 4 +- RSSDP/SsdpDeviceLocator.cs | 2 +- 6 files changed, 70 insertions(+), 97 deletions(-) (limited to 'MediaBrowser.Common/Net') diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index 721350483..c5d60b2a0 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -266,12 +266,6 @@ namespace Emby.Dlna.Main continue; } - // Limit to LAN addresses only - if (!_networkManager.IsAddressInSubnets(address, true, true)) - { - continue; - } - var fullService = "urn:schemas-upnp-org:device:MediaServer:1"; _logger.LogInformation("Registering publisher for {0} on {1}", fullService, address); diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 97fc2c004..33aec1a06 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1274,7 +1274,7 @@ namespace Emby.Server.Implementations if (addresses.Count == 0) { - addresses.AddRange(_networkManager.GetLocalIpAddresses()); + addresses.AddRange(_networkManager.GetLocalIpAddresses(ServerConfigurationManager.Configuration.IgnoreVirtualInterfaces)); } var resultList = new List(); diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index 465530888..b3e88b667 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -56,13 +56,13 @@ namespace Emby.Server.Implementations.Networking NetworkChanged?.Invoke(this, EventArgs.Empty); } - public IPAddress[] GetLocalIpAddresses() + public IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface = true) { lock (_localIpAddressSyncLock) { if (_localIpAddresses == null) { - var addresses = GetLocalIpAddressesInternal().ToArray(); + var addresses = GetLocalIpAddressesInternal(ignoreVirtualInterface).ToArray(); _localIpAddresses = addresses; } @@ -71,45 +71,42 @@ namespace Emby.Server.Implementations.Networking } } - private List GetLocalIpAddressesInternal() + private List GetLocalIpAddressesInternal(bool ignoreVirtualInterface) { - var list = GetIPsDefault().ToList(); + var list = GetIPsDefault(ignoreVirtualInterface).ToList(); if (list.Count == 0) { list = GetLocalIpAddressesFallback().GetAwaiter().GetResult().ToList(); } - var listClone = new List(); + var listClone = list.ToList(); - var subnets = LocalSubnetsFn(); - - foreach (var i in list) - { - if (i.IsIPv6LinkLocal || i.ToString().StartsWith("169.254.", StringComparison.OrdinalIgnoreCase)) - { - continue; - } - if (Array.IndexOf(subnets, "[" + i.ToString() + "]") == -1) - { - listClone.Add(i); - } - } - - return listClone + return list .OrderBy(i => i.AddressFamily == AddressFamily.InterNetwork ? 0 : 1) - // .ThenBy(i => listClone.IndexOf(i)) + .ThenBy(i => listClone.IndexOf(i)) + .Where(FilterIpAddress) .GroupBy(i => i.ToString()) .Select(x => x.First()) .ToList(); } + private static bool FilterIpAddress(IPAddress address) + { + if (address.IsIPv6LinkLocal + || address.ToString().StartsWith("169.", StringComparison.OrdinalIgnoreCase)) + { + return false; + } + + return true; + } + public bool IsInPrivateAddressSpace(string endpoint) { return IsInPrivateAddressSpace(endpoint, true); } - // checks if the address in endpoint is an RFC1918, RFC1122, or RFC3927 address private bool IsInPrivateAddressSpace(string endpoint, bool checkSubnets) { if (string.Equals(endpoint, "::1", StringComparison.OrdinalIgnoreCase)) @@ -131,28 +128,23 @@ namespace Emby.Server.Implementations.Networking } // Private address space: + // http://en.wikipedia.org/wiki/Private_network - if (endpoint.ToLower() == "localhost") + if (endpoint.StartsWith("172.", StringComparison.OrdinalIgnoreCase)) { - return true; + return Is172AddressPrivate(endpoint); } - try + if (endpoint.StartsWith("localhost", StringComparison.OrdinalIgnoreCase) || + endpoint.StartsWith("127.", StringComparison.OrdinalIgnoreCase) || + endpoint.StartsWith("169.", StringComparison.OrdinalIgnoreCase)) { - byte[] octet = IPAddress.Parse(endpoint).GetAddressBytes(); - - if ((octet[0] == 10) || - (octet[0] == 172 && (octet[1] >= 16 && octet[1] <= 31)) || // RFC1918 - (octet[0] == 192 && octet[1] == 168) || // RFC1918 - (octet[0] == 127) || // RFC1122 - (octet[0] == 169 && octet[1] == 254)) // RFC3927 - { - return false; - } + return true; } - catch + + if (checkSubnets && endpoint.StartsWith("192.168", StringComparison.OrdinalIgnoreCase)) { - // return false; + return true; } if (checkSubnets && IsInPrivateAddressSpaceAndLocalSubnet(endpoint)) @@ -185,7 +177,6 @@ namespace Emby.Server.Implementations.Networking return false; } - // Gives a list of possible subnets from the system whose interface ip starts with endpointFirstPart private List GetSubnets(string endpointFirstPart) { lock (_subnetLookupLock) @@ -231,6 +222,19 @@ namespace Emby.Server.Implementations.Networking } } + private static bool Is172AddressPrivate(string endpoint) + { + for (var i = 16; i <= 31; i++) + { + if (endpoint.StartsWith("172." + i.ToString(CultureInfo.InvariantCulture) + ".", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + + return false; + } + public bool IsInLocalNetwork(string endpoint) { return IsInLocalNetworkInternal(endpoint, true); @@ -241,57 +245,23 @@ namespace Emby.Server.Implementations.Networking return IsAddressInSubnets(IPAddress.Parse(addressString), addressString, subnets); } - // returns true if address is in the LAN list in the config file - // always returns false if address has been excluded from the LAN if excludeInterfaces is true - // and excludes RFC addresses if excludeRFC is true - public bool IsAddressInSubnets(IPAddress address, bool excludeInterfaces, bool excludeRFC) - { - byte[] octet = address.GetAddressBytes(); - - if ((octet[0] == 127) || // RFC1122 - (octet[0] == 169 && octet[1] == 254)) // RFC3927 - { - // don't use on loopback or 169 interfaces - return false; - } - - string addressString = address.ToString(); - string excludeAddress = "[" + addressString + "]"; - var subnets = LocalSubnetsFn(); - - // Exclude any addresses if they appear in the LAN list in [ ] - if (Array.IndexOf(subnets, excludeAddress) != -1) - { - return false; - } - return IsAddressInSubnets(address, addressString, subnets); - } - - // Checks to see if address/addressString (same but different type) falls within subnets[] private static bool IsAddressInSubnets(IPAddress address, string addressString, string[] subnets) { foreach (var subnet in subnets) { var normalizedSubnet = subnet.Trim(); - // is the subnet a host address and does it match the address being passes? + if (string.Equals(normalizedSubnet, addressString, StringComparison.OrdinalIgnoreCase)) { return true; } - // parse CIDR subnets and see if address falls within it. + if (normalizedSubnet.Contains('/', StringComparison.Ordinal)) { - try - { - var ipNetwork = IPNetwork.Parse(normalizedSubnet); - if (ipNetwork.Contains(address)) - { - return true; - } - } - catch + var ipNetwork = IPNetwork.Parse(normalizedSubnet); + if (ipNetwork.Contains(address)) { - // Ignoring - invalid subnet passed encountered. + return true; } } } @@ -389,8 +359,8 @@ namespace Emby.Server.Implementations.Networking { return Dns.GetHostAddressesAsync(hostName); } - - private IEnumerable GetIPsDefault() + + private IEnumerable GetIPsDefault(bool ignoreVirtualInterface) { IEnumerable interfaces; @@ -410,7 +380,15 @@ namespace Emby.Server.Implementations.Networking { var ipProperties = network.GetIPProperties(); - // Exclude any addresses if they appear in the LAN list in [ ] + // Try to exclude virtual adapters + // http://stackoverflow.com/questions/8089685/c-sharp-finding-my-machines-local-ip-address-and-not-the-vms + var addr = ipProperties.GatewayAddresses.FirstOrDefault(); + if (addr == null + || (ignoreVirtualInterface + && (addr.Address.Equals(IPAddress.Any) || addr.Address.Equals(IPAddress.IPv6Any)))) + { + return Enumerable.Empty(); + } return ipProperties.UnicastAddresses .Select(i => i.Address) @@ -516,12 +494,15 @@ namespace Emby.Server.Implementations.Networking foreach (NetworkInterface ni in interfaces) { - foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) + if (ni.GetIPProperties().GatewayAddresses.FirstOrDefault() != null) { - if (ip.Address.Equals(address) && ip.IPv4Mask != null) + foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) { - return ip.IPv4Mask; - } + if (ip.Address.Equals(address) && ip.IPv4Mask != null) + { + return ip.IPv4Mask; + } + } } } diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index b7ec1d122..3ba75abd8 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -41,12 +41,10 @@ namespace MediaBrowser.Common.Net /// true if [is in local network] [the specified endpoint]; otherwise, false. bool IsInLocalNetwork(string endpoint); - IPAddress[] GetLocalIpAddresses(); + IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface); bool IsAddressInSubnets(string addressString, string[] subnets); - bool IsAddressInSubnets(IPAddress address, bool excludeInterfaces, bool excludeRFC); - bool IsInSameSubnet(IPAddress address1, IPAddress address2, IPAddress subnetMask); IPAddress GetLocalIpSubnetMask(IPAddress address); diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 47da52005..18097ef24 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -370,13 +370,13 @@ namespace Rssdp.Infrastructure if (_enableMultiSocketBinding) { - foreach (var address in _networkManager.GetLocalIpAddresses()) + foreach (var address in _networkManager.GetLocalIpAddresses(_config.Configuration.IgnoreVirtualInterfaces)) { if (address.AddressFamily == AddressFamily.InterNetworkV6) { // Not support IPv6 right now continue; - } + } try { diff --git a/RSSDP/SsdpDeviceLocator.cs b/RSSDP/SsdpDeviceLocator.cs index b62c50e28..59a2710d5 100644 --- a/RSSDP/SsdpDeviceLocator.cs +++ b/RSSDP/SsdpDeviceLocator.cs @@ -357,7 +357,7 @@ namespace Rssdp.Infrastructure private void ProcessSearchResponseMessage(HttpResponseMessage message, IPAddress localIpAddress) { if (!message.IsSuccessStatusCode) return; - + var location = GetFirstHeaderUriValue("Location", message); if (location != null) { -- cgit v1.2.3 From ebd589aa86abb7bdbc9ab981cb8f4c908f790ac1 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Tue, 28 Apr 2020 21:57:39 +0100 Subject: Whilst fixing issues with SSDP on devices with multiple interfaces, i came across a design issue in the current code - namely interfaces without a gateway were ignored. Fixing this required the removal of the code that attempted to detect virtual interfaces. Not wanting to remove functionality, but not able to keep the code in place, I implemented a work around solution (see 4 below). Whilst in the area, I also fixed a few minor bugs i encountered (1, 5, 6 below) and stopped SSDP messages from going out on non-LAN interfaces (3) All these changes are related. Changes 1 IsInPrivateAddressSpace - improved subnet code checking 2 interfaces with no gateway were being excluded from SSDP blasts 3 filtered SSDP blasts from not LAN addresses as defined on the network page. 4 removed #986 mod - as this was part of the issue of #2986. Interfaces can be excluded from the LAN by putting the LAN address in brackets. eg. [10.1.1.1] will exclude an interface with ip address 10.1.1.1 from SSDP 5 fixed a problem where an invalid LAN address causing the SSDP to crash 6 corrected local link filter (FilterIPAddress) to filter on 169.254. addresses --- Emby.Dlna/Main/DlnaEntryPoint.cs | 8 +- Emby.Server.Implementations/ApplicationHost.cs | 2 +- .../Networking/NetworkManager.cs | 150 ++++++++++++--------- MediaBrowser.Common/Net/INetworkManager.cs | 4 +- RSSDP/SsdpCommunicationsServer.cs | 11 +- RSSDP/SsdpDeviceLocator.cs | 2 +- 6 files changed, 101 insertions(+), 76 deletions(-) (limited to 'MediaBrowser.Common/Net') diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index c5d60b2a0..e6806c87b 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -180,7 +180,7 @@ namespace Emby.Dlna.Main var enableMultiSocketBinding = OperatingSystem.Id == OperatingSystemId.Windows || OperatingSystem.Id == OperatingSystemId.Linux; - _communicationsServer = new SsdpCommunicationsServer(_config, _socketFactory, _networkManager, _logger, enableMultiSocketBinding) + _communicationsServer = new SsdpCommunicationsServer(_socketFactory, _networkManager, _logger, enableMultiSocketBinding) { IsShared = true }; @@ -266,6 +266,12 @@ namespace Emby.Dlna.Main continue; } + // Limit to LAN addresses only + if (!_networkManager.IsAddressInSubnets(address, true, true)) + { + continue; + } + var fullService = "urn:schemas-upnp-org:device:MediaServer:1"; _logger.LogInformation("Registering publisher for {0} on {1}", fullService, address); diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 33aec1a06..97fc2c004 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1274,7 +1274,7 @@ namespace Emby.Server.Implementations if (addresses.Count == 0) { - addresses.AddRange(_networkManager.GetLocalIpAddresses(ServerConfigurationManager.Configuration.IgnoreVirtualInterfaces)); + addresses.AddRange(_networkManager.GetLocalIpAddresses()); } var resultList = new List(); diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs index b3e88b667..5979d1eae 100644 --- a/Emby.Server.Implementations/Networking/NetworkManager.cs +++ b/Emby.Server.Implementations/Networking/NetworkManager.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; using System.Net; using System.Net.NetworkInformation; @@ -56,13 +55,13 @@ namespace Emby.Server.Implementations.Networking NetworkChanged?.Invoke(this, EventArgs.Empty); } - public IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface = true) + public IPAddress[] GetLocalIpAddresses() { lock (_localIpAddressSyncLock) { if (_localIpAddresses == null) { - var addresses = GetLocalIpAddressesInternal(ignoreVirtualInterface).ToArray(); + var addresses = GetLocalIpAddressesInternal().ToArray(); _localIpAddresses = addresses; } @@ -71,35 +70,37 @@ namespace Emby.Server.Implementations.Networking } } - private List GetLocalIpAddressesInternal(bool ignoreVirtualInterface) + private List GetLocalIpAddressesInternal() { - var list = GetIPsDefault(ignoreVirtualInterface).ToList(); + var list = GetIPsDefault().ToList(); if (list.Count == 0) { list = GetLocalIpAddressesFallback().GetAwaiter().GetResult().ToList(); } - var listClone = list.ToList(); + var listClone = new List(); - return list - .OrderBy(i => i.AddressFamily == AddressFamily.InterNetwork ? 0 : 1) - .ThenBy(i => listClone.IndexOf(i)) - .Where(FilterIpAddress) - .GroupBy(i => i.ToString()) - .Select(x => x.First()) - .ToList(); - } + var subnets = LocalSubnetsFn(); - private static bool FilterIpAddress(IPAddress address) - { - if (address.IsIPv6LinkLocal - || address.ToString().StartsWith("169.", StringComparison.OrdinalIgnoreCase)) + foreach (var i in list) { - return false; + if (i.IsIPv6LinkLocal || i.ToString().StartsWith("169.254.", StringComparison.OrdinalIgnoreCase)) + { + continue; + } + if (Array.IndexOf(subnets, "[" + i.ToString() + "]") == -1) + { + listClone.Add(i); + } } - return true; + return listClone + .OrderBy(i => i.AddressFamily == AddressFamily.InterNetwork ? 0 : 1) + // .ThenBy(i => listClone.IndexOf(i)) + .GroupBy(i => i.ToString()) + .Select(x => x.First()) + .ToList(); } public bool IsInPrivateAddressSpace(string endpoint) @@ -107,6 +108,7 @@ namespace Emby.Server.Implementations.Networking return IsInPrivateAddressSpace(endpoint, true); } + // checks if the address in endpoint is an RFC1918, RFC1122, or RFC3927 address private bool IsInPrivateAddressSpace(string endpoint, bool checkSubnets) { if (string.Equals(endpoint, "::1", StringComparison.OrdinalIgnoreCase)) @@ -128,23 +130,28 @@ namespace Emby.Server.Implementations.Networking } // Private address space: - // http://en.wikipedia.org/wiki/Private_network - if (endpoint.StartsWith("172.", StringComparison.OrdinalIgnoreCase)) + if (endpoint.ToLower() == "localhost") { - return Is172AddressPrivate(endpoint); + return true; } - if (endpoint.StartsWith("localhost", StringComparison.OrdinalIgnoreCase) || - endpoint.StartsWith("127.", StringComparison.OrdinalIgnoreCase) || - endpoint.StartsWith("169.", StringComparison.OrdinalIgnoreCase)) + try { - return true; - } + byte[] octet = IPAddress.Parse(endpoint).GetAddressBytes(); - if (checkSubnets && endpoint.StartsWith("192.168", StringComparison.OrdinalIgnoreCase)) + if ((octet[0] == 10) || + (octet[0] == 172 && (octet[1] >= 16 && octet[1] <= 31)) || // RFC1918 + (octet[0] == 192 && octet[1] == 168) || // RFC1918 + (octet[0] == 127) || // RFC1122 + (octet[0] == 169 && octet[1] == 254)) // RFC3927 + { + return false; + } + } + catch { - return true; + } if (checkSubnets && IsInPrivateAddressSpaceAndLocalSubnet(endpoint)) @@ -177,6 +184,7 @@ namespace Emby.Server.Implementations.Networking return false; } + // Gives a list of possible subnets from the system whose interface ip starts with endpointFirstPart private List GetSubnets(string endpointFirstPart) { lock (_subnetLookupLock) @@ -222,19 +230,6 @@ namespace Emby.Server.Implementations.Networking } } - private static bool Is172AddressPrivate(string endpoint) - { - for (var i = 16; i <= 31; i++) - { - if (endpoint.StartsWith("172." + i.ToString(CultureInfo.InvariantCulture) + ".", StringComparison.OrdinalIgnoreCase)) - { - return true; - } - } - - return false; - } - public bool IsInLocalNetwork(string endpoint) { return IsInLocalNetworkInternal(endpoint, true); @@ -245,23 +240,57 @@ namespace Emby.Server.Implementations.Networking return IsAddressInSubnets(IPAddress.Parse(addressString), addressString, subnets); } + // returns true if address is in the LAN list in the config file + // always returns false if address has been excluded from the LAN if excludeInterfaces is true + // and excludes RFC addresses if excludeRFC is true + public bool IsAddressInSubnets(IPAddress address, bool excludeInterfaces, bool excludeRFC) + { + byte[] octet = address.GetAddressBytes(); + + if ((octet[0] == 127) || // RFC1122 + (octet[0] == 169 && octet[1] == 254)) // RFC3927 + { + // don't use on loopback or 169 interfaces + return false; + } + + string addressString = address.ToString(); + string excludeAddress = "[" + addressString + "]"; + var subnets = LocalSubnetsFn(); + + // Exclude any addresses if they appear in the LAN list in [ ] + if (Array.IndexOf(subnets, excludeAddress) != -1) + { + return false; + } + return IsAddressInSubnets(address, addressString, subnets); + } + + // Checks to see if address/addressString (same but different type) falls within subnets[] private static bool IsAddressInSubnets(IPAddress address, string addressString, string[] subnets) { foreach (var subnet in subnets) { var normalizedSubnet = subnet.Trim(); - + // is the subnet a host address and does it match the address being passes? if (string.Equals(normalizedSubnet, addressString, StringComparison.OrdinalIgnoreCase)) { return true; } - + // parse CIDR subnets and see if address falls within it. if (normalizedSubnet.Contains('/', StringComparison.Ordinal)) { - var ipNetwork = IPNetwork.Parse(normalizedSubnet); - if (ipNetwork.Contains(address)) + try { - return true; + var ipNetwork = IPNetwork.Parse(normalizedSubnet); + if (ipNetwork.Contains(address)) + { + return true; + } + } + catch + { + // Ignoring - invalid subnet passed encountered. } } } @@ -359,8 +388,8 @@ namespace Emby.Server.Implementations.Networking { return Dns.GetHostAddressesAsync(hostName); } - - private IEnumerable GetIPsDefault(bool ignoreVirtualInterface) + + private IEnumerable GetIPsDefault() { IEnumerable interfaces; @@ -380,15 +409,7 @@ namespace Emby.Server.Implementations.Networking { var ipProperties = network.GetIPProperties(); - // Try to exclude virtual adapters - // http://stackoverflow.com/questions/8089685/c-sharp-finding-my-machines-local-ip-address-and-not-the-vms - var addr = ipProperties.GatewayAddresses.FirstOrDefault(); - if (addr == null - || (ignoreVirtualInterface - && (addr.Address.Equals(IPAddress.Any) || addr.Address.Equals(IPAddress.IPv6Any)))) - { - return Enumerable.Empty(); - } + // Exclude any addresses if they appear in the LAN list in [ ] return ipProperties.UnicastAddresses .Select(i => i.Address) @@ -494,15 +515,12 @@ namespace Emby.Server.Implementations.Networking foreach (NetworkInterface ni in interfaces) { - if (ni.GetIPProperties().GatewayAddresses.FirstOrDefault() != null) + foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) { - foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) + if (ip.Address.Equals(address) && ip.IPv4Mask != null) { - if (ip.Address.Equals(address) && ip.IPv4Mask != null) - { - return ip.IPv4Mask; - } - } + return ip.IPv4Mask; + } } } diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index 3ba75abd8..b7ec1d122 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -41,10 +41,12 @@ namespace MediaBrowser.Common.Net /// true if [is in local network] [the specified endpoint]; otherwise, false. bool IsInLocalNetwork(string endpoint); - IPAddress[] GetLocalIpAddresses(bool ignoreVirtualInterface); + IPAddress[] GetLocalIpAddresses(); bool IsAddressInSubnets(string addressString, string[] subnets); + bool IsAddressInSubnets(IPAddress address, bool excludeInterfaces, bool excludeRFC); + bool IsInSameSubnet(IPAddress address1, IPAddress address2, IPAddress subnetMask); IPAddress GetLocalIpSubnetMask(IPAddress address); diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 18097ef24..a16e4c73f 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -46,8 +46,7 @@ namespace Rssdp.Infrastructure private HttpResponseParser _ResponseParser; private readonly ILogger _logger; private ISocketFactory _SocketFactory; - private readonly INetworkManager _networkManager; - private readonly IServerConfigurationManager _config; + private readonly INetworkManager _networkManager; private int _LocalPort; private int _MulticastTtl; @@ -77,11 +76,11 @@ namespace Rssdp.Infrastructure /// Minimum constructor. /// /// The argument is null. - public SsdpCommunicationsServer(IServerConfigurationManager config, ISocketFactory socketFactory, + public SsdpCommunicationsServer(ISocketFactory socketFactory, INetworkManager networkManager, ILogger logger, bool enableMultiSocketBinding) : this(socketFactory, 0, SsdpConstants.SsdpDefaultMulticastTimeToLive, networkManager, logger, enableMultiSocketBinding) { - _config = config; + } /// @@ -370,13 +369,13 @@ namespace Rssdp.Infrastructure if (_enableMultiSocketBinding) { - foreach (var address in _networkManager.GetLocalIpAddresses(_config.Configuration.IgnoreVirtualInterfaces)) + foreach (var address in _networkManager.GetLocalIpAddresses()) { if (address.AddressFamily == AddressFamily.InterNetworkV6) { // Not support IPv6 right now continue; - } + } try { diff --git a/RSSDP/SsdpDeviceLocator.cs b/RSSDP/SsdpDeviceLocator.cs index 59a2710d5..b62c50e28 100644 --- a/RSSDP/SsdpDeviceLocator.cs +++ b/RSSDP/SsdpDeviceLocator.cs @@ -357,7 +357,7 @@ namespace Rssdp.Infrastructure private void ProcessSearchResponseMessage(HttpResponseMessage message, IPAddress localIpAddress) { if (!message.IsSuccessStatusCode) return; - + var location = GetFirstHeaderUriValue("Location", message); if (location != null) { -- cgit v1.2.3 From 61e65d032ecb1d2bf614e018f4a0dd925300cfde Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Sun, 17 May 2020 20:43:54 +0100 Subject: Update MediaBrowser.Common/Net/INetworkManager.cs Co-authored-by: Patrick Barron <18354464+barronpm@users.noreply.github.com> --- MediaBrowser.Common/Net/INetworkManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Common/Net') diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index 19314ada8..783b7c60c 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -62,7 +62,7 @@ namespace MediaBrowser.Common.Net IPAddress[] GetLocalIpAddresses(); /// - /// Checks if the give address false within the ranges givin in [subnets]. The addresses in subnets can be hosts or subnets in the CIDR format. + /// Checks if the given address falls within the ranges given in [subnets]. The addresses in subnets can be hosts or subnets in the CIDR format. /// /// The address to check /// If true, check against addresses in the LAN settings which have [] arroud and return true if it matches the address give in address -- cgit v1.2.3 From 5e1be0d4f0ac6ec4aa5f30ab617b544a38420c1a Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Sun, 17 May 2020 20:44:19 +0100 Subject: Update MediaBrowser.Common/Net/INetworkManager.cs Co-authored-by: Patrick Barron <18354464+barronpm@users.noreply.github.com> --- MediaBrowser.Common/Net/INetworkManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Common/Net') diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index 783b7c60c..1fec0390d 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -65,7 +65,7 @@ namespace MediaBrowser.Common.Net /// Checks if the given address falls within the ranges given in [subnets]. The addresses in subnets can be hosts or subnets in the CIDR format. /// /// The address to check - /// If true, check against addresses in the LAN settings which have [] arroud and return true if it matches the address give in address + /// If true, check against addresses in the LAN settings surrounded by brackets ([]) /// falseif the address isn't in the subnets, true otherwise bool IsAddressInSubnets(string addressString, string[] subnets); -- cgit v1.2.3 From d5a924772b0b25808beb3405a041a037bbc679c8 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Sun, 17 May 2020 20:44:35 +0100 Subject: Update MediaBrowser.Common/Net/INetworkManager.cs Co-authored-by: Patrick Barron <18354464+barronpm@users.noreply.github.com> --- MediaBrowser.Common/Net/INetworkManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Common/Net') diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index 1fec0390d..56b253b2d 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -66,7 +66,7 @@ namespace MediaBrowser.Common.Net /// /// The address to check /// If true, check against addresses in the LAN settings surrounded by brackets ([]) - /// falseif the address isn't in the subnets, true otherwise + /// trueif the address is in at least one of the given subnets, false otherwise. bool IsAddressInSubnets(string addressString, string[] subnets); /// -- cgit v1.2.3 From f404e915eeef6cc9b05c6d006569b6d3a3e54eee Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Wed, 3 Jun 2020 13:04:45 +0200 Subject: Enable StyleCop for MediaBrowser.Common --- .../Configuration/ConfigurationStore.cs | 20 +++++++++++++++ .../Configuration/IApplicationPaths.cs | 22 ++++++++-------- .../Configuration/IConfigurationFactory.cs | 30 ---------------------- .../Configuration/IConfigurationManager.cs | 2 +- .../Configuration/IValidatingConfiguration.cs | 15 +++++++++++ MediaBrowser.Common/MediaBrowser.Common.csproj | 2 +- MediaBrowser.Common/Net/CacheMode.cs | 11 ++++++++ MediaBrowser.Common/Net/CompressionMethods.cs | 15 +++++++++++ MediaBrowser.Common/Net/HttpRequestOptions.cs | 14 ---------- MediaBrowser.Common/Progress/ActionableProgress.cs | 17 +++--------- MediaBrowser.Common/Progress/SimpleProgress.cs | 16 ++++++++++++ 11 files changed, 94 insertions(+), 70 deletions(-) create mode 100644 MediaBrowser.Common/Configuration/ConfigurationStore.cs create mode 100644 MediaBrowser.Common/Configuration/IValidatingConfiguration.cs create mode 100644 MediaBrowser.Common/Net/CacheMode.cs create mode 100644 MediaBrowser.Common/Net/CompressionMethods.cs create mode 100644 MediaBrowser.Common/Progress/SimpleProgress.cs (limited to 'MediaBrowser.Common/Net') diff --git a/MediaBrowser.Common/Configuration/ConfigurationStore.cs b/MediaBrowser.Common/Configuration/ConfigurationStore.cs new file mode 100644 index 000000000..d31d45e4c --- /dev/null +++ b/MediaBrowser.Common/Configuration/ConfigurationStore.cs @@ -0,0 +1,20 @@ +using System; + +namespace MediaBrowser.Common.Configuration +{ + /// + /// Describes a single entry in the application configuration. + /// + public class ConfigurationStore + { + /// + /// Gets or sets the unique identifier for the configuration. + /// + public string Key { get; set; } + + /// + /// Gets or sets the type used to store the data for this configuration entry. + /// + public Type ConfigurationType { get; set; } + } +} diff --git a/MediaBrowser.Common/Configuration/IApplicationPaths.cs b/MediaBrowser.Common/Configuration/IApplicationPaths.cs index 870b90796..4cea61682 100644 --- a/MediaBrowser.Common/Configuration/IApplicationPaths.cs +++ b/MediaBrowser.Common/Configuration/IApplicationPaths.cs @@ -3,12 +3,12 @@ using MediaBrowser.Model.Configuration; namespace MediaBrowser.Common.Configuration { /// - /// Interface IApplicationPaths + /// Interface IApplicationPaths. /// public interface IApplicationPaths { /// - /// Gets the path to the program data folder + /// Gets the path to the program data folder. /// /// The program data path. string ProgramDataPath { get; } @@ -23,13 +23,13 @@ namespace MediaBrowser.Common.Configuration string WebPath { get; } /// - /// Gets the path to the program system folder + /// Gets the path to the program system folder. /// /// The program data path. string ProgramSystemPath { get; } /// - /// Gets the folder path to the data directory + /// Gets the folder path to the data directory. /// /// The data directory. string DataPath { get; } @@ -41,43 +41,43 @@ namespace MediaBrowser.Common.Configuration string ImageCachePath { get; } /// - /// Gets the path to the plugin directory + /// Gets the path to the plugin directory. /// /// The plugins path. string PluginsPath { get; } /// - /// Gets the path to the plugin configurations directory + /// Gets the path to the plugin configurations directory. /// /// The plugin configurations path. string PluginConfigurationsPath { get; } /// - /// Gets the path to the log directory + /// Gets the path to the log directory. /// /// The log directory path. string LogDirectoryPath { get; } /// - /// Gets the path to the application configuration root directory + /// Gets the path to the application configuration root directory. /// /// The configuration directory path. string ConfigurationDirectoryPath { get; } /// - /// Gets the path to the system configuration file + /// Gets the path to the system configuration file. /// /// The system configuration file path. string SystemConfigurationFilePath { get; } /// - /// Gets the folder path to the cache directory + /// Gets the folder path to the cache directory. /// /// The cache directory. string CachePath { get; } /// - /// Gets the folder path to the temp directory within the cache folder + /// Gets the folder path to the temp directory within the cache folder. /// /// The temp directory. string TempDirectory { get; } diff --git a/MediaBrowser.Common/Configuration/IConfigurationFactory.cs b/MediaBrowser.Common/Configuration/IConfigurationFactory.cs index 07ca2b58b..6db1f1364 100644 --- a/MediaBrowser.Common/Configuration/IConfigurationFactory.cs +++ b/MediaBrowser.Common/Configuration/IConfigurationFactory.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; namespace MediaBrowser.Common.Configuration @@ -15,33 +14,4 @@ namespace MediaBrowser.Common.Configuration /// The configuration store. IEnumerable GetConfigurations(); } - - /// - /// Describes a single entry in the application configuration. - /// - public class ConfigurationStore - { - /// - /// Gets or sets the unique identifier for the configuration. - /// - public string Key { get; set; } - - /// - /// Gets or sets the type used to store the data for this configuration entry. - /// - public Type ConfigurationType { get; set; } - } - - /// - /// A configuration store that can be validated. - /// - public interface IValidatingConfiguration - { - /// - /// Validation method to be invoked before saving the configuration. - /// - /// The old configuration. - /// The new configuration. - void Validate(object oldConfig, object newConfig); - } } diff --git a/MediaBrowser.Common/Configuration/IConfigurationManager.cs b/MediaBrowser.Common/Configuration/IConfigurationManager.cs index caf2edd83..fe726090d 100644 --- a/MediaBrowser.Common/Configuration/IConfigurationManager.cs +++ b/MediaBrowser.Common/Configuration/IConfigurationManager.cs @@ -24,7 +24,7 @@ namespace MediaBrowser.Common.Configuration event EventHandler NamedConfigurationUpdated; /// - /// Gets or sets the application paths. + /// Gets the application paths. /// /// The application paths. IApplicationPaths CommonApplicationPaths { get; } diff --git a/MediaBrowser.Common/Configuration/IValidatingConfiguration.cs b/MediaBrowser.Common/Configuration/IValidatingConfiguration.cs new file mode 100644 index 000000000..3b1d84f3c --- /dev/null +++ b/MediaBrowser.Common/Configuration/IValidatingConfiguration.cs @@ -0,0 +1,15 @@ +namespace MediaBrowser.Common.Configuration +{ + /// + /// A configuration store that can be validated. + /// + public interface IValidatingConfiguration + { + /// + /// Validation method to be invoked before saving the configuration. + /// + /// The old configuration. + /// The new configuration. + void Validate(object oldConfig, object newConfig); + } +} diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index a597b9052..0713b83b7 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -37,7 +37,7 @@ - + diff --git a/MediaBrowser.Common/Net/CacheMode.cs b/MediaBrowser.Common/Net/CacheMode.cs new file mode 100644 index 000000000..78fa3bf9b --- /dev/null +++ b/MediaBrowser.Common/Net/CacheMode.cs @@ -0,0 +1,11 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1602 + +namespace MediaBrowser.Common.Net +{ + public enum CacheMode + { + None = 0, + Unconditional = 1 + } +} diff --git a/MediaBrowser.Common/Net/CompressionMethods.cs b/MediaBrowser.Common/Net/CompressionMethods.cs new file mode 100644 index 000000000..39b72609f --- /dev/null +++ b/MediaBrowser.Common/Net/CompressionMethods.cs @@ -0,0 +1,15 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1602 + +using System; + +namespace MediaBrowser.Common.Net +{ + [Flags] + public enum CompressionMethods + { + None = 0b00000001, + Deflate = 0b00000010, + Gzip = 0b00000100 + } +} diff --git a/MediaBrowser.Common/Net/HttpRequestOptions.cs b/MediaBrowser.Common/Net/HttpRequestOptions.cs index 38274a80e..347fc9833 100644 --- a/MediaBrowser.Common/Net/HttpRequestOptions.cs +++ b/MediaBrowser.Common/Net/HttpRequestOptions.cs @@ -102,18 +102,4 @@ namespace MediaBrowser.Common.Net return value; } } - - public enum CacheMode - { - None = 0, - Unconditional = 1 - } - - [Flags] - public enum CompressionMethods - { - None = 0b00000001, - Deflate = 0b00000010, - Gzip = 0b00000100 - } } diff --git a/MediaBrowser.Common/Progress/ActionableProgress.cs b/MediaBrowser.Common/Progress/ActionableProgress.cs index af69055aa..d5bcd5be9 100644 --- a/MediaBrowser.Common/Progress/ActionableProgress.cs +++ b/MediaBrowser.Common/Progress/ActionableProgress.cs @@ -5,15 +5,16 @@ using System; namespace MediaBrowser.Common.Progress { /// - /// Class ActionableProgress + /// Class ActionableProgress. /// - /// + /// The type for the action parameter. public class ActionableProgress : IProgress { /// - /// The _actions + /// The _actions. /// private Action _action; + public event EventHandler ProgressChanged; /// @@ -32,14 +33,4 @@ namespace MediaBrowser.Common.Progress _action?.Invoke(value); } } - - public class SimpleProgress : IProgress - { - public event EventHandler ProgressChanged; - - public void Report(T value) - { - ProgressChanged?.Invoke(this, value); - } - } } diff --git a/MediaBrowser.Common/Progress/SimpleProgress.cs b/MediaBrowser.Common/Progress/SimpleProgress.cs new file mode 100644 index 000000000..d75675bf1 --- /dev/null +++ b/MediaBrowser.Common/Progress/SimpleProgress.cs @@ -0,0 +1,16 @@ +#pragma warning disable CS1591 + +using System; + +namespace MediaBrowser.Common.Progress +{ + public class SimpleProgress : IProgress + { + public event EventHandler ProgressChanged; + + public void Report(T value) + { + ProgressChanged?.Invoke(this, value); + } + } +} -- cgit v1.2.3 From 2cecde658b2bd4a97999c737005c7b06c63b8813 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Thu, 11 Jun 2020 22:58:29 +0100 Subject: Update INetworkManager.cs Editting comments - adding periods --- MediaBrowser.Common/Net/INetworkManager.cs | 42 +++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'MediaBrowser.Common/Net') diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index 56b253b2d..74441d68d 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -12,7 +12,7 @@ namespace MediaBrowser.Common.Net event EventHandler NetworkChanged; /// - /// Contains a function to return the list of user defined LAN addresses + /// Gets or sets a function to return the list of user defined LAN addresses. /// Func LocalSubnetsFn { get; set; } @@ -54,44 +54,44 @@ namespace MediaBrowser.Common.Net /// The endpoint. /// true if [is in local network] [the specified endpoint]; otherwise, false. bool IsInLocalNetwork(string endpoint); - + /// - /// Investigates an caches a list of interface addresses, excluding local link and LAN excluded addresses + /// Investigates an caches a list of interface addresses, excluding local link and LAN excluded addresses. /// - /// The list of ipaddresses + /// The list of ipaddresses. IPAddress[] GetLocalIpAddresses(); - - /// + + /// /// Checks if the given address falls within the ranges given in [subnets]. The addresses in subnets can be hosts or subnets in the CIDR format. /// - /// The address to check - /// If true, check against addresses in the LAN settings surrounded by brackets ([]) + /// The address to check. + /// If true, check against addresses in the LAN settings surrounded by brackets ([]). /// trueif the address is in at least one of the given subnets, false otherwise. bool IsAddressInSubnets(string addressString, string[] subnets); /// - /// Returns true if address is in the LAN list in the config file + /// Returns true if address is in the LAN list in the config file. /// - /// The address to check - /// If true, check against addresses in the LAN settings which have [] arroud and return true if it matches the address give in address - /// If true, returns false if address is in the 127.x.x.x or 169.128.x.x range - /// falseif the address isn't in the LAN list, true if the address has been defined as a LAN address + /// The address to check. + /// If true, check against addresses in the LAN settings which have [] arroud and return true if it matches the address give in address. + /// If true, returns false if address is in the 127.x.x.x or 169.128.x.x range. + /// falseif the address isn't in the LAN list, true if the address has been defined as a LAN address. bool IsAddressInSubnets(IPAddress address, bool excludeInterfaces, bool excludeRFC); /// - /// Checks if address is in the LAN list in the config file + /// Checks if address is in the LAN list in the config file. /// - /// Source address to check - /// Destination address to check against - /// Destination subnet to check against - /// true/falsedepending on whether address1 is in the same subnet as IPAddress2 with subnetMas + /// Source address to check. + /// Destination address to check against. + /// Destination subnet to check against. + /// true/falsedepending on whether address1 is in the same subnet as IPAddress2 with subnetMask. bool IsInSameSubnet(IPAddress address1, IPAddress address2, IPAddress subnetMask); /// - /// Returns the subnet mask of an interface with the given address + /// Returns the subnet mask of an interface with the given address. /// - /// The address to check - /// Returns the subnet mask of an interface with the given address, or null if an interface match cannot be found + /// The address to check. + /// Returns the subnet mask of an interface with the given address, or null if an interface match cannot be found. IPAddress GetLocalIpSubnetMask(IPAddress address); } } -- cgit v1.2.3 From 306f7b3c309da4d88d643d050338b0168b430a0b Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Thu, 11 Jun 2020 23:10:13 +0100 Subject: Update INetworkManager.cs --- MediaBrowser.Common/Net/INetworkManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.Common/Net') diff --git a/MediaBrowser.Common/Net/INetworkManager.cs b/MediaBrowser.Common/Net/INetworkManager.cs index 74441d68d..a0330afef 100644 --- a/MediaBrowser.Common/Net/INetworkManager.cs +++ b/MediaBrowser.Common/Net/INetworkManager.cs @@ -61,7 +61,7 @@ namespace MediaBrowser.Common.Net /// The list of ipaddresses. IPAddress[] GetLocalIpAddresses(); - /// + /// /// Checks if the given address falls within the ranges given in [subnets]. The addresses in subnets can be hosts or subnets in the CIDR format. /// /// The address to check. -- cgit v1.2.3 From 076e17f35556c6d1257856896619e30eb494b2bb Mon Sep 17 00:00:00 2001 From: crobibero Date: Wed, 19 Aug 2020 06:31:45 -0600 Subject: Add default http client --- Jellyfin.Server/Startup.cs | 15 ++- MediaBrowser.Common/Net/DefaultHttpClient.cs | 108 +++++++++++++++++++++ .../Net/DefaultHttpClientHandler.cs | 18 ++++ .../Net/UserAgentDelegatingHandler.cs | 52 ++++++++++ 4 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 MediaBrowser.Common/Net/DefaultHttpClient.cs create mode 100644 MediaBrowser.Common/Net/DefaultHttpClientHandler.cs create mode 100644 MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs (limited to 'MediaBrowser.Common/Net') diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs index 108d8f881..05deaa2e0 100644 --- a/Jellyfin.Server/Startup.cs +++ b/Jellyfin.Server/Startup.cs @@ -1,13 +1,20 @@ +using System.Diagnostics; +using System.Net; using System.Net.Http; +using System.Reflection; +using Emby.Server.Implementations; using Jellyfin.Server.Extensions; +using Jellyfin.Server.Implementations; using Jellyfin.Server.Middleware; using Jellyfin.Server.Models; +using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Http.Logging; using Prometheus; namespace Jellyfin.Server @@ -44,7 +51,13 @@ namespace Jellyfin.Server services.AddCustomAuthentication(); services.AddJellyfinApiAuthorization(); - services.AddHttpClient(); + + services + .AddTransient() + .AddHttpClient() + .ConfigureHttpClient((sp, options) => {}) + .ConfigurePrimaryHttpMessageHandler(x => new DefaultHttpClientHandler()) + .AddHttpMessageHandler(); } /// diff --git a/MediaBrowser.Common/Net/DefaultHttpClient.cs b/MediaBrowser.Common/Net/DefaultHttpClient.cs new file mode 100644 index 000000000..cbc06eec0 --- /dev/null +++ b/MediaBrowser.Common/Net/DefaultHttpClient.cs @@ -0,0 +1,108 @@ +using System; +using System.IO; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Common.Net +{ + /// + /// Default http client. + /// + public class DefaultHttpClient + { + private readonly HttpClient _httpClient; + + /// + /// Initializes a new instance of the class. + /// + /// Instance of httpclient. + public DefaultHttpClient(HttpClient httpClient) + { + _httpClient = httpClient; + } + + /// + /// Make GET request. + /// + /// Url to request. + /// A containing the . + public Task GetAsync(string url) + { + return _httpClient.GetAsync(url); + } + + /// + /// Make GET request. + /// + /// Url to request. + /// A containing the . + public Task GetAsync(Uri url) + { + return _httpClient.GetAsync(url); + } + + /// + /// Make GET request. + /// + /// Url to request. + /// The cancellation token. + /// A containing the . + public Task GetAsync(string url, CancellationToken cancellationToken) + { + return _httpClient.GetAsync(url, cancellationToken); + } + + /// + /// Make GET request. + /// + /// Url to request. + /// The cancellation token. + /// A containing the . + public Task GetAsync(Uri url, CancellationToken cancellationToken) + { + return _httpClient.GetAsync(url, cancellationToken); + } + + /// + /// Get stream. + /// + /// Url to get stream from. + /// A containing the . + public Task GetStreamAsync(string url) + { + return _httpClient.GetStreamAsync(url); + } + + /// + /// Get stream. + /// + /// Url to get stream from. + /// A containing the . + public Task GetStreamAsync(Uri url) + { + return _httpClient.GetStreamAsync(url); + } + + /// + /// Send request. + /// + /// The . + /// A containing the . + public Task SendAsync(HttpRequestMessage requestMessage) + { + return _httpClient.SendAsync(requestMessage); + } + + /// + /// Send request. + /// + /// The . + /// The cancellation token. + /// A containing the . + public Task SendAsync(HttpRequestMessage requestMessage, CancellationToken cancellationToken) + { + return _httpClient.SendAsync(requestMessage, cancellationToken); + } + } +} diff --git a/MediaBrowser.Common/Net/DefaultHttpClientHandler.cs b/MediaBrowser.Common/Net/DefaultHttpClientHandler.cs new file mode 100644 index 000000000..6608fad34 --- /dev/null +++ b/MediaBrowser.Common/Net/DefaultHttpClientHandler.cs @@ -0,0 +1,18 @@ +using System.Net; +using System.Net.Http; + +namespace MediaBrowser.Common.Net +{ + /// + /// Default http client handler. + /// + public class DefaultHttpClientHandler : HttpClientHandler + { + /// + public DefaultHttpClientHandler() + { + // TODO change to DecompressionMethods.All with .NET5 + AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; + } + } +} diff --git a/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs b/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs new file mode 100644 index 000000000..f527c766f --- /dev/null +++ b/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Common.Net +{ + /// + /// User agent delegating handler. + /// Adds User-Agent header to all requests. + /// + public class UserAgentDelegatingHandler : DelegatingHandler + { + /// + public UserAgentDelegatingHandler(IApplicationHost applicationHost) + { + UserAgentValues = new List + { + new ProductInfoHeaderValue(applicationHost.Name.Replace(' ', '-'), applicationHost.ApplicationVersionString), + new ProductInfoHeaderValue($"({Environment.OSVersion}; {applicationHost.ApplicationUserAgentAddress})") + }; + } + + /// + /// Gets or sets the user agent values. + /// + public List UserAgentValues { get; set; } + + /// + /// Send request message. + /// + /// The request message. + /// The cancellation token. + /// A containing the . + protected override Task SendAsync( + HttpRequestMessage request, + CancellationToken cancellationToken) + { + if (request.Headers.UserAgent.Count == 0) + { + foreach (var userAgentValue in UserAgentValues) + { + request.Headers.UserAgent.Add(userAgentValue); + } + } + + return base.SendAsync(request, cancellationToken); + } + } +} -- cgit v1.2.3 From ac5c0866f3745784c78e376c2eefb111b929d8e5 Mon Sep 17 00:00:00 2001 From: crobibero Date: Wed, 19 Aug 2020 06:52:18 -0600 Subject: P E R F O R M A N C E --- MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'MediaBrowser.Common/Net') diff --git a/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs b/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs index f527c766f..c016af87c 100644 --- a/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs +++ b/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; using System.Threading; @@ -13,21 +12,18 @@ namespace MediaBrowser.Common.Net /// public class UserAgentDelegatingHandler : DelegatingHandler { + private readonly ProductInfoHeaderValue[] _userAgentValues; + /// public UserAgentDelegatingHandler(IApplicationHost applicationHost) { - UserAgentValues = new List + _userAgentValues = new [] { new ProductInfoHeaderValue(applicationHost.Name.Replace(' ', '-'), applicationHost.ApplicationVersionString), new ProductInfoHeaderValue($"({Environment.OSVersion}; {applicationHost.ApplicationUserAgentAddress})") }; } - /// - /// Gets or sets the user agent values. - /// - public List UserAgentValues { get; set; } - /// /// Send request message. /// @@ -40,9 +36,9 @@ namespace MediaBrowser.Common.Net { if (request.Headers.UserAgent.Count == 0) { - foreach (var userAgentValue in UserAgentValues) + for (var i = 0; i < _userAgentValues.Length; i++) { - request.Headers.UserAgent.Add(userAgentValue); + request.Headers.UserAgent.Add(_userAgentValues[i]); } } -- cgit v1.2.3 From f6b8cd4b46d03a1baa86d4ee31d1a66e2ad05097 Mon Sep 17 00:00:00 2001 From: crobibero Date: Wed, 19 Aug 2020 07:09:07 -0600 Subject: Fix build --- MediaBrowser.Common/Net/DefaultHttpClient.cs | 31 ---------------------- .../Net/DefaultHttpClientHandler.cs | 4 ++- .../Net/UserAgentDelegatingHandler.cs | 7 +++-- 3 files changed, 8 insertions(+), 34 deletions(-) (limited to 'MediaBrowser.Common/Net') diff --git a/MediaBrowser.Common/Net/DefaultHttpClient.cs b/MediaBrowser.Common/Net/DefaultHttpClient.cs index cbc06eec0..be18e82db 100644 --- a/MediaBrowser.Common/Net/DefaultHttpClient.cs +++ b/MediaBrowser.Common/Net/DefaultHttpClient.cs @@ -22,16 +22,6 @@ namespace MediaBrowser.Common.Net _httpClient = httpClient; } - /// - /// Make GET request. - /// - /// Url to request. - /// A containing the . - public Task GetAsync(string url) - { - return _httpClient.GetAsync(url); - } - /// /// Make GET request. /// @@ -42,17 +32,6 @@ namespace MediaBrowser.Common.Net return _httpClient.GetAsync(url); } - /// - /// Make GET request. - /// - /// Url to request. - /// The cancellation token. - /// A containing the . - public Task GetAsync(string url, CancellationToken cancellationToken) - { - return _httpClient.GetAsync(url, cancellationToken); - } - /// /// Make GET request. /// @@ -64,16 +43,6 @@ namespace MediaBrowser.Common.Net return _httpClient.GetAsync(url, cancellationToken); } - /// - /// Get stream. - /// - /// Url to get stream from. - /// A containing the . - public Task GetStreamAsync(string url) - { - return _httpClient.GetStreamAsync(url); - } - /// /// Get stream. /// diff --git a/MediaBrowser.Common/Net/DefaultHttpClientHandler.cs b/MediaBrowser.Common/Net/DefaultHttpClientHandler.cs index 6608fad34..e189d6e70 100644 --- a/MediaBrowser.Common/Net/DefaultHttpClientHandler.cs +++ b/MediaBrowser.Common/Net/DefaultHttpClientHandler.cs @@ -8,7 +8,9 @@ namespace MediaBrowser.Common.Net /// public class DefaultHttpClientHandler : HttpClientHandler { - /// + /// + /// Initializes a new instance of the class. + /// public DefaultHttpClientHandler() { // TODO change to DecompressionMethods.All with .NET5 diff --git a/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs b/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs index c016af87c..31af85f7d 100644 --- a/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs +++ b/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs @@ -14,10 +14,13 @@ namespace MediaBrowser.Common.Net { private readonly ProductInfoHeaderValue[] _userAgentValues; - /// + /// + /// Initializes a new instance of the class. + /// + /// Instance of the interface. public UserAgentDelegatingHandler(IApplicationHost applicationHost) { - _userAgentValues = new [] + _userAgentValues = new[] { new ProductInfoHeaderValue(applicationHost.Name.Replace(' ', '-'), applicationHost.ApplicationVersionString), new ProductInfoHeaderValue($"({Environment.OSVersion}; {applicationHost.ApplicationUserAgentAddress})") -- cgit v1.2.3 From abb79bf810a25331a9c84958690e7af7717499e6 Mon Sep 17 00:00:00 2001 From: crobibero Date: Wed, 19 Aug 2020 13:41:00 -0600 Subject: remove OS and email from default UserAgent --- MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'MediaBrowser.Common/Net') diff --git a/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs b/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs index 31af85f7d..74dc22b7a 100644 --- a/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs +++ b/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs @@ -1,5 +1,4 @@ -using System; -using System.Net.Http; +using System.Net.Http; using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; @@ -22,8 +21,7 @@ namespace MediaBrowser.Common.Net { _userAgentValues = new[] { - new ProductInfoHeaderValue(applicationHost.Name.Replace(' ', '-'), applicationHost.ApplicationVersionString), - new ProductInfoHeaderValue($"({Environment.OSVersion}; {applicationHost.ApplicationUserAgentAddress})") + new ProductInfoHeaderValue(applicationHost.Name.Replace(' ', '-'), applicationHost.ApplicationVersionString) }; } -- cgit v1.2.3 From 64a811d78333287647abf2c5193d005b5758eec3 Mon Sep 17 00:00:00 2001 From: crobibero Date: Mon, 31 Aug 2020 08:47:38 -0600 Subject: use named http clients --- Jellyfin.Server/Startup.cs | 23 +++++-- MediaBrowser.Common/Net/DefaultHttpClient.cs | 77 ---------------------- MediaBrowser.Common/Net/NamedClient.cs | 18 +++++ .../Net/UserAgentDelegatingHandler.cs | 49 -------------- 4 files changed, 36 insertions(+), 131 deletions(-) delete mode 100644 MediaBrowser.Common/Net/DefaultHttpClient.cs create mode 100644 MediaBrowser.Common/Net/NamedClient.cs delete mode 100644 MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs (limited to 'MediaBrowser.Common/Net') diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs index a2db7b5c1..eb74d906f 100644 --- a/Jellyfin.Server/Startup.cs +++ b/Jellyfin.Server/Startup.cs @@ -1,9 +1,11 @@ using System; using System.ComponentModel; +using System.Net.Http.Headers; using Jellyfin.Api.TypeConverters; using Jellyfin.Server.Extensions; using Jellyfin.Server.Middleware; using Jellyfin.Server.Models; +using MediaBrowser.Common; using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; @@ -21,14 +23,17 @@ namespace Jellyfin.Server public class Startup { private readonly IServerConfigurationManager _serverConfigurationManager; + private readonly IApplicationHost _applicationHost; /// /// Initializes a new instance of the class. /// /// The server configuration manager. - public Startup(IServerConfigurationManager serverConfigurationManager) + /// The application host. + public Startup(IServerConfigurationManager serverConfigurationManager, IApplicationHost applicationHost) { _serverConfigurationManager = serverConfigurationManager; + _applicationHost = applicationHost; } /// @@ -49,10 +54,18 @@ namespace Jellyfin.Server services.AddJellyfinApiAuthorization(); services - .AddTransient() - .AddHttpClient() - .ConfigurePrimaryHttpMessageHandler(x => new DefaultHttpClientHandler()) - .AddHttpMessageHandler(); + .AddHttpClient(NamedClient.Default, c => + { + c.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(_applicationHost.Name.Replace(' ', '-'), _applicationHost.ApplicationVersionString)); + }) + .ConfigurePrimaryHttpMessageHandler(x => new DefaultHttpClientHandler()); + + services.AddHttpClient(NamedClient.MusicBrainz, c => + { + c.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(_applicationHost.Name.Replace(' ', '-'), _applicationHost.ApplicationVersionString)); + c.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(_applicationHost.ApplicationUserAgentAddress)); + }) + .ConfigurePrimaryHttpMessageHandler(x => new DefaultHttpClientHandler()); } /// diff --git a/MediaBrowser.Common/Net/DefaultHttpClient.cs b/MediaBrowser.Common/Net/DefaultHttpClient.cs deleted file mode 100644 index be18e82db..000000000 --- a/MediaBrowser.Common/Net/DefaultHttpClient.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.IO; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Net -{ - /// - /// Default http client. - /// - public class DefaultHttpClient - { - private readonly HttpClient _httpClient; - - /// - /// Initializes a new instance of the class. - /// - /// Instance of httpclient. - public DefaultHttpClient(HttpClient httpClient) - { - _httpClient = httpClient; - } - - /// - /// Make GET request. - /// - /// Url to request. - /// A containing the . - public Task GetAsync(Uri url) - { - return _httpClient.GetAsync(url); - } - - /// - /// Make GET request. - /// - /// Url to request. - /// The cancellation token. - /// A containing the . - public Task GetAsync(Uri url, CancellationToken cancellationToken) - { - return _httpClient.GetAsync(url, cancellationToken); - } - - /// - /// Get stream. - /// - /// Url to get stream from. - /// A containing the . - public Task GetStreamAsync(Uri url) - { - return _httpClient.GetStreamAsync(url); - } - - /// - /// Send request. - /// - /// The . - /// A containing the . - public Task SendAsync(HttpRequestMessage requestMessage) - { - return _httpClient.SendAsync(requestMessage); - } - - /// - /// Send request. - /// - /// The . - /// The cancellation token. - /// A containing the . - public Task SendAsync(HttpRequestMessage requestMessage, CancellationToken cancellationToken) - { - return _httpClient.SendAsync(requestMessage, cancellationToken); - } - } -} diff --git a/MediaBrowser.Common/Net/NamedClient.cs b/MediaBrowser.Common/Net/NamedClient.cs new file mode 100644 index 000000000..0f6161c32 --- /dev/null +++ b/MediaBrowser.Common/Net/NamedClient.cs @@ -0,0 +1,18 @@ +namespace MediaBrowser.Common.Net +{ + /// + /// Registered http client names. + /// + public static class NamedClient + { + /// + /// Gets the value for the default named http client. + /// + public const string Default = nameof(Default); + + /// + /// Gets the value for the MusicBrainz named http client. + /// + public const string MusicBrainz = nameof(MusicBrainz); + } +} diff --git a/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs b/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs deleted file mode 100644 index 74dc22b7a..000000000 --- a/MediaBrowser.Common/Net/UserAgentDelegatingHandler.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Net.Http; -using System.Net.Http.Headers; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Net -{ - /// - /// User agent delegating handler. - /// Adds User-Agent header to all requests. - /// - public class UserAgentDelegatingHandler : DelegatingHandler - { - private readonly ProductInfoHeaderValue[] _userAgentValues; - - /// - /// Initializes a new instance of the class. - /// - /// Instance of the interface. - public UserAgentDelegatingHandler(IApplicationHost applicationHost) - { - _userAgentValues = new[] - { - new ProductInfoHeaderValue(applicationHost.Name.Replace(' ', '-'), applicationHost.ApplicationVersionString) - }; - } - - /// - /// Send request message. - /// - /// The request message. - /// The cancellation token. - /// A containing the . - protected override Task SendAsync( - HttpRequestMessage request, - CancellationToken cancellationToken) - { - if (request.Headers.UserAgent.Count == 0) - { - for (var i = 0; i < _userAgentValues.Length; i++) - { - request.Headers.UserAgent.Add(_userAgentValues[i]); - } - } - - return base.SendAsync(request, cancellationToken); - } - } -} -- cgit v1.2.3 From f498e1ee59af1413cd4f041227b0296f9ec02a21 Mon Sep 17 00:00:00 2001 From: crobibero Date: Mon, 31 Aug 2020 12:10:49 -0600 Subject: remove IHttpClient 🎉 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Emby.Server.Implementations/ApplicationHost.cs | 2 - .../HttpClientManager/HttpClientManager.cs | 335 --------------------- MediaBrowser.Common/Net/IHttpClient.cs | 53 ---- 3 files changed, 390 deletions(-) delete mode 100644 Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs delete mode 100644 MediaBrowser.Common/Net/IHttpClient.cs (limited to 'MediaBrowser.Common/Net') diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 9ae010d7c..fbf4aef8b 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -523,8 +523,6 @@ namespace Emby.Server.Implementations ServiceCollection.AddSingleton(_fileSystemManager); ServiceCollection.AddSingleton(); - ServiceCollection.AddSingleton(); - ServiceCollection.AddSingleton(_networkManager); ServiceCollection.AddSingleton(); diff --git a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs deleted file mode 100644 index 25adc5812..000000000 --- a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs +++ /dev/null @@ -1,335 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; -using MediaBrowser.Common; -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; -using MediaBrowser.Model.IO; -using MediaBrowser.Model.Net; -using Microsoft.Extensions.Logging; -using Microsoft.Net.Http.Headers; - -namespace Emby.Server.Implementations.HttpClientManager -{ - /// - /// Class HttpClientManager. - /// - public class HttpClientManager : IHttpClient - { - private readonly ILogger _logger; - private readonly IApplicationPaths _appPaths; - private readonly IFileSystem _fileSystem; - private readonly IApplicationHost _appHost; - - /// - /// Holds a dictionary of http clients by host. Use GetHttpClient(host) to retrieve or create a client for web requests. - /// DON'T dispose it after use. - /// - /// The HTTP clients. - private readonly ConcurrentDictionary _httpClients = new ConcurrentDictionary(); - - /// - /// Initializes a new instance of the class. - /// - public HttpClientManager( - IApplicationPaths appPaths, - ILogger logger, - IFileSystem fileSystem, - IApplicationHost appHost) - { - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _fileSystem = fileSystem; - _appPaths = appPaths ?? throw new ArgumentNullException(nameof(appPaths)); - _appHost = appHost; - } - - /// - /// Gets the correct http client for the given url. - /// - /// The url. - /// HttpClient. - private HttpClient GetHttpClient(string url) - { - var key = GetHostFromUrl(url); - - if (!_httpClients.TryGetValue(key, out var client)) - { - client = new HttpClient() - { - BaseAddress = new Uri(url) - }; - - _httpClients.TryAdd(key, client); - } - - return client; - } - - private HttpRequestMessage GetRequestMessage(HttpRequestOptions options, HttpMethod method) - { - string url = options.Url; - var uriAddress = new Uri(url); - string userInfo = uriAddress.UserInfo; - if (!string.IsNullOrWhiteSpace(userInfo)) - { - _logger.LogWarning("Found userInfo in url: {0} ... url: {1}", userInfo, url); - url = url.Replace(userInfo + '@', string.Empty, StringComparison.Ordinal); - } - - var request = new HttpRequestMessage(method, url); - - foreach (var header in options.RequestHeaders) - { - request.Headers.TryAddWithoutValidation(header.Key, header.Value); - } - - if (options.EnableDefaultUserAgent - && !request.Headers.TryGetValues(HeaderNames.UserAgent, out _)) - { - request.Headers.Add(HeaderNames.UserAgent, _appHost.ApplicationUserAgent); - } - - switch (options.DecompressionMethod) - { - case CompressionMethods.Deflate | CompressionMethods.Gzip: - request.Headers.Add(HeaderNames.AcceptEncoding, new[] { "gzip", "deflate" }); - break; - case CompressionMethods.Deflate: - request.Headers.Add(HeaderNames.AcceptEncoding, "deflate"); - break; - case CompressionMethods.Gzip: - request.Headers.Add(HeaderNames.AcceptEncoding, "gzip"); - break; - default: - break; - } - - if (options.EnableKeepAlive) - { - request.Headers.Add(HeaderNames.Connection, "Keep-Alive"); - } - - // request.Headers.Add(HeaderNames.CacheControl, "no-cache"); - - /* - if (!string.IsNullOrWhiteSpace(userInfo)) - { - var parts = userInfo.Split(':'); - if (parts.Length == 2) - { - request.Headers.Add(HeaderNames., GetCredential(url, parts[0], parts[1]); - } - } - */ - - return request; - } - - /// - /// Gets the response internal. - /// - /// The options. - /// Task{HttpResponseInfo}. - public Task GetResponse(HttpRequestOptions options) - => SendAsync(options, HttpMethod.Get); - - /// - /// Performs a GET request and returns the resulting stream. - /// - /// The options. - /// Task{Stream}. - public async Task Get(HttpRequestOptions options) - { - var response = await GetResponse(options).ConfigureAwait(false); - return response.Content; - } - - /// - /// send as an asynchronous operation. - /// - /// The options. - /// The HTTP method. - /// Task{HttpResponseInfo}. - public Task SendAsync(HttpRequestOptions options, string httpMethod) - => SendAsync(options, new HttpMethod(httpMethod)); - - /// - /// send as an asynchronous operation. - /// - /// The options. - /// The HTTP method. - /// Task{HttpResponseInfo}. - public async Task SendAsync(HttpRequestOptions options, HttpMethod httpMethod) - { - if (options.CacheMode == CacheMode.None) - { - return await SendAsyncInternal(options, httpMethod).ConfigureAwait(false); - } - - var url = options.Url; - var urlHash = url.ToUpperInvariant().GetMD5().ToString("N", CultureInfo.InvariantCulture); - - var responseCachePath = Path.Combine(_appPaths.CachePath, "httpclient", urlHash); - - var response = GetCachedResponse(responseCachePath, options.CacheLength, url); - if (response != null) - { - return response; - } - - response = await SendAsyncInternal(options, httpMethod).ConfigureAwait(false); - - if (response.StatusCode == HttpStatusCode.OK) - { - await CacheResponse(response, responseCachePath).ConfigureAwait(false); - } - - return response; - } - - private HttpResponseInfo GetCachedResponse(string responseCachePath, TimeSpan cacheLength, string url) - { - if (File.Exists(responseCachePath) - && _fileSystem.GetLastWriteTimeUtc(responseCachePath).Add(cacheLength) > DateTime.UtcNow) - { - var stream = new FileStream(responseCachePath, FileMode.Open, FileAccess.Read, FileShare.Read, IODefaults.FileStreamBufferSize, true); - - return new HttpResponseInfo - { - ResponseUrl = url, - Content = stream, - StatusCode = HttpStatusCode.OK, - ContentLength = stream.Length - }; - } - - return null; - } - - private async Task CacheResponse(HttpResponseInfo response, string responseCachePath) - { - Directory.CreateDirectory(Path.GetDirectoryName(responseCachePath)); - - using (var fileStream = new FileStream( - responseCachePath, - FileMode.Create, - FileAccess.Write, - FileShare.None, - IODefaults.FileStreamBufferSize, - true)) - { - await response.Content.CopyToAsync(fileStream).ConfigureAwait(false); - - response.Content.Position = 0; - } - } - - private async Task SendAsyncInternal(HttpRequestOptions options, HttpMethod httpMethod) - { - ValidateParams(options); - - options.CancellationToken.ThrowIfCancellationRequested(); - - var client = GetHttpClient(options.Url); - - var httpWebRequest = GetRequestMessage(options, httpMethod); - - if (!string.IsNullOrEmpty(options.RequestContent) - || httpMethod == HttpMethod.Post) - { - if (options.RequestContent != null) - { - httpWebRequest.Content = new StringContent( - options.RequestContent, - null, - options.RequestContentType); - } - else - { - httpWebRequest.Content = new ByteArrayContent(Array.Empty()); - } - } - - options.CancellationToken.ThrowIfCancellationRequested(); - - var response = await client.SendAsync( - httpWebRequest, - options.BufferContent || options.CacheMode == CacheMode.Unconditional ? HttpCompletionOption.ResponseContentRead : HttpCompletionOption.ResponseHeadersRead, - options.CancellationToken).ConfigureAwait(false); - - await EnsureSuccessStatusCode(response, options).ConfigureAwait(false); - - options.CancellationToken.ThrowIfCancellationRequested(); - - var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); - return new HttpResponseInfo(response.Headers, response.Content.Headers) - { - Content = stream, - StatusCode = response.StatusCode, - ContentType = response.Content.Headers.ContentType?.MediaType, - ContentLength = response.Content.Headers.ContentLength, - ResponseUrl = response.Content.Headers.ContentLocation?.ToString() - }; - } - - /// - public Task Post(HttpRequestOptions options) - => SendAsync(options, HttpMethod.Post); - - private void ValidateParams(HttpRequestOptions options) - { - if (string.IsNullOrEmpty(options.Url)) - { - throw new ArgumentNullException(nameof(options)); - } - } - - /// - /// Gets the host from URL. - /// - /// The URL. - /// System.String. - private static string GetHostFromUrl(string url) - { - var index = url.IndexOf("://", StringComparison.OrdinalIgnoreCase); - - if (index != -1) - { - url = url.Substring(index + 3); - var host = url.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault(); - - if (!string.IsNullOrWhiteSpace(host)) - { - return host; - } - } - - return url; - } - - private async Task EnsureSuccessStatusCode(HttpResponseMessage response, HttpRequestOptions options) - { - if (response.IsSuccessStatusCode) - { - return; - } - - if (options.LogErrorResponseBody) - { - string msg = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - _logger.LogError("HTTP request failed with message: {Message}", msg); - } - - throw new HttpException(response.ReasonPhrase) - { - StatusCode = response.StatusCode - }; - } - } -} diff --git a/MediaBrowser.Common/Net/IHttpClient.cs b/MediaBrowser.Common/Net/IHttpClient.cs deleted file mode 100644 index 534e22edd..000000000 --- a/MediaBrowser.Common/Net/IHttpClient.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.IO; -using System.Net.Http; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Net -{ - /// - /// Interface IHttpClient. - /// - public interface IHttpClient - { - /// - /// Gets the response. - /// - /// The options. - /// Task{HttpResponseInfo}. - Task GetResponse(HttpRequestOptions options); - - /// - /// Gets the specified options. - /// - /// The options. - /// Task{Stream}. - Task Get(HttpRequestOptions options); - - /// - /// Warning: Deprecated function, - /// use 'Task{HttpResponseInfo} SendAsync(HttpRequestOptions options, HttpMethod httpMethod);' instead - /// Sends the asynchronous. - /// - /// The options. - /// The HTTP method. - /// Task{HttpResponseInfo}. - [Obsolete("Use 'Task{HttpResponseInfo} SendAsync(HttpRequestOptions options, HttpMethod httpMethod);' instead")] - Task SendAsync(HttpRequestOptions options, string httpMethod); - - /// - /// Sends the asynchronous. - /// - /// The options. - /// The HTTP method. - /// Task{HttpResponseInfo}. - Task SendAsync(HttpRequestOptions options, HttpMethod httpMethod); - - /// - /// Posts the specified options. - /// - /// The options. - /// Task{HttpResponseInfo}. - Task Post(HttpRequestOptions options); - } -} -- cgit v1.2.3 From e1d0b430d95402c694f1686ba6837d27753d6454 Mon Sep 17 00:00:00 2001 From: crobibero Date: Tue, 1 Sep 2020 07:51:55 -0600 Subject: Remove HttpRequestOptions --- .../LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs | 9 +- .../LiveTv/TunerHosts/SharedHttpStream.cs | 13 --- MediaBrowser.Common/Net/HttpRequestOptions.cs | 105 --------------------- 3 files changed, 1 insertion(+), 126 deletions(-) delete mode 100644 MediaBrowser.Common/Net/HttpRequestOptions.cs (limited to 'MediaBrowser.Common/Net') diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs index 1873d1789..28e30fac8 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs @@ -71,15 +71,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun { var model = await GetModelInfo(info, false, cancellationToken).ConfigureAwait(false); - var options = new HttpRequestOptions - { - Url = model.LineupURL, - CancellationToken = cancellationToken, - BufferContent = false - }; - using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(model.LineupURL, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - await using var stream = await response.Content.ReadAsStreamAsync(); + await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); var lineup = await JsonSerializer.DeserializeAsync>(stream, cancellationToken: cancellationToken) .ConfigureAwait(false) ?? new List(); diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs index 7a16704a9..53c81ecd7 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs @@ -55,19 +55,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts var typeName = GetType().Name; Logger.LogInformation("Opening " + typeName + " Live stream from {0}", url); - var httpRequestOptions = new HttpRequestOptions - { - Url = url, - CancellationToken = CancellationToken.None, - BufferContent = false, - DecompressionMethod = CompressionMethods.None - }; - - foreach (var header in mediaSource.RequiredHttpHeaders) - { - httpRequestOptions.RequestHeaders[header.Key] = header.Value; - } - using var response = await _httpClientFactory.CreateClient(NamedClient.Default) .GetAsync(url, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None) .ConfigureAwait(false); diff --git a/MediaBrowser.Common/Net/HttpRequestOptions.cs b/MediaBrowser.Common/Net/HttpRequestOptions.cs deleted file mode 100644 index 347fc9833..000000000 --- a/MediaBrowser.Common/Net/HttpRequestOptions.cs +++ /dev/null @@ -1,105 +0,0 @@ -#pragma warning disable CS1591 - -using System; -using System.Collections.Generic; -using System.Threading; -using Microsoft.Net.Http.Headers; - -namespace MediaBrowser.Common.Net -{ - /// - /// Class HttpRequestOptions. - /// - public class HttpRequestOptions - { - /// - /// Initializes a new instance of the class. - /// - public HttpRequestOptions() - { - RequestHeaders = new Dictionary(StringComparer.OrdinalIgnoreCase); - - CacheMode = CacheMode.None; - DecompressionMethod = CompressionMethods.Deflate; - } - - /// - /// Gets or sets the URL. - /// - /// The URL. - public string Url { get; set; } - - public CompressionMethods DecompressionMethod { get; set; } - - /// - /// Gets or sets the accept header. - /// - /// The accept header. - public string AcceptHeader - { - get => GetHeaderValue(HeaderNames.Accept); - set => RequestHeaders[HeaderNames.Accept] = value; - } - - /// - /// Gets or sets the cancellation token. - /// - /// The cancellation token. - public CancellationToken CancellationToken { get; set; } - - /// - /// Gets or sets the user agent. - /// - /// The user agent. - public string UserAgent - { - get => GetHeaderValue(HeaderNames.UserAgent); - set => RequestHeaders[HeaderNames.UserAgent] = value; - } - - /// - /// Gets or sets the referrer. - /// - /// The referrer. - public string Referer - { - get => GetHeaderValue(HeaderNames.Referer); - set => RequestHeaders[HeaderNames.Referer] = value; - } - - /// - /// Gets or sets the host. - /// - /// The host. - public string Host - { - get => GetHeaderValue(HeaderNames.Host); - set => RequestHeaders[HeaderNames.Host] = value; - } - - public Dictionary RequestHeaders { get; private set; } - - public string RequestContentType { get; set; } - - public string RequestContent { get; set; } - - public bool BufferContent { get; set; } - - public bool LogErrorResponseBody { get; set; } - - public bool EnableKeepAlive { get; set; } - - public CacheMode CacheMode { get; set; } - - public TimeSpan CacheLength { get; set; } - - public bool EnableDefaultUserAgent { get; set; } - - private string GetHeaderValue(string name) - { - RequestHeaders.TryGetValue(name, out var value); - - return value; - } - } -} -- cgit v1.2.3 From 39041019e72709e938c789f495286a3fd1ce24fd Mon Sep 17 00:00:00 2001 From: crobibero Date: Tue, 1 Sep 2020 07:53:57 -0600 Subject: Remove CacheMode, CompressionMethods, HttpResponseInfo --- MediaBrowser.Common/Net/CacheMode.cs | 11 ---- MediaBrowser.Common/Net/CompressionMethods.cs | 15 ----- MediaBrowser.Common/Net/HttpResponseInfo.cs | 80 --------------------------- 3 files changed, 106 deletions(-) delete mode 100644 MediaBrowser.Common/Net/CacheMode.cs delete mode 100644 MediaBrowser.Common/Net/CompressionMethods.cs delete mode 100644 MediaBrowser.Common/Net/HttpResponseInfo.cs (limited to 'MediaBrowser.Common/Net') diff --git a/MediaBrowser.Common/Net/CacheMode.cs b/MediaBrowser.Common/Net/CacheMode.cs deleted file mode 100644 index 78fa3bf9b..000000000 --- a/MediaBrowser.Common/Net/CacheMode.cs +++ /dev/null @@ -1,11 +0,0 @@ -#pragma warning disable CS1591 -#pragma warning disable SA1602 - -namespace MediaBrowser.Common.Net -{ - public enum CacheMode - { - None = 0, - Unconditional = 1 - } -} diff --git a/MediaBrowser.Common/Net/CompressionMethods.cs b/MediaBrowser.Common/Net/CompressionMethods.cs deleted file mode 100644 index 39b72609f..000000000 --- a/MediaBrowser.Common/Net/CompressionMethods.cs +++ /dev/null @@ -1,15 +0,0 @@ -#pragma warning disable CS1591 -#pragma warning disable SA1602 - -using System; - -namespace MediaBrowser.Common.Net -{ - [Flags] - public enum CompressionMethods - { - None = 0b00000001, - Deflate = 0b00000010, - Gzip = 0b00000100 - } -} diff --git a/MediaBrowser.Common/Net/HttpResponseInfo.cs b/MediaBrowser.Common/Net/HttpResponseInfo.cs deleted file mode 100644 index d4fee6c78..000000000 --- a/MediaBrowser.Common/Net/HttpResponseInfo.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.IO; -using System.Net; -using System.Net.Http.Headers; - -namespace MediaBrowser.Common.Net -{ - /// - /// Class HttpResponseInfo. - /// - public sealed class HttpResponseInfo : IDisposable - { -#pragma warning disable CS1591 - public HttpResponseInfo() - { - } - - public HttpResponseInfo(HttpResponseHeaders headers, HttpContentHeaders contentHeader) - { - Headers = headers; - ContentHeaders = contentHeader; - } - -#pragma warning restore CS1591 - - /// - /// Gets or sets the type of the content. - /// - /// The type of the content. - public string ContentType { get; set; } - - /// - /// Gets or sets the response URL. - /// - /// The response URL. - public string ResponseUrl { get; set; } - - /// - /// Gets or sets the content. - /// - /// The content. - public Stream Content { get; set; } - - /// - /// Gets or sets the status code. - /// - /// The status code. - public HttpStatusCode StatusCode { get; set; } - - /// - /// Gets or sets the temp file path. - /// - /// The temp file path. - public string TempFilePath { get; set; } - - /// - /// Gets or sets the length of the content. - /// - /// The length of the content. - public long? ContentLength { get; set; } - - /// - /// Gets or sets the headers. - /// - /// The headers. - public HttpResponseHeaders Headers { get; set; } - - /// - /// Gets or sets the content headers. - /// - /// The content headers. - public HttpContentHeaders ContentHeaders { get; set; } - - /// - public void Dispose() - { - // backwards compatibility - } - } -} -- cgit v1.2.3