using System; using System.Net; using System.Net.Http; using System.Net.Http.Json; using System.Threading; using System.Threading.Tasks; using Oqtane.Models; using Oqtane.Shared; namespace Oqtane.Services { public class ServiceBase { private readonly HttpClient _http; protected ServiceBase(HttpClient client) { _http = client; } public string CreateApiUrl(string serviceName, Alias alias) { return CreateApiUrl(serviceName, alias, ControllerRoutes.ApiRoute); } public string CreateApiUrl(string serviceName, Alias alias, string routeTemplate) { string apiurl = "/"; if (routeTemplate == ControllerRoutes.ApiRoute) { if (alias != null && !string.IsNullOrEmpty(alias.Path)) { // include the alias path for multi-tenant context apiurl += alias.Path + "/"; } } else { // legacy support for ControllerRoutes.Default if (alias != null) { // include the alias for multi-tenant context apiurl += $"{alias.AliasId}/"; } else { // tenant agnostic apiurl += "~/"; } } apiurl += $"api/{serviceName}"; return apiurl; } // add entityid parameter to url for custom authorization policy public string CreateAuthorizationPolicyUrl(string url, int entityId) { string qs = "entityid=" + entityId.ToString(); if (url.Contains("?")) { return url + "&" + qs; } else { return url + "?" + qs; } } protected async Task GetAsync(string uri) { var response = await _http.GetAsync(uri); CheckResponse(response); } protected async Task GetStringAsync(string uri) { try { return await _http.GetStringAsync(uri); } catch (Exception e) { //TODO replace with logging Console.WriteLine(e); } return default; } protected async Task GetByteArrayAsync(string uri) { try { return await _http.GetByteArrayAsync(uri); } catch (Exception e) { Console.WriteLine(e); } return default; } protected async Task GetJsonAsync(string uri) { var response = await _http.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None); if (CheckResponse(response) && ValidateJsonContent(response.Content)) { return await response.Content.ReadFromJsonAsync(); } return default; } protected async Task PutAsync(string uri) { var response = await _http.PutAsync(uri, null); CheckResponse(response); } protected async Task PutJsonAsync(string uri, T value) { return await PutJsonAsync(uri, value); } protected async Task PutJsonAsync(string uri, TValue value) { var response = await _http.PutAsJsonAsync(uri, value); if (CheckResponse(response) && ValidateJsonContent(response.Content)) { var result = await response.Content.ReadFromJsonAsync(); return result; } return default; } protected async Task PostAsync(string uri) { var response = await _http.PostAsync(uri, null); CheckResponse(response); } protected async Task PostJsonAsync(string uri, T value) { return await PostJsonAsync(uri, value); } protected async Task PostJsonAsync(string uri, TValue value) { var response = await _http.PostAsJsonAsync(uri, value); if (CheckResponse(response) && ValidateJsonContent(response.Content)) { var result = await response.Content.ReadFromJsonAsync(); return result; } return default; } protected async Task DeleteAsync(string uri) { var response = await _http.DeleteAsync(uri); CheckResponse(response); } private bool CheckResponse(HttpResponseMessage response) { if (response.IsSuccessStatusCode) return true; if (response.StatusCode != HttpStatusCode.NoContent && response.StatusCode != HttpStatusCode.NotFound) { //TODO: Log errors here Console.WriteLine($"Request: {response.RequestMessage.RequestUri}"); Console.WriteLine($"Response status: {response.StatusCode} {response.ReasonPhrase}"); } return false; } private static bool ValidateJsonContent(HttpContent content) { var mediaType = content?.Headers.ContentType?.MediaType; return mediaType != null && mediaType.Equals("application/json", StringComparison.OrdinalIgnoreCase); //TODO Missing content JSON validation } [Obsolete("This method is obsolete. Use CreateApiUrl(Alias alias, string serviceName) instead.", false)] public string CreateApiUrl(Alias alias, string absoluteUri, string serviceName) { // only retained for short term backward compatibility return CreateApiUrl(alias, serviceName); } [Obsolete("This method is obsolete. Use CreateApiUrl(string serviceName, Alias alias) instead.", false)] public string CreateApiUrl(string serviceName) { return CreateApiUrl(serviceName, null, ControllerRoutes.Default); } [Obsolete("This method is deprecated.", false)] public Alias Alias { get; set; } [Obsolete("This method is obsolete. Use CreateApiUrl(string serviceName, Alias alias) instead.", false)] public string CreateApiUrl(Alias alias, string serviceName) { return CreateApiUrl(serviceName, alias, ControllerRoutes.Default); } } }