From eea676429b603c9a19e098b1a99c6c024af95ec7 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Thu, 30 Nov 2023 12:26:37 -0500 Subject: Use file-scoped namespaces in Jellyfin.Networking --- .../HappyEyeballs/HttpClientExtension.cs | 131 ++++++++++----------- 1 file changed, 65 insertions(+), 66 deletions(-) (limited to 'src/Jellyfin.Networking/HappyEyeballs/HttpClientExtension.cs') diff --git a/src/Jellyfin.Networking/HappyEyeballs/HttpClientExtension.cs b/src/Jellyfin.Networking/HappyEyeballs/HttpClientExtension.cs index d59e4e5e38..7d86434b81 100644 --- a/src/Jellyfin.Networking/HappyEyeballs/HttpClientExtension.cs +++ b/src/Jellyfin.Networking/HappyEyeballs/HttpClientExtension.cs @@ -30,91 +30,90 @@ using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; -namespace Jellyfin.Networking.HappyEyeballs +namespace Jellyfin.Networking.HappyEyeballs; + +/// +/// Defines the class. +/// +/// Implementation taken from https://github.com/ppy/osu-framework/pull/4191 . +/// +public static class HttpClientExtension { /// - /// Defines the class. - /// - /// Implementation taken from https://github.com/ppy/osu-framework/pull/4191 . + /// Gets or sets a value indicating whether the client should use IPv6. /// - public static class HttpClientExtension + public static bool UseIPv6 { get; set; } = true; + + /// + /// Implements the httpclient callback method. + /// + /// The instance. + /// The instance. + /// The http steam. + public static async ValueTask OnConnect(SocketsHttpConnectionContext context, CancellationToken cancellationToken) { - /// - /// Gets or sets a value indicating whether the client should use IPv6. - /// - public static bool UseIPv6 { get; set; } = true; - - /// - /// Implements the httpclient callback method. - /// - /// The instance. - /// The instance. - /// The http steam. - public static async ValueTask OnConnect(SocketsHttpConnectionContext context, CancellationToken cancellationToken) + if (!UseIPv6) { - if (!UseIPv6) - { - return await AttemptConnection(AddressFamily.InterNetwork, context, cancellationToken).ConfigureAwait(false); - } + return await AttemptConnection(AddressFamily.InterNetwork, context, cancellationToken).ConfigureAwait(false); + } - using var cancelIPv6 = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); - var tryConnectAsyncIPv6 = AttemptConnection(AddressFamily.InterNetworkV6, context, cancelIPv6.Token); + using var cancelIPv6 = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + var tryConnectAsyncIPv6 = AttemptConnection(AddressFamily.InterNetworkV6, context, cancelIPv6.Token); - // GetAwaiter().GetResult() is used instead of .Result as this results in improved exception handling. - // The tasks have already been completed. - // See https://github.com/dotnet/corefx/pull/29792/files#r189415885 for more details. - if (await Task.WhenAny(tryConnectAsyncIPv6, Task.Delay(200, cancelIPv6.Token)).ConfigureAwait(false) == tryConnectAsyncIPv6 && tryConnectAsyncIPv6.IsCompletedSuccessfully) + // GetAwaiter().GetResult() is used instead of .Result as this results in improved exception handling. + // The tasks have already been completed. + // See https://github.com/dotnet/corefx/pull/29792/files#r189415885 for more details. + if (await Task.WhenAny(tryConnectAsyncIPv6, Task.Delay(200, cancelIPv6.Token)).ConfigureAwait(false) == tryConnectAsyncIPv6 && tryConnectAsyncIPv6.IsCompletedSuccessfully) + { + await cancelIPv6.CancelAsync().ConfigureAwait(false); + return tryConnectAsyncIPv6.GetAwaiter().GetResult(); + } + + using var cancelIPv4 = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + var tryConnectAsyncIPv4 = AttemptConnection(AddressFamily.InterNetwork, context, cancelIPv4.Token); + + if (await Task.WhenAny(tryConnectAsyncIPv6, tryConnectAsyncIPv4).ConfigureAwait(false) == tryConnectAsyncIPv6) + { + if (tryConnectAsyncIPv6.IsCompletedSuccessfully) { - await cancelIPv6.CancelAsync().ConfigureAwait(false); + await cancelIPv4.CancelAsync().ConfigureAwait(false); return tryConnectAsyncIPv6.GetAwaiter().GetResult(); } - using var cancelIPv4 = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); - var tryConnectAsyncIPv4 = AttemptConnection(AddressFamily.InterNetwork, context, cancelIPv4.Token); - - if (await Task.WhenAny(tryConnectAsyncIPv6, tryConnectAsyncIPv4).ConfigureAwait(false) == tryConnectAsyncIPv6) + return tryConnectAsyncIPv4.GetAwaiter().GetResult(); + } + else + { + if (tryConnectAsyncIPv4.IsCompletedSuccessfully) { - if (tryConnectAsyncIPv6.IsCompletedSuccessfully) - { - await cancelIPv4.CancelAsync().ConfigureAwait(false); - return tryConnectAsyncIPv6.GetAwaiter().GetResult(); - } - + await cancelIPv6.CancelAsync().ConfigureAwait(false); return tryConnectAsyncIPv4.GetAwaiter().GetResult(); } - else - { - if (tryConnectAsyncIPv4.IsCompletedSuccessfully) - { - await cancelIPv6.CancelAsync().ConfigureAwait(false); - return tryConnectAsyncIPv4.GetAwaiter().GetResult(); - } - return tryConnectAsyncIPv6.GetAwaiter().GetResult(); - } + return tryConnectAsyncIPv6.GetAwaiter().GetResult(); } + } - private static async Task AttemptConnection(AddressFamily addressFamily, SocketsHttpConnectionContext context, CancellationToken cancellationToken) + private static async Task AttemptConnection(AddressFamily addressFamily, SocketsHttpConnectionContext context, CancellationToken cancellationToken) + { + // The following socket constructor will create a dual-mode socket on systems where IPV6 is available. + var socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp) { - // The following socket constructor will create a dual-mode socket on systems where IPV6 is available. - var socket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp) - { - // Turn off Nagle's algorithm since it degrades performance in most HttpClient scenarios. - NoDelay = true - }; + // Turn off Nagle's algorithm since it degrades performance in most HttpClient scenarios. + NoDelay = true + }; - try - { - await socket.ConnectAsync(context.DnsEndPoint, cancellationToken).ConfigureAwait(false); - // The stream should take the ownership of the underlying socket, - // closing it when it's disposed. - return new NetworkStream(socket, ownsSocket: true); - } - catch - { - socket.Dispose(); - throw; - } + try + { + await socket.ConnectAsync(context.DnsEndPoint, cancellationToken).ConfigureAwait(false); + // The stream should take the ownership of the underlying socket, + // closing it when it's disposed. + return new NetworkStream(socket, ownsSocket: true); + } + catch + { + socket.Dispose(); + throw; } } } -- cgit v1.2.3