using System.Net; using System.Net.Http; using System.Net.Http.Headers; using Dalamud.Plugin.Internal; using Dalamud.Utility; namespace Dalamud.Networking.Http; /// /// A service to help build and manage HttpClients with some semblance of Happy Eyeballs (RFC 8305 - IPv4 fallback) /// awareness. /// [ServiceManager.BlockingEarlyLoadedService($"{nameof(PluginManager)} currently uses this.")] // ^ TODO: This seems unnecessary, remove the hard dependency at a later time. // Otherwise, if PM eventually marks this class as required, note that in the comment above. internal class HappyHttpClient : IInternalDisposableService { /// /// Initializes a new instance of the class. /// /// A service to talk to the Smileton Loporrits to build an HTTP Client aware of Happy Eyeballs. /// [ServiceManager.ServiceConstructor] private HappyHttpClient() { this.SharedHappyEyeballsCallback = new HappyEyeballsCallback(); this.SharedHttpClient = new HttpClient(new SocketsHttpHandler { AutomaticDecompression = DecompressionMethods.All, ConnectCallback = this.SharedHappyEyeballsCallback.ConnectCallback, }) { DefaultRequestHeaders = { UserAgent = { new ProductInfoHeaderValue("Dalamud", Util.AssemblyVersion), }, }, }; } /// /// Gets a meant to be shared across all (standard) requests made by the application, /// where custom configurations are not required. /// /// May or may not have been properly tested by the Loporrits. /// public HttpClient SharedHttpClient { get; } /// /// Gets a meant to be shared across any custom s that /// need to be made in other parts of the application. /// /// This should be used when shared callback state is desired across multiple clients, as sharing the SocketsHandler /// may lead to GC issues. /// public HappyEyeballsCallback SharedHappyEyeballsCallback { get; } /// void IInternalDisposableService.DisposeService() { this.SharedHttpClient.Dispose(); this.SharedHappyEyeballsCallback.Dispose(); GC.SuppressFinalize(this); } }