diff --git a/Agent/Interfaces/IUpdater.cs b/Agent/Interfaces/IUpdater.cs index e9eda814..3804a7af 100644 --- a/Agent/Interfaces/IUpdater.cs +++ b/Agent/Interfaces/IUpdater.cs @@ -3,7 +3,7 @@ using System.Threading.Tasks; namespace Remotely.Agent.Interfaces { - public interface IUpdater : IDisposable + public interface IUpdater { Task BeginChecking(); Task CheckForUpdates(); diff --git a/Agent/Program.cs b/Agent/Program.cs index a08adc66..3e24c5dc 100644 --- a/Agent/Program.cs +++ b/Agent/Program.cs @@ -55,7 +55,7 @@ namespace Remotely.Agent serviceCollection.AddScoped(); serviceCollection.AddScoped(); serviceCollection.AddScoped(); - serviceCollection.AddScoped(); + serviceCollection.AddScoped(); if (EnvironmentHelper.IsWindows) { diff --git a/Agent/Services/UpdateDownloader.cs b/Agent/Services/UpdateDownloader.cs new file mode 100644 index 00000000..ebc22b38 --- /dev/null +++ b/Agent/Services/UpdateDownloader.cs @@ -0,0 +1,36 @@ +using System; +using System.IO; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Remotely.Agent.Services +{ + public interface IUpdateDownloader + { + Task DownloadFile(string address, string fileName); + } + + public class UpdateDownloader : IUpdateDownloader + { + private readonly TimeSpan _timeout = TimeSpan.FromHours(6); + private readonly IHttpClientFactory _clientFactory; + + public UpdateDownloader(IHttpClientFactory clientFactory) + { + _clientFactory = clientFactory; + } + + public async Task DownloadFile(string downloadUrl, string filePath) + { + using var client = _clientFactory.CreateClient(); + client.Timeout = _timeout; + + using var downloadStream = await client.GetStreamAsync(downloadUrl); + using var fileStream = new FileStream(filePath, FileMode.Create); + + await downloadStream.CopyToAsync(fileStream); + } + } + +} \ No newline at end of file diff --git a/Agent/Services/UpdaterLinux.cs b/Agent/Services/UpdaterLinux.cs index 8e95c058..27dc3916 100644 --- a/Agent/Services/UpdaterLinux.cs +++ b/Agent/Services/UpdaterLinux.cs @@ -20,18 +20,17 @@ namespace Remotely.Agent.Services { private readonly SemaphoreSlim _checkForUpdatesLock = new(1, 1); private readonly ConfigService _configService; - private readonly IWebClientEx _webClientEx; + private readonly IUpdateDownloader _updateDownloader; private readonly IHttpClientFactory _httpClientFactory; private readonly SemaphoreSlim _installLatestVersionLock = new(1, 1); - private DateTimeOffset _lastUpdateFailure; private readonly System.Timers.Timer _updateTimer = new(TimeSpan.FromHours(6).TotalMilliseconds); + private DateTimeOffset _lastUpdateFailure; - public UpdaterLinux(ConfigService configService, IWebClientEx webClientEx, IHttpClientFactory httpClientFactory) + public UpdaterLinux(ConfigService configService, IUpdateDownloader updateDownloader, IHttpClientFactory httpClientFactory) { _configService = configService; - _webClientEx = webClientEx; + _updateDownloader = updateDownloader; _httpClientFactory = httpClientFactory; - _webClientEx.SetRequestTimeout((int)_updateTimer.Interval); } @@ -49,10 +48,13 @@ namespace Remotely.Agent.Services public async Task CheckForUpdates() { + if (!await _checkForUpdatesLock.WaitAsync(0)) + { + return; + } + try { - await _checkForUpdatesLock.WaitAsync(); - if (EnvironmentHelper.IsDebug) { return; @@ -111,12 +113,6 @@ namespace Remotely.Agent.Services } } - public void Dispose() - { - _webClientEx?.Dispose(); - GC.SuppressFinalize(this); - } - public async Task InstallLatestVersion() { try @@ -148,12 +144,12 @@ namespace Remotely.Agent.Services throw new PlatformNotSupportedException(); } - await _webClientEx.DownloadFileTaskAsync( - serverUrl + $"/API/ClientDownloads/{connectionInfo.OrganizationID}/{platform}", + await _updateDownloader.DownloadFile( + $"{serverUrl}/API/ClientDownloads/{connectionInfo.OrganizationID}/{platform}", installerPath); - await _webClientEx.DownloadFileTaskAsync( - serverUrl + $"/API/AgentUpdate/DownloadPackage/linux/{downloadId}", + await _updateDownloader.DownloadFile( + $"{serverUrl}/API/AgentUpdate/DownloadPackage/linux/{downloadId}", zipPath); using var httpClient = _httpClientFactory.CreateClient(); diff --git a/Agent/Services/UpdaterMac.cs b/Agent/Services/UpdaterMac.cs index b48c1edd..981f1449 100644 --- a/Agent/Services/UpdaterMac.cs +++ b/Agent/Services/UpdaterMac.cs @@ -22,17 +22,16 @@ namespace Remotely.Agent.Services private readonly SemaphoreSlim _checkForUpdatesLock = new(1, 1); private readonly ConfigService _configService; private readonly IHttpClientFactory _httpClientFactory; - private readonly IWebClientEx _webClientEx; + private readonly IUpdateDownloader _updateDownloader; private readonly SemaphoreSlim _installLatestVersionLock = new(1, 1); private DateTimeOffset _lastUpdateFailure; private readonly System.Timers.Timer _updateTimer = new(TimeSpan.FromHours(6).TotalMilliseconds); - public UpdaterMac(ConfigService configService, IWebClientEx webClientEx, IHttpClientFactory httpClientFactory) + public UpdaterMac(ConfigService configService, IUpdateDownloader updateDownloader, IHttpClientFactory httpClientFactory) { _configService = configService; _httpClientFactory = httpClientFactory; - _webClientEx = webClientEx; - _webClientEx.SetRequestTimeout((int)_updateTimer.Interval); + _updateDownloader = updateDownloader; } @@ -50,10 +49,13 @@ namespace Remotely.Agent.Services public async Task CheckForUpdates() { + if (!await _checkForUpdatesLock.WaitAsync(0)) + { + return; + } + try { - await _checkForUpdatesLock.WaitAsync(); - if (EnvironmentHelper.IsDebug) { return; @@ -112,12 +114,6 @@ namespace Remotely.Agent.Services } } - public void Dispose() - { - _webClientEx?.Dispose(); - GC.SuppressFinalize(this); - } - public async Task InstallLatestVersion() { try @@ -134,12 +130,12 @@ namespace Remotely.Agent.Services var installerPath = Path.Combine(Path.GetTempPath(), "RemotelyUpdate.sh"); - await _webClientEx.DownloadFileTaskAsync( - serverUrl + $"/API/ClientDownloads/{connectionInfo.OrganizationID}/MacOSInstaller-{_achitecture}", + await _updateDownloader.DownloadFile( + $"{serverUrl}/API/ClientDownloads/{connectionInfo.OrganizationID}/MacOSInstaller-{_achitecture}", installerPath); - await _webClientEx.DownloadFileTaskAsync( - serverUrl + $"/API/AgentUpdate/DownloadPackage/macos-{_achitecture}/{downloadId}", + await _updateDownloader.DownloadFile( + $"{serverUrl}/API/AgentUpdate/DownloadPackage/macos-{_achitecture}/{downloadId}", zipPath); using var httpClient = _httpClientFactory.CreateClient(); diff --git a/Agent/Services/UpdaterWin.cs b/Agent/Services/UpdaterWin.cs index 1d369f8a..818d3aa0 100644 --- a/Agent/Services/UpdaterWin.cs +++ b/Agent/Services/UpdaterWin.cs @@ -15,19 +15,18 @@ namespace Remotely.Agent.Services { private readonly SemaphoreSlim _checkForUpdatesLock = new(1, 1); private readonly ConfigService _configService; - private readonly IWebClientEx _webClientEx; + private readonly IUpdateDownloader _updateDownloader; private readonly IHttpClientFactory _httpClientFactory; private readonly SemaphoreSlim _installLatestVersionLock = new(1, 1); private readonly System.Timers.Timer _updateTimer = new(TimeSpan.FromHours(6).TotalMilliseconds); private DateTimeOffset _lastUpdateFailure; - public UpdaterWin(ConfigService configService, IWebClientEx webClientEx, IHttpClientFactory httpClientFactory) + public UpdaterWin(ConfigService configService, IUpdateDownloader updateDownloader, IHttpClientFactory httpClientFactory) { _configService = configService; - _webClientEx = webClientEx; + _updateDownloader = updateDownloader; _httpClientFactory = httpClientFactory; - _webClientEx.SetRequestTimeout((int)_updateTimer.Interval); } public async Task BeginChecking() @@ -44,9 +43,13 @@ namespace Remotely.Agent.Services public async Task CheckForUpdates() { + if (!await _checkForUpdatesLock.WaitAsync(0)) + { + return; + } + try { - await _checkForUpdatesLock.WaitAsync(); if (EnvironmentHelper.IsDebug) { @@ -107,12 +110,6 @@ namespace Remotely.Agent.Services } } - public void Dispose() - { - _webClientEx?.Dispose(); - GC.SuppressFinalize(this); - } - public async Task InstallLatestVersion() { try @@ -130,12 +127,12 @@ namespace Remotely.Agent.Services var installerPath = Path.Combine(Path.GetTempPath(), "Remotely_Installer.exe"); var platform = Environment.Is64BitOperatingSystem ? "x64" : "x86"; - await _webClientEx.DownloadFileTaskAsync( - serverUrl + $"/Content/Remotely_Installer.exe", + await _updateDownloader.DownloadFile( + $"{serverUrl}/Content/Remotely_Installer.exe", installerPath); - await _webClientEx.DownloadFileTaskAsync( - serverUrl + $"/api/AgentUpdate/DownloadPackage/win-{platform}/{downloadId}", + await _updateDownloader.DownloadFile( + $"{serverUrl}/api/AgentUpdate/DownloadPackage/win-{platform}/{downloadId}", zipPath); using var httpClient = _httpClientFactory.CreateClient(); diff --git a/Agent/Services/WebClientEx.cs b/Agent/Services/WebClientEx.cs deleted file mode 100644 index 6c5d0c77..00000000 --- a/Agent/Services/WebClientEx.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Net; -using System.Threading.Tasks; - -namespace Remotely.Agent.Services -{ - public interface IWebClientEx : IDisposable - { - void SetRequestTimeout(int requestTimeoutMs); - Task DownloadFileTaskAsync(string address, string fileName); - } - - public class WebClientEx : WebClient, IWebClientEx - { - private int _requestTimeout; - - public void SetRequestTimeout(int requestTimeoutMs) - { - _requestTimeout = requestTimeoutMs; - } - - protected override WebRequest GetWebRequest(Uri uri) - { - WebRequest webRequest = base.GetWebRequest(uri); - webRequest.Timeout = _requestTimeout; - return webRequest; - } - } - -} \ No newline at end of file