decePubClient/Services/IHttpService.cs

197 lines
6.4 KiB
C#

using Blazored.LocalStorage;
using System.Globalization;
using System.Net.Http.Json;
using System.Net;
using decePubClient.Models;
namespace decePubClient.Services
{
public interface IHttpService
{
Task<HttpResponseMessage> Get(string uri, object payload = default, string?[] queryParams = default);
Task<HttpResponseMessage> GetAnon(string uri, object payload = default, string?[] queryParams = default);
Task<HttpResponseMessage> Post(string uri, object payload = default);
Task<HttpResponseMessage> PostAnon(string uri, object payload = default);
Task<HttpResponseMessage> Delete(string uri, string?[] queryParams = default, object payload = default);
}
public class HttpService : IHttpService
{
readonly IHttpClientFactory HttpClientFactory;
readonly TokenAuthStateProvider AuthStateProvider;
readonly ILogger<HttpService> Logger;
readonly ILocalStorageService Storage;
readonly IStorage DbStorage;
public HttpService(
IHttpClientFactory httpClientFactory,
TokenAuthStateProvider authStateProvider,
ILogger<HttpService> logger,
ILocalStorageService storage,
IStorage dbStorage)
{
HttpClientFactory = httpClientFactory;
AuthStateProvider = authStateProvider;
Logger = logger;
Storage = storage;
DbStorage = dbStorage;
}
public async Task<HttpResponseMessage> Get(string uri, object payload = default, string?[] queryParams = default)
{
try
{
uri = $"{CultureInfo.DefaultThreadCurrentCulture.TwoLetterISOLanguageName}/{uri}";
var request = default(HttpRequestMessage);
if (queryParams != null)
request = new(HttpMethod.Get, string.Join('?', uri, string.Join('&', queryParams)));
else
request = new(HttpMethod.Get, uri);
if (payload != null)
request.Content = JsonContent.Create(payload);
return await SendRequest(request);
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(Get)}:{uri}");
await DbStorage.AddLog(ex, $"{nameof(Get)}:{uri}");
return new(HttpStatusCode.ServiceUnavailable);
}
}
public async Task<HttpResponseMessage> Post(string uri, object payload = default)
{
try
{
uri = $"{CultureInfo.DefaultThreadCurrentCulture.TwoLetterISOLanguageName}/{uri}";
var request = new HttpRequestMessage(HttpMethod.Post, uri)
{
Content = JsonContent.Create(payload)
};
return await SendRequest(request);
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(Post)}:{uri}");
await DbStorage.AddLog(ex, $"{nameof(Post)}:{uri}");
return new(HttpStatusCode.ServiceUnavailable);
}
}
public async Task<HttpResponseMessage> GetAnon(string uri, object payload = default, string?[] queryParams = default)
{
try
{
uri = $"{CultureInfo.DefaultThreadCurrentCulture.TwoLetterISOLanguageName}/{uri}";
var request = default(HttpRequestMessage);
if (queryParams != null)
request = new(HttpMethod.Get, string.Join('?', uri, string.Join('&', queryParams)));
else
request = new(HttpMethod.Get, uri);
if (payload != null)
request.Content = JsonContent.Create(payload);
return await SendAnonRequest(request);
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(GetAnon)}:{uri}");
await DbStorage.AddLog(ex, $"{nameof(GetAnon)}:{uri}");
return new(HttpStatusCode.ServiceUnavailable);
}
}
public async Task<HttpResponseMessage> PostAnon(string uri, object payload = default)
{
try
{
uri = $"{CultureInfo.DefaultThreadCurrentCulture.TwoLetterISOLanguageName}/{uri}";
var request = new HttpRequestMessage(HttpMethod.Post, uri)
{
Content = JsonContent.Create(payload)
};
return await SendAnonRequest(request);
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(PostAnon)}:{uri}");
await DbStorage.AddLog(ex, $"{nameof(PostAnon)}:{uri}");
return new(HttpStatusCode.ServiceUnavailable);
}
}
public async Task<HttpResponseMessage> Delete(string uri, string?[] queryParams = default, object payload = default)
{
try
{
uri = $"{CultureInfo.DefaultThreadCurrentCulture.TwoLetterISOLanguageName}/{uri}";
var request = default(HttpRequestMessage);
if (queryParams != null)
request = new(HttpMethod.Delete, string.Join('?', uri, string.Join('&', queryParams)));
else
request = new(HttpMethod.Delete, uri);
if (payload != null)
request.Content = JsonContent.Create(payload);
return await SendRequest(request);
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(Delete)}:{uri}");
await DbStorage.AddLog(ex, $"{nameof(Delete)}:{uri}");
return new(HttpStatusCode.ServiceUnavailable);
}
}
// helper methods
async Task<HttpResponseMessage> SendRequest(HttpRequestMessage request)
{
try
{
var authData = await Storage.GetItemAsync<AuthData>(nameof(AuthData));
var isApiUrl = !request.RequestUri?.IsAbsoluteUri;
if (isApiUrl.HasValue && isApiUrl.Value)
request.Headers.Authorization = new("Bearer", authData.Token);
var response = await HttpClientFactory.CreateClient().SendAsync(request);
if (response.StatusCode is HttpStatusCode.Unauthorized or HttpStatusCode.Forbidden)
{
Logger.LogWarning($"{nameof(SendRequest)}:401/403:{request.RequestUri?.OriginalString}:{await response.Content.ReadAsStringAsync()}");
await DbStorage.AddLog($"{nameof(SendRequest)}:401/403:{request.RequestUri?.OriginalString}:{await response.Content.ReadAsStringAsync()}", $"{nameof(SendRequest)}:{request.RequestUri?.OriginalString}");
await AuthStateProvider.LogoutAsync();
}
return response;
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(SendRequest)}:{request.RequestUri?.OriginalString}");
await DbStorage.AddLog(ex, $"{nameof(SendRequest)}:{request.RequestUri?.OriginalString}");
return new(HttpStatusCode.ServiceUnavailable);
}
}
async Task<HttpResponseMessage> SendAnonRequest(HttpRequestMessage request)
{
try
{
var authData = await Storage.GetItemAsync<AuthData>(nameof(AuthData));
if (!string.IsNullOrEmpty(authData?.Token))
request.Headers.Authorization = new("Bearer", authData.Token);
var response = await HttpClientFactory.CreateClient().SendAsync(request);
return response;
}
catch (Exception ex)
{
Logger.LogError(ex, $"{nameof(SendAnonRequest)}:{request.RequestUri?.OriginalString}");
await DbStorage.AddLog(ex, $"{nameof(SendAnonRequest)}:{request.RequestUri?.OriginalString}");
return new(HttpStatusCode.ServiceUnavailable);
}
}
}
}