diff --git a/LANCommander.SDK/Client.cs b/LANCommander.SDK/Client.cs index 8e298260..ec907dfd 100644 --- a/LANCommander.SDK/Client.cs +++ b/LANCommander.SDK/Client.cs @@ -86,9 +86,11 @@ namespace LANCommander.SDK if (!String.IsNullOrWhiteSpace(baseUrl)) { BaseUrl = new Uri(baseUrl); - ApiClient = new RestClient(BaseUrl); - - ApiClient.ThrowOnAnyError = true; + ApiClient = new RestClient(new RestClientOptions + { + BaseUrl = BaseUrl, + ThrowOnAnyError = true + }); } } @@ -102,42 +104,6 @@ namespace LANCommander.SDK return SemVersion.FromVersion(Assembly.GetExecutingAssembly().GetName().Version); } - private void ValidateVersion(IRestResponse response) - { - try - { - var version = GetCurrentVersion(); - var header = response.Headers.FirstOrDefault(h => h.Name == "X-API-Version"); - - if (response.IsSuccessful && header == null) - { - response.ErrorException = new ApiVersionMismatchException(version, null, $"The server is out of date and does not support client version {version}."); - - return; - } - - var apiVersion = SemVersion.Parse((string)header.Value, SemVersionStyles.Any); - - if (version.Major != apiVersion.Major || version.Minor != apiVersion.Minor) - { - switch (version.ComparePrecedenceTo(apiVersion)) - { - case -1: - response.ErrorException = new ApiVersionMismatchException(version, apiVersion, $"Your client (v{version}) is out of date and is not supported by the server (v{apiVersion})"); - break; - - case 1: - response.ErrorException = new ApiVersionMismatchException(version, apiVersion, $"Your client (v{version}) is on a version not supported by the server (v{apiVersion})"); - break; - } - } - } - catch (Exception ex) - { - Logger?.LogError(ex, "Could not validate API version"); - } - } - internal T PostRequest(string route, object body, bool ignoreVersion = false) { if (Token == null) @@ -149,11 +115,11 @@ namespace LANCommander.SDK .AddHeader("X-API-Version", GetCurrentVersion().ToString()); if (!ignoreVersion) - request.OnBeforeDeserialization += ValidateVersion; + request.Interceptors.Add(new VersionInterceptor()); var response = ApiClient.Post(request); - return response.Data; + return response; } internal T PostRequest(string route, bool ignoreVersion = false) @@ -166,11 +132,11 @@ namespace LANCommander.SDK .AddHeader("X-API-Version", GetCurrentVersion().ToString()); if (!ignoreVersion) - request.OnBeforeDeserialization += ValidateVersion; + request.Interceptors.Add(new VersionInterceptor()); var response = ApiClient.Post(request); - return response.Data; + return response; } internal async Task PostRequestAsync(string route, object body, bool ignoreVersion = false) @@ -184,7 +150,7 @@ namespace LANCommander.SDK .AddHeader("X-API-Version", GetCurrentVersion().ToString()); if (!ignoreVersion) - request.OnBeforeDeserialization += ValidateVersion; + request.Interceptors.Add(new VersionInterceptor()); var response = await ApiClient.PostAsync(request); @@ -201,7 +167,7 @@ namespace LANCommander.SDK .AddHeader("X-API-Version", GetCurrentVersion().ToString()); if (!ignoreVersion) - request.OnBeforeDeserialization += ValidateVersion; + request.Interceptors.Add(new VersionInterceptor()); var response = await ApiClient.PostAsync(request); @@ -218,11 +184,11 @@ namespace LANCommander.SDK .AddHeader("X-API-Version", GetCurrentVersion().ToString()); if (!ignoreVersion) - request.OnBeforeDeserialization += ValidateVersion; + request.Interceptors.Add(new VersionInterceptor()); var response = ApiClient.Get(request); - return response.Data; + return response; } internal async Task GetRequestAsync(string route, bool ignoreVersion = false) @@ -235,7 +201,7 @@ namespace LANCommander.SDK .AddHeader("X-API-Version", GetCurrentVersion().ToString()); if (!ignoreVersion) - request.OnBeforeDeserialization += ValidateVersion; + request.Interceptors.Add(new VersionInterceptor()); var response = await ApiClient.GetAsync(request); @@ -309,28 +275,28 @@ namespace LANCommander.SDK internal T UploadRequest(string route, string fileName, byte[] data, bool ignoreVersion = false) { - var request = new RestRequest(route, Method.POST) + var request = new RestRequest(route, Method.Post) .AddHeader("Authorization", $"Bearer {Token.AccessToken}") .AddHeader("X-API-Version", GetCurrentVersion().ToString()); if (!ignoreVersion) - request.OnBeforeDeserialization += ValidateVersion; + request.Interceptors.Add(new VersionInterceptor()); request.AddFile(fileName, data, fileName); var response = ApiClient.Post(request); - return response.Data; + return response; } internal async Task UploadRequestAsync(string route, string fileName, byte[] data, bool ignoreVersion = false) { - var request = new RestRequest(route, Method.POST) + var request = new RestRequest(route, Method.Post) .AddHeader("Authorization", $"Bearer {Token.AccessToken}") .AddHeader("X-API-Version", GetCurrentVersion().ToString()); if (!ignoreVersion) - request.OnBeforeDeserialization += ValidateVersion; + request.Interceptors.Add(new VersionInterceptor()); request.AddFile(fileName, data, fileName); @@ -341,7 +307,7 @@ namespace LANCommander.SDK public async Task AuthenticateAsync(string username, string password, bool ignoreVersion = false) { - var request = new RestRequest("/api/Auth", Method.POST); + var request = new RestRequest("/api/Auth", Method.Post); request.AddJsonBody(new AuthRequest() { @@ -350,7 +316,7 @@ namespace LANCommander.SDK }); if (!ignoreVersion) - request.OnBeforeDeserialization += ValidateVersion; + request.Interceptors.Add(new VersionInterceptor()); var response = await ApiClient.ExecuteAsync(request); @@ -387,7 +353,7 @@ namespace LANCommander.SDK public async Task LogoutAsync() { - await ApiClient.ExecuteAsync(new RestRequest("/api/Auth/Logout", Method.POST)); + await ApiClient.ExecuteAsync(new RestRequest("/api/Auth/Logout", Method.Post)); Connected = false; Token = null; @@ -395,7 +361,7 @@ namespace LANCommander.SDK public async Task RegisterAsync(string username, string password) { - var response = await ApiClient.ExecuteAsync(new RestRequest("/api/auth/register", Method.POST).AddJsonBody(new AuthRequest() + var response = await ApiClient.ExecuteAsync(new RestRequest("/api/auth/register", Method.Post).AddJsonBody(new AuthRequest() { UserName = username, Password = password @@ -429,7 +395,7 @@ namespace LANCommander.SDK public async Task PingAsync() { - var response = await ApiClient.ExecuteAsync(new RestRequest("/api/Ping", Method.GET)); + var response = await ApiClient.ExecuteAsync(new RestRequest("/api/Ping", Method.Get)); return response.StatusCode == HttpStatusCode.OK; } @@ -454,7 +420,7 @@ namespace LANCommander.SDK .AddHeader("X-API-Version", GetCurrentVersion().ToString()); if (!ignoreVersion) - request.OnBeforeDeserialization += ValidateVersion; + request.Interceptors.Add(new VersionInterceptor()); if (String.IsNullOrEmpty(token.AccessToken) || String.IsNullOrEmpty(token.RefreshToken)) { @@ -505,7 +471,7 @@ namespace LANCommander.SDK .AddHeader("X-API-Version", GetCurrentVersion().ToString()); if (!ignoreVersion) - request.OnBeforeDeserialization += ValidateVersion; + request.Interceptors.Add(new VersionInterceptor()); if (String.IsNullOrEmpty(token.AccessToken) || String.IsNullOrEmpty(token.RefreshToken)) { diff --git a/LANCommander.SDK/LANCommander.SDK.csproj b/LANCommander.SDK/LANCommander.SDK.csproj index 32bd8d94..d5a4c4ea 100644 --- a/LANCommander.SDK/LANCommander.SDK.csproj +++ b/LANCommander.SDK/LANCommander.SDK.csproj @@ -9,7 +9,7 @@ - + diff --git a/LANCommander.SDK/LauncherService.cs b/LANCommander.SDK/LauncherService.cs index fa5bbf25..86c53a10 100644 --- a/LANCommander.SDK/LauncherService.cs +++ b/LANCommander.SDK/LauncherService.cs @@ -39,7 +39,7 @@ namespace LANCommander.SDK { try { - var request = new RestRequest("/api/Launcher", Method.GET); + var request = new RestRequest("/api/Launcher", Method.Get); return await Client.GetRequestAsync("/api/Launcher/CheckForUpdate", true); } diff --git a/LANCommander.SDK/VersionInterceptor.cs b/LANCommander.SDK/VersionInterceptor.cs new file mode 100644 index 00000000..a3928f83 --- /dev/null +++ b/LANCommander.SDK/VersionInterceptor.cs @@ -0,0 +1,57 @@ +using LANCommander.SDK.Exceptions; +using Microsoft.Extensions.Logging; +using RestSharp; +using RestSharp.Interceptors; +using Semver; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace LANCommander.SDK +{ + internal class VersionInterceptor : Interceptor + { + private readonly ILogger Logger; + + public override ValueTask AfterRequest(RestResponse response, CancellationToken cancellationToken) + { + try + { + var version = Client.GetCurrentVersion(); + var header = response.Headers.FirstOrDefault(h => h.Name == "X-API-Version"); + + if (response.IsSuccessful && header == null) + { + response.ErrorException = new ApiVersionMismatchException(version, null, $"The server is out of date and does not support client version {version}."); + + return new ValueTask(); + } + + var apiVersion = SemVersion.Parse((string)header.Value, SemVersionStyles.Any); + + if (version.Major != apiVersion.Major || version.Minor != apiVersion.Minor) + { + switch (version.ComparePrecedenceTo(apiVersion)) + { + case -1: + response.ErrorException = new ApiVersionMismatchException(version, apiVersion, $"Your client (v{version}) is out of date and is not supported by the server (v{apiVersion})"); + break; + + case 1: + response.ErrorException = new ApiVersionMismatchException(version, apiVersion, $"Your client (v{version}) is on a version not supported by the server (v{apiVersion})"); + break; + } + } + } + catch (Exception ex) + { + Logger?.LogError(ex, "Could not validate API version"); + } + + return new ValueTask(); + } + } +}