using System; using System.Globalization; using System.IO; using System.Net; using System.Net.Http; using System.Text; using System.Text.Json; using System.Threading; using System.Threading.Tasks; namespace Nebula.Launcher.Services; [ServiceRegister] public class RestService { private readonly HttpClient _client = new(); private readonly DebugService _debug; private readonly JsonSerializerOptions _serializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true }; public RestService(DebugService debug) { _debug = debug; } public async Task> GetAsync(Uri uri, CancellationToken cancellationToken) { _debug.Debug("GET " + uri); try { var response = await _client.GetAsync(uri, cancellationToken); return await ReadResult(response, cancellationToken); } catch (Exception ex) { _debug.Error("ERROR WHILE CONNECTION " + uri + ": " + ex.Message); return new RestResult(default, ex.Message, HttpStatusCode.RequestTimeout); } } public async Task GetAsyncDefault(Uri uri, T defaultValue, CancellationToken cancellationToken) { var result = await GetAsync(uri, cancellationToken); return result.Value ?? defaultValue; } public async Task> PostAsync(T information, Uri uri, CancellationToken cancellationToken) { _debug.Debug("POST " + uri); try { var json = JsonSerializer.Serialize(information, _serializerOptions); var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await _client.PostAsync(uri, content, cancellationToken); return await ReadResult(response, cancellationToken); } catch (Exception ex) { _debug.Debug("ERROR " + ex.Message); return new RestResult(default, ex.Message, HttpStatusCode.RequestTimeout); } } public async Task> PostAsync(Stream stream, Uri uri, CancellationToken cancellationToken) { _debug.Debug("POST " + uri); try { using var multipartFormContent = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture)); multipartFormContent.Add(new StreamContent(stream), "formFile", "image.png"); var response = await _client.PostAsync(uri, multipartFormContent, cancellationToken); return await ReadResult(response, cancellationToken); } catch (Exception ex) { _debug.Error("ERROR " + ex.Message); if (ex.StackTrace != null) _debug.Error(ex.StackTrace); return new RestResult(default, ex.Message, HttpStatusCode.RequestTimeout); } } public async Task> DeleteAsync(Uri uri, CancellationToken cancellationToken) { _debug.Debug("DELETE " + uri); try { var response = await _client.DeleteAsync(uri, cancellationToken); return await ReadResult(response, cancellationToken); } catch (Exception ex) { _debug.Debug("ERROR " + ex.Message); return new RestResult(default, ex.Message, HttpStatusCode.RequestTimeout); } } private async Task> ReadResult(HttpResponseMessage response, CancellationToken cancellationToken) { var content = await response.Content.ReadAsStringAsync(cancellationToken); //_debug.Debug("CONTENT:" + content); if (response.IsSuccessStatusCode) { _debug.Debug($"SUCCESSFUL GET CONTENT {typeof(T)}"); if (typeof(T) == typeof(RawResult)) return (new RestResult(new RawResult(content), null, response.StatusCode) as RestResult)!; return new RestResult(JsonSerializer.Deserialize(content, _serializerOptions), null, response.StatusCode); } _debug.Error("ERROR " + response.StatusCode + " " + content); return new RestResult(default, "response code:" + response.StatusCode, response.StatusCode); } } public class RestResult { public string? Message; public HttpStatusCode StatusCode; public T? Value; public RestResult(T? value, string? message, HttpStatusCode statusCode) { Value = value; Message = message; StatusCode = statusCode; } public static implicit operator T?(RestResult result) { return result.Value; } } public class RawResult { public string Result; public RawResult(string result) { Result = result; } public static implicit operator string(RawResult result) { return result.Result; } }