diff --git a/MareSynchronos/Plugin.cs b/MareSynchronos/Plugin.cs index f5b7c8c..1be7da3 100644 --- a/MareSynchronos/Plugin.cs +++ b/MareSynchronos/Plugin.cs @@ -27,6 +27,9 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using NReco.Logging.File; +using System.Net.Http.Headers; +using System.Net.Http; +using System.Reflection; namespace MareSynchronos; @@ -148,6 +151,13 @@ public sealed class Plugin : IDalamudPlugin collection.AddSingleton((s) => new NotificationService(s.GetRequiredService>(), s.GetRequiredService(), s.GetRequiredService(), notificationManager, chatGui, s.GetRequiredService())); + collection.AddSingleton((s) => + { + var httpClient = new HttpClient(); + var ver = Assembly.GetExecutingAssembly().GetName().Version; + httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("MareSynchronos", ver!.Major + "." + ver!.Minor + "." + ver!.Build)); + return httpClient; + }); collection.AddSingleton((s) => new MareConfigService(pluginInterface.ConfigDirectory.FullName)); collection.AddSingleton((s) => new ServerConfigService(pluginInterface.ConfigDirectory.FullName)); collection.AddSingleton((s) => new NotesConfigService(pluginInterface.ConfigDirectory.FullName)); diff --git a/MareSynchronos/Services/ServerConfiguration/ServerConfigurationManager.cs b/MareSynchronos/Services/ServerConfiguration/ServerConfigurationManager.cs index 615e200..56c90de 100644 --- a/MareSynchronos/Services/ServerConfiguration/ServerConfigurationManager.cs +++ b/MareSynchronos/Services/ServerConfiguration/ServerConfigurationManager.cs @@ -18,6 +18,7 @@ public class ServerConfigurationManager private readonly ServerConfigService _configService; private readonly DalamudUtilService _dalamudUtil; private readonly MareConfigService _mareConfigService; + private readonly HttpClient _httpClient; private readonly ILogger _logger; private readonly MareMediator _mareMediator; private readonly NotesConfigService _notesConfig; @@ -25,8 +26,7 @@ public class ServerConfigurationManager public ServerConfigurationManager(ILogger logger, ServerConfigService configService, ServerTagConfigService serverTagConfig, NotesConfigService notesConfig, DalamudUtilService dalamudUtil, - MareConfigService mareConfigService, - MareMediator mareMediator) + MareConfigService mareConfigService, HttpClient httpClient, MareMediator mareMediator) { _logger = logger; _configService = configService; @@ -34,6 +34,7 @@ public class ServerConfigurationManager _notesConfig = notesConfig; _dalamudUtil = dalamudUtil; _mareConfigService = mareConfigService; + _httpClient = httpClient; _mareMediator = mareMediator; EnsureMainExists(); } @@ -489,13 +490,12 @@ public class ServerConfigurationManager public async Task> GetUIDsWithDiscordToken(string serverUri, string token) { - using HttpClient client = new HttpClient(); try { var baseUri = serverUri.Replace("wss://", "https://").Replace("ws://", "http://"); var oauthCheckUri = MareAuth.GetUIDsFullPath(new Uri(baseUri)); - client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); - var response = await client.GetAsync(oauthCheckUri).ConfigureAwait(false); + _httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); + var response = await _httpClient.GetAsync(oauthCheckUri).ConfigureAwait(false); var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); return await JsonSerializer.DeserializeAsync>(responseStream).ConfigureAwait(false) ?? []; } @@ -508,12 +508,11 @@ public class ServerConfigurationManager public async Task CheckDiscordOAuth(string serverUri) { - using HttpClient client = new HttpClient(); try { var baseUri = serverUri.Replace("wss://", "https://").Replace("ws://", "http://"); var oauthCheckUri = MareAuth.GetDiscordOAuthEndpointFullPath(new Uri(baseUri)); - var response = await client.GetFromJsonAsync(oauthCheckUri).ConfigureAwait(false); + var response = await _httpClient.GetFromJsonAsync(oauthCheckUri).ConfigureAwait(false); return response; } catch (Exception ex) @@ -529,13 +528,14 @@ public class ServerConfigurationManager Util.OpenLink(discordAuthUri.ToString() + "?sessionId=" + sessionId); string? discordToken = null; - using HttpClient client = new HttpClient(); - client.Timeout = TimeSpan.FromSeconds(60); + using CancellationTokenSource timeOutCts = new(); + timeOutCts.CancelAfter(TimeSpan.FromSeconds(60)); + using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(timeOutCts.Token, token); try { var baseUri = serverUri.Replace("wss://", "https://").Replace("ws://", "http://"); var oauthCheckUri = MareAuth.GetDiscordOAuthTokenFullPath(new Uri(baseUri), sessionId); - var response = await client.GetAsync(oauthCheckUri, token).ConfigureAwait(false); + var response = await _httpClient.GetAsync(oauthCheckUri, linkedCts.Token).ConfigureAwait(false); discordToken = await response.Content.ReadAsStringAsync().ConfigureAwait(false); } catch (Exception ex) diff --git a/MareSynchronos/UI/SettingsUi.cs b/MareSynchronos/UI/SettingsUi.cs index 4ed19d7..853fe70 100644 --- a/MareSynchronos/UI/SettingsUi.cs +++ b/MareSynchronos/UI/SettingsUi.cs @@ -26,6 +26,7 @@ using Microsoft.Extensions.Logging; using System.Collections.Concurrent; using System.Diagnostics; using System.Globalization; +using System.Net.Http.Headers; using System.Net.Http.Json; using System.Numerics; using System.Text; @@ -40,6 +41,7 @@ public class SettingsUi : WindowMediatorSubscriberBase private readonly MareConfigService _configService; private readonly ConcurrentDictionary> _currentDownloads = new(); private readonly DalamudUtilService _dalamudUtilService; + private readonly HttpClient _httpClient; private readonly FileCacheManager _fileCacheManager; private readonly FileCompactor _fileCompactor; private readonly FileUploadManager _fileTransferManager; @@ -78,7 +80,7 @@ public class SettingsUi : WindowMediatorSubscriberBase FileCacheManager fileCacheManager, FileCompactor fileCompactor, ApiController apiController, IpcManager ipcManager, CacheMonitor cacheMonitor, - DalamudUtilService dalamudUtilService) : base(logger, mediator, "Mare Synchronos Settings", performanceCollector) + DalamudUtilService dalamudUtilService, HttpClient httpClient) : base(logger, mediator, "Mare Synchronos Settings", performanceCollector) { _configService = configService; _mareCharaFileManager = mareCharaFileManager; @@ -93,6 +95,7 @@ public class SettingsUi : WindowMediatorSubscriberBase _ipcManager = ipcManager; _cacheMonitor = cacheMonitor; _dalamudUtilService = dalamudUtilService; + _httpClient = httpClient; _fileCompactor = fileCompactor; _uiShared = uiShared; AllowClickthrough = false; @@ -1833,13 +1836,14 @@ public class SettingsUi : WindowMediatorSubscriberBase return (false, false, $"Failed to convert {failedConversions.Count} entries: " + string.Join(", ", failedConversions.Select(k => k.CharacterName))); } - using HttpClient client = new(); var baseUri = serverStorage.ServerUri.Replace("wss://", "https://").Replace("ws://", "http://"); var oauthCheckUri = MareAuth.GetUIDsBasedOnSecretKeyFullPath(new Uri(baseUri)); - client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", serverStorage.OAuthToken); - var requestContent = JsonContent.Create(secretKeyMapping.Select(k => k.Key).ToList()); - using var response = await client.PostAsync(oauthCheckUri, requestContent, token).ConfigureAwait(false); + HttpRequestMessage requestMessage = new(HttpMethod.Post, oauthCheckUri); + requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", serverStorage.OAuthToken); + requestMessage.Content = requestContent; + + using var response = await _httpClient.SendAsync(requestMessage, token).ConfigureAwait(false); Dictionary? secretKeyUidMapping = await JsonSerializer.DeserializeAsync> (await response.Content.ReadAsStreamAsync(token).ConfigureAwait(false), cancellationToken: token).ConfigureAwait(false); if (secretKeyUidMapping == null) diff --git a/MareSynchronos/WebAPI/Files/FileTransferOrchestrator.cs b/MareSynchronos/WebAPI/Files/FileTransferOrchestrator.cs index 26dc967..0968f0f 100644 --- a/MareSynchronos/WebAPI/Files/FileTransferOrchestrator.cs +++ b/MareSynchronos/WebAPI/Files/FileTransferOrchestrator.cs @@ -22,14 +22,11 @@ public class FileTransferOrchestrator : DisposableMediatorSubscriberBase private int CurrentlyUsedDownloadSlots => _availableDownloadSlots - _downloadSemaphore.CurrentCount; public FileTransferOrchestrator(ILogger logger, MareConfigService mareConfig, - MareMediator mediator, TokenProvider tokenProvider) : base(logger, mediator) + MareMediator mediator, TokenProvider tokenProvider, HttpClient httpClient) : base(logger, mediator) { _mareConfig = mareConfig; _tokenProvider = tokenProvider; - _httpClient = new() - { - Timeout = TimeSpan.FromSeconds(3000) - }; + _httpClient = httpClient; var ver = Assembly.GetExecutingAssembly().GetName().Version; _httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("MareSynchronos", ver!.Major + "." + ver!.Minor + "." + ver!.Build)); diff --git a/MareSynchronos/WebAPI/SignalR/TokenProvider.cs b/MareSynchronos/WebAPI/SignalR/TokenProvider.cs index 56c9c60..3acb889 100644 --- a/MareSynchronos/WebAPI/SignalR/TokenProvider.cs +++ b/MareSynchronos/WebAPI/SignalR/TokenProvider.cs @@ -20,14 +20,14 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber private readonly ServerConfigurationManager _serverManager; private readonly ConcurrentDictionary _tokenCache = new(); - public TokenProvider(ILogger logger, ServerConfigurationManager serverManager, DalamudUtilService dalamudUtil, MareMediator mareMediator) + public TokenProvider(ILogger logger, ServerConfigurationManager serverManager, DalamudUtilService dalamudUtil, MareMediator mareMediator, HttpClient httpClient) { _logger = logger; _serverManager = serverManager; _dalamudUtil = dalamudUtil; - _httpClient = new(); var ver = Assembly.GetExecutingAssembly().GetName().Version; Mediator = mareMediator; + _httpClient = httpClient; Mediator.Subscribe(this, (_) => { _lastJwtIdentifier = null; @@ -38,7 +38,6 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber _lastJwtIdentifier = null; _tokenCache.Clear(); }); - _httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("MareSynchronos", ver!.Major + "." + ver!.Minor + "." + ver!.Build)); } public MareMediator Mediator { get; } @@ -48,7 +47,6 @@ public sealed class TokenProvider : IDisposable, IMediatorSubscriber public void Dispose() { Mediator.UnsubscribeAll(this); - _httpClient.Dispose(); } public async Task GetNewToken(bool isRenewal, JwtIdentifier identifier, CancellationToken ct)