Discord-History-Tracker/app/Server/Endpoints/BaseEndpoint.cs

61 lines
1.8 KiB
C#

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<BaseEndpoint>();
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] : "<missing>"));
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<JsonElement> ReadJson(HttpContext ctx) {
return await ctx.Request.ReadFromJsonAsync<JsonElement?>() ?? throw new HttpException(HttpStatusCode.UnsupportedMediaType, "This endpoint only accepts JSON.");
}
}
}