using System; using System.Net; using System.Text.Json; using System.Threading.Tasks; using DHT.Server.Database; using DHT.Server.Service; using DHT.Utils.Http; using DHT.Utils.Logging; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Extensions; namespace DHT.Server.Endpoints { abstract class BaseEndpoint { private static readonly Log Log = Log.ForType(); protected IDatabaseFile Db { get; } private readonly ServerParameters parameters; protected BaseEndpoint(IDatabaseFile db, ServerParameters parameters) { this.Db = db; this.parameters = parameters; } public async Task Handle(HttpContext ctx) { var request = ctx.Request; var response = ctx.Response; Log.Info("Request: " + request.GetDisplayUrl() + " (" + request.ContentLength + " B)"); var requestToken = request.Headers["X-DHT-Token"]; if (requestToken.Count != 1 || requestToken[0] != parameters.Token) { Log.Error("Token: " + (requestToken.Count == 1 ? requestToken[0] : "")); response.StatusCode = (int) HttpStatusCode.Forbidden; return; } try { var (statusCode, output) = await Respond(ctx); response.StatusCode = (int) statusCode; if (output != null) { await response.WriteAsJsonAsync(output); } } catch (HttpException e) { Log.Error(e); response.StatusCode = (int) e.StatusCode; await response.WriteAsync(e.Message); } catch (Exception e) { Log.Error(e); response.StatusCode = (int) HttpStatusCode.InternalServerError; } } protected abstract Task<(HttpStatusCode, object?)> Respond(HttpContext ctx); protected static async Task ReadJson(HttpContext ctx) { return await ctx.Request.ReadFromJsonAsync() ?? throw new HttpException(HttpStatusCode.UnsupportedMediaType, "This endpoint only accepts JSON."); } } }