using HyperBooru.ApiModels; using System.Net; using System.Net.Http.Json; namespace HyperBooru.ApiClient; public sealed class HBSession : IDisposable { public Media Media { get; private init; } public Tag Tag { get; private init; } public Feed Feed { get; private init; } public User User { get; private init; } public Uri BaseUri { get; private init; } internal HttpClient HttpClient { get; private init; } public HBSession ( Uri baseUri, bool skipCertificateCheck) { BaseUri = new($"{baseUri.Scheme}://{baseUri.Host}:{baseUri.Port}/"); var handler = new HttpClientHandler() { AllowAutoRedirect = true, UseCookies = true, CookieContainer = new CookieContainer() }; if(skipCertificateCheck) { handler.ClientCertificateOptions = ClientCertificateOption.Manual; handler.ServerCertificateCustomValidationCallback = (request, cert, certChain, policyErrors) => true; } HttpClient = new(new ErrorHandler(handler)) { BaseAddress = BaseUri }; Media = new(this); Tag = new(this); Feed = new(this); User = new(this); } public async Task LoginAsync(string username, string password) { var formData = new FormUrlEncodedContent(new[] { new KeyValuePair("username", username), new KeyValuePair("password", password) }); var resp = await HttpClient.PostAsync($"/Login", formData); if(resp.StatusCode == HttpStatusCode.Forbidden) { throw new Exception("Invalid username or password"); } else if(!resp.IsSuccessStatusCode) { var content = await resp.Content.ReadAsStringAsync(); throw new Exception($"Unknown error while logging in: {content}"); } } public async Task LogoutAsync() => await HttpClient.PostAsync("/Logout", null); public void Dispose() => HttpClient.Dispose(); } public class ErrorHandler : DelegatingHandler { public ErrorHandler(HttpMessageHandler innerHandler) : base(innerHandler) {} protected override async Task SendAsync(HttpRequestMessage request, CancellationToken ct) { var resp = await base.SendAsync(request, ct); if(resp.IsSuccessStatusCode) return resp; HBException e; try { e = await resp.Content.ReadFromJsonAsync(ct) ?? throw new NullReferenceException(); } catch { throw new HBException("An unknown error occurred"); } throw e; } }