mirror of
https://github.com/chylex/Discord-History-Tracker.git
synced 2024-11-25 14:42:44 +01:00
Compare commits
No commits in common. "3d9d6a454a0ad48e27cc588028f594c18b28f9bb" and "93fe018343d3895b0c538bf8983f920b4e52fcf8" have entirely different histories.
3d9d6a454a
...
93fe018343
@ -3,9 +3,12 @@ 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;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace DHT.Server.Endpoints;
|
||||
|
||||
@ -13,14 +16,25 @@ abstract class BaseEndpoint {
|
||||
private static readonly Log Log = Log.ForType<BaseEndpoint>();
|
||||
|
||||
protected IDatabaseFile Db { get; }
|
||||
protected ServerParameters Parameters { get; }
|
||||
|
||||
protected BaseEndpoint(IDatabaseFile db) {
|
||||
protected BaseEndpoint(IDatabaseFile db, ServerParameters parameters) {
|
||||
this.Db = db;
|
||||
this.Parameters = parameters;
|
||||
}
|
||||
|
||||
public async Task Handle(HttpContext ctx) {
|
||||
private async Task Handle(HttpContext ctx, StringValues token) {
|
||||
var request = ctx.Request;
|
||||
var response = ctx.Response;
|
||||
|
||||
Log.Info("Request: " + request.GetDisplayUrl() + " (" + request.ContentLength + " B)");
|
||||
|
||||
if (token.Count != 1 || token[0] != Parameters.Token) {
|
||||
Log.Error("Token: " + (token.Count == 1 ? token[0] : "<missing>"));
|
||||
response.StatusCode = (int) HttpStatusCode.Forbidden;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
response.StatusCode = (int) HttpStatusCode.OK;
|
||||
var output = await Respond(ctx);
|
||||
@ -35,6 +49,14 @@ abstract class BaseEndpoint {
|
||||
}
|
||||
}
|
||||
|
||||
public async Task HandleGet(HttpContext ctx) {
|
||||
await Handle(ctx, ctx.Request.Query["token"]);
|
||||
}
|
||||
|
||||
public async Task HandlePost(HttpContext ctx) {
|
||||
await Handle(ctx, ctx.Request.Headers["X-DHT-Token"]);
|
||||
}
|
||||
|
||||
protected abstract Task<IHttpOutput> Respond(HttpContext ctx);
|
||||
|
||||
protected static async Task<JsonElement> ReadJson(HttpContext ctx) {
|
||||
|
@ -2,13 +2,14 @@ using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using DHT.Server.Data;
|
||||
using DHT.Server.Database;
|
||||
using DHT.Server.Service;
|
||||
using DHT.Utils.Http;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace DHT.Server.Endpoints;
|
||||
|
||||
sealed class GetAttachmentEndpoint : BaseEndpoint {
|
||||
public GetAttachmentEndpoint(IDatabaseFile db) : base(db) {}
|
||||
public GetAttachmentEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
|
||||
|
||||
protected override Task<IHttpOutput> Respond(HttpContext ctx) {
|
||||
string attachmentUrl = WebUtility.UrlDecode((string) ctx.Request.RouteValues["url"]!);
|
||||
|
@ -13,16 +13,12 @@ namespace DHT.Server.Endpoints;
|
||||
sealed class GetTrackingScriptEndpoint : BaseEndpoint {
|
||||
private static ResourceLoader Resources { get; } = new (Assembly.GetExecutingAssembly());
|
||||
|
||||
private readonly ServerParameters serverParameters;
|
||||
|
||||
public GetTrackingScriptEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db) {
|
||||
serverParameters = parameters;
|
||||
}
|
||||
public GetTrackingScriptEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
|
||||
|
||||
protected override async Task<IHttpOutput> Respond(HttpContext ctx) {
|
||||
string bootstrap = await Resources.ReadTextAsync("Tracker/bootstrap.js");
|
||||
string script = bootstrap.Replace("= 0; /*[PORT]*/", "= " + serverParameters.Port + ";")
|
||||
.Replace("/*[TOKEN]*/", HttpUtility.JavaScriptStringEncode(serverParameters.Token))
|
||||
string script = bootstrap.Replace("= 0; /*[PORT]*/", "= " + Parameters.Port + ";")
|
||||
.Replace("/*[TOKEN]*/", HttpUtility.JavaScriptStringEncode(Parameters.Token))
|
||||
.Replace("/*[IMPORTS]*/", await Resources.ReadJoinedAsync("Tracker/scripts/", '\n'))
|
||||
.Replace("/*[CSS-CONTROLLER]*/", await Resources.ReadTextAsync("Tracker/styles/controller.css"))
|
||||
.Replace("/*[CSS-SETTINGS]*/", await Resources.ReadTextAsync("Tracker/styles/settings.css"))
|
||||
|
@ -3,13 +3,14 @@ using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using DHT.Server.Data;
|
||||
using DHT.Server.Database;
|
||||
using DHT.Server.Service;
|
||||
using DHT.Utils.Http;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace DHT.Server.Endpoints;
|
||||
|
||||
sealed class TrackChannelEndpoint : BaseEndpoint {
|
||||
public TrackChannelEndpoint(IDatabaseFile db) : base(db) {}
|
||||
public TrackChannelEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
|
||||
|
||||
protected override async Task<IHttpOutput> Respond(HttpContext ctx) {
|
||||
var root = await ReadJson(ctx);
|
||||
|
@ -9,6 +9,7 @@ using DHT.Server.Data;
|
||||
using DHT.Server.Data.Filters;
|
||||
using DHT.Server.Database;
|
||||
using DHT.Server.Download;
|
||||
using DHT.Server.Service;
|
||||
using DHT.Utils.Collections;
|
||||
using DHT.Utils.Http;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
@ -19,7 +20,7 @@ sealed class TrackMessagesEndpoint : BaseEndpoint {
|
||||
private const string HasNewMessages = "1";
|
||||
private const string NoNewMessages = "0";
|
||||
|
||||
public TrackMessagesEndpoint(IDatabaseFile db) : base(db) {}
|
||||
public TrackMessagesEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
|
||||
|
||||
protected override async Task<IHttpOutput> Respond(HttpContext ctx) {
|
||||
var root = await ReadJson(ctx);
|
||||
|
@ -3,13 +3,14 @@ using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using DHT.Server.Data;
|
||||
using DHT.Server.Database;
|
||||
using DHT.Server.Service;
|
||||
using DHT.Utils.Http;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace DHT.Server.Endpoints;
|
||||
|
||||
sealed class TrackUsersEndpoint : BaseEndpoint {
|
||||
public TrackUsersEndpoint(IDatabaseFile db) : base(db) {}
|
||||
public TrackUsersEndpoint(IDatabaseFile db, ServerParameters parameters) : base(db, parameters) {}
|
||||
|
||||
protected override async Task<IHttpOutput> Respond(HttpContext ctx) {
|
||||
var root = await ReadJson(ctx);
|
||||
|
@ -1,44 +0,0 @@
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using DHT.Utils.Logging;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace DHT.Server.Service.Middlewares;
|
||||
|
||||
sealed class ServerAuthorizationMiddleware {
|
||||
private static readonly Log Log = Log.ForType<ServerAuthorizationMiddleware>();
|
||||
|
||||
private readonly RequestDelegate next;
|
||||
private readonly ServerParameters serverParameters;
|
||||
|
||||
public ServerAuthorizationMiddleware(RequestDelegate next, ServerParameters serverParameters) {
|
||||
this.next = next;
|
||||
this.serverParameters = serverParameters;
|
||||
}
|
||||
|
||||
public async Task InvokeAsync(HttpContext context) {
|
||||
var request = context.Request;
|
||||
|
||||
bool success = HttpMethods.IsGet(request.Method)
|
||||
? CheckToken(request.Query["token"])
|
||||
: CheckToken(request.Headers["X-DHT-Token"]);
|
||||
|
||||
if (success) {
|
||||
await next(context);
|
||||
}
|
||||
else {
|
||||
context.Response.StatusCode = (int) HttpStatusCode.Forbidden;
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckToken(StringValues token) {
|
||||
if (token.Count == 1 && token[0] == serverParameters.Token) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
Log.Error("Invalid token: " + (token.Count == 1 ? token[0] : "<missing>"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using DHT.Utils.Logging;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
|
||||
namespace DHT.Server.Service.Middlewares;
|
||||
|
||||
sealed class ServerLoggingMiddleware {
|
||||
private static readonly Log Log = Log.ForType<ServerLoggingMiddleware>();
|
||||
|
||||
private readonly RequestDelegate next;
|
||||
|
||||
public ServerLoggingMiddleware(RequestDelegate next) {
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public async Task InvokeAsync(HttpContext context) {
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
await next(context);
|
||||
stopwatch.Stop();
|
||||
|
||||
var request = context.Request;
|
||||
var requestLength = request.ContentLength ?? 0L;
|
||||
var responseStatus = context.Response.StatusCode;
|
||||
var elapsedMs = stopwatch.ElapsedMilliseconds;
|
||||
Log.Debug("Request to " + request.GetEncodedPathAndQuery() + " (" + requestLength + " B) returned " + responseStatus + ", took " + elapsedMs + " ms");
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.Threading;
|
||||
using DHT.Server.Database;
|
||||
using DHT.Utils.Logging;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@ -74,7 +75,7 @@ public static class ServerLauncher {
|
||||
options.ListenLocalhost(port, static listenOptions => listenOptions.Protocols = HttpProtocols.Http1);
|
||||
}
|
||||
|
||||
Server = new WebHostBuilder()
|
||||
Server = WebHost.CreateDefaultBuilder()
|
||||
.ConfigureServices(AddServices)
|
||||
.UseKestrel(SetKestrelOptions)
|
||||
.UseStartup<Startup>()
|
||||
|
@ -2,7 +2,6 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text.Json.Serialization;
|
||||
using DHT.Server.Database;
|
||||
using DHT.Server.Endpoints;
|
||||
using DHT.Server.Service.Middlewares;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@ -28,23 +27,27 @@ sealed class Startup {
|
||||
builder.WithOrigins(AllowedOrigins).AllowCredentials().AllowAnyMethod().AllowAnyHeader().WithExposedHeaders("X-DHT");
|
||||
});
|
||||
});
|
||||
|
||||
services.AddRoutingCore();
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||
public void Configure(IApplicationBuilder app, IHostApplicationLifetime lifetime, IDatabaseFile db, ServerParameters parameters) {
|
||||
app.UseMiddleware<ServerLoggingMiddleware>();
|
||||
app.UseCors();
|
||||
app.UseMiddleware<ServerAuthorizationMiddleware>();
|
||||
app.UseRouting();
|
||||
|
||||
app.UseCors();
|
||||
app.UseEndpoints(endpoints => {
|
||||
endpoints.MapGet("/get-tracking-script", new GetTrackingScriptEndpoint(db, parameters).Handle);
|
||||
endpoints.MapGet("/get-attachment/{url}", new GetAttachmentEndpoint(db).Handle);
|
||||
endpoints.MapPost("/track-channel", new TrackChannelEndpoint(db).Handle);
|
||||
endpoints.MapPost("/track-users", new TrackUsersEndpoint(db).Handle);
|
||||
endpoints.MapPost("/track-messages", new TrackMessagesEndpoint(db).Handle);
|
||||
GetTrackingScriptEndpoint getTrackingScript = new (db, parameters);
|
||||
endpoints.MapGet("/get-tracking-script", context => getTrackingScript.HandleGet(context));
|
||||
|
||||
TrackChannelEndpoint trackChannel = new (db, parameters);
|
||||
endpoints.MapPost("/track-channel", context => trackChannel.HandlePost(context));
|
||||
|
||||
TrackUsersEndpoint trackUsers = new (db, parameters);
|
||||
endpoints.MapPost("/track-users", context => trackUsers.HandlePost(context));
|
||||
|
||||
TrackMessagesEndpoint trackMessages = new (db, parameters);
|
||||
endpoints.MapPost("/track-messages", context => trackMessages.HandlePost(context));
|
||||
|
||||
GetAttachmentEndpoint getAttachment = new (db, parameters);
|
||||
endpoints.MapGet("/get-attachment/{url}", context => getAttachment.HandleGet(context));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user