diff --git a/extra/admin-api/Spacebar.Cdn/Controllers/ImagesAndStickersController.cs b/extra/admin-api/Spacebar.Cdn/Controllers/ImagesAndStickersController.cs
index 1f28f9bd..6c0409dc 100644
--- a/extra/admin-api/Spacebar.Cdn/Controllers/ImagesAndStickersController.cs
+++ b/extra/admin-api/Spacebar.Cdn/Controllers/ImagesAndStickersController.cs
@@ -13,7 +13,7 @@ public class ImagesAndStickerController(LruFileCache lfc, IFileSource fs, CdnWor
[HttpGet("/stickers/{id}.{ext}")]
[HttpGet("/emojis/{id}")]
[HttpGet("/emojis/{id}.{ext}")]
- public async Task<IActionResult> GetUserAvatar(string id, string ext = "png") {
+ public async Task<IActionResult> GetUserAvatar(string id, string ext = "webp") {
DiscordImageResizeParams resizeParams = Request.GetResizeParams();
var cacheKey = Request.Path + resizeParams.ToSerializedName();
LruFileCache.Entry? entry;
diff --git a/extra/admin-api/Spacebar.Cdn/Controllers/StaticAssetController.cs b/extra/admin-api/Spacebar.Cdn/Controllers/StaticAssetController.cs
index 52b802a5..ce64bc47 100644
--- a/extra/admin-api/Spacebar.Cdn/Controllers/StaticAssetController.cs
+++ b/extra/admin-api/Spacebar.Cdn/Controllers/StaticAssetController.cs
@@ -12,7 +12,7 @@ namespace Spacebar.Cdn.Controllers;
public class StaticAssetController(LruFileCache lfc, IFileSource fs, CdnWorkerService cws) : ControllerBase {
[HttpGet("/embed/avatars/{avatarIdx}")]
[HttpGet("/embed/avatars/{avatarIdx}.{ext}")]
- public async Task<IActionResult> GetUserAvatar(string avatarIdx, string ext = "png") {
+ public async Task<IActionResult> GetUserAvatar(string avatarIdx, string ext = "webp") {
DiscordImageResizeParams resizeParams = Request.GetResizeParams();
var cacheKey = Request.Path + resizeParams.ToSerializedName();
LruFileCache.Entry? entry;
diff --git a/extra/admin-api/Spacebar.Cdn/Controllers/UserController.cs b/extra/admin-api/Spacebar.Cdn/Controllers/UserController.cs
index ee9ced71..eaf8feb7 100644
--- a/extra/admin-api/Spacebar.Cdn/Controllers/UserController.cs
+++ b/extra/admin-api/Spacebar.Cdn/Controllers/UserController.cs
@@ -11,7 +11,7 @@ namespace Spacebar.Cdn.Controllers;
public class UserController(LruFileCache lfc, IFileSource fs, CdnWorkerService cws) : ControllerBase {
[HttpGet("/avatars/{userId}/{hash}")]
[HttpGet("/avatars/{userId}/{hash}.{ext}")]
- public async Task<IActionResult> GetUserAvatar(string userId, string hash, string ext = "png") {
+ public async Task<IActionResult> GetUserAvatar(string userId, string hash, string ext = "webp") {
DiscordImageResizeParams resizeParams = Request.GetResizeParams();
var originalKey = fs.BaseUrl + Request.Path;
var cacheKey = Request.Path + resizeParams.ToSerializedName();
diff --git a/extra/admin-api/Spacebar.Cdn/Services/CdnWorkerService.cs b/extra/admin-api/Spacebar.Cdn/Services/CdnWorkerService.cs
index 2eabf129..1238705e 100644
--- a/extra/admin-api/Spacebar.Cdn/Services/CdnWorkerService.cs
+++ b/extra/admin-api/Spacebar.Cdn/Services/CdnWorkerService.cs
@@ -1,10 +1,11 @@
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Net.Sockets;
using ArcaneLibs.Extensions;
namespace Spacebar.Cdn.Services;
-public class CdnWorkerService(SpacebarCdnWorkerConfiguration cfg) : IDisposable {
+public class CdnWorkerService(SpacebarCdnWorkerConfiguration cfg, IHostApplicationLifetime lifetime) : IDisposable {
private int _q8Idx = 0;
private int _q16Idx = 0;
private int _q16HdriIdx = 0;
@@ -24,13 +25,23 @@ public class CdnWorkerService(SpacebarCdnWorkerConfiguration cfg) : IDisposable
Console.WriteLine("Done initializing CDN worker store!");
}
- private static HttpClient[] GetWorkerHttpClients(List<string> urls) {
+ [SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Unix is presumed by the developers - depends on unix sockets anyhow")]
+ private HttpClient[] GetWorkerHttpClients(List<string> urls) {
List<HttpClient> results = [];
foreach (var url in urls) {
Console.WriteLine(" - Handling worker URI/path: " + url);
- if (url.StartsWith("http://unix:")) results.Add(UnixSocketHttpClientFactory.GetHttpClientForSocket(url));
- else if (url.StartsWith("http://") || url.StartsWith("https://")) results.Add(new HttpClient() { BaseAddress = new(url) });
- // else if (File.Exists(url)) { }
+ if (url.StartsWith("http://unix:")) results.Add(HttpClientFactory.GetHttpClientForSocket(url));
+ else if (url.StartsWith("http://") || url.StartsWith("https://")) results.Add(HttpClientFactory.GetHttpClientForUrl(url));
+ else if (File.Exists(url) && File.GetUnixFileMode(url).HasFlag(UnixFileMode.OtherExecute)) {
+ var res = HttpClientFactory.GetHttpClientForExec(url);
+ results.Add(res.client);
+ lifetime.ApplicationStopped.Register(() => {
+ Console.WriteLine("Killing CDN worker...");
+ res.p.Kill();
+ res.p.WaitForExit();
+ Console.WriteLine("CDN worker killed!");
+ });
+ }
else throw new NotImplementedException($"Don't know how to handle worker URL \"{url}\"");
}
@@ -60,7 +71,7 @@ public class CdnWorkerService(SpacebarCdnWorkerConfiguration cfg) : IDisposable
}
}
-internal class UnixSocketHttpClientFactory {
+internal class HttpClientFactory {
internal static HttpClient GetHttpClientForSocket(string url) {
var socketPath = new Uri(url).LocalPath;
var httpHandler = new SocketsHttpHandler {
@@ -73,7 +84,30 @@ internal class UnixSocketHttpClientFactory {
}
};
return new HttpClient(httpHandler) {
- BaseAddress = new Uri("http://localhost") // just a dummy value, since dotnet still wants :)
+ BaseAddress = new Uri("http://localhost"), // just a dummy value, since dotnet still wants it :)
+ Timeout = TimeSpan.FromMinutes(15) // because stuff can get slow, we want caching to at least attempt to succeed
+ };
+ }
+
+ public static HttpClient GetHttpClientForUrl(string url) {
+ return new HttpClient {
+ BaseAddress = new(url),
+ Timeout = TimeSpan.FromMinutes(15)
+ };
+ }
+
+ public static (HttpClient client, Process p) GetHttpClientForExec(string path) {
+ var url = $"http://unix:{Path.GetTempPath()}sb-cdn-worker-{Random.Shared.GetHexString(32)}.sock";
+ var psi = new ProcessStartInfo() {
+ FileName = path,
+ RedirectStandardError = true, RedirectStandardOutput = true
};
+ psi.Environment["DOTNET_URLS"] = url;
+ var p = Process.Start(psi);
+ p.OutputDataReceived += (_, args) => Console.WriteLine("[CDN Worker/OUT] " + args.Data);
+ p.ErrorDataReceived += (_, args) => Console.WriteLine("[CDN Worker/ERR] " + args.Data);
+ p.BeginErrorReadLine();
+ p.BeginOutputReadLine();
+ return (GetHttpClientForSocket(url), p);
}
}
\ No newline at end of file
|