diff --git a/extra/admin-api/Interop/Spacebar.Interop.Cdn.Abstractions/FilesystemFileSource.cs b/extra/admin-api/Interop/Spacebar.Interop.Cdn.Abstractions/FilesystemFileSource.cs
index 8a67dfe3..8e0f2e77 100644
--- a/extra/admin-api/Interop/Spacebar.Interop.Cdn.Abstractions/FilesystemFileSource.cs
+++ b/extra/admin-api/Interop/Spacebar.Interop.Cdn.Abstractions/FilesystemFileSource.cs
@@ -24,6 +24,7 @@ public class FilesystemFileSource(string baseUrl) : IFileSource {
await using var rs = File.OpenRead(GetPathSafe(path));
var ms = new MemoryStream();
await rs.CopyToAsync(ms);
+ ms.Seek(0, SeekOrigin.Begin);
return new() {
Stream = ms,
MimeType = "MIME/TYPE"
diff --git a/extra/admin-api/Interop/Spacebar.Interop.Cdn.Abstractions/LruFileCache.cs b/extra/admin-api/Interop/Spacebar.Interop.Cdn.Abstractions/LruFileCache.cs
index 27b55400..23ea6d43 100644
--- a/extra/admin-api/Interop/Spacebar.Interop.Cdn.Abstractions/LruFileCache.cs
+++ b/extra/admin-api/Interop/Spacebar.Interop.Cdn.Abstractions/LruFileCache.cs
@@ -1,3 +1,5 @@
+using System.Collections.Frozen;
+using System.Collections.Immutable;
using ArcaneLibs;
namespace Spacebar.Interop.Cdn.Abstractions;
diff --git a/extra/admin-api/Spacebar.Cdn/Controllers/Internal/GetImageController.cs b/extra/admin-api/Spacebar.Cdn/Controllers/Internal/GetImageController.cs
index 3b7df118..38e2717d 100644
--- a/extra/admin-api/Spacebar.Cdn/Controllers/Internal/GetImageController.cs
+++ b/extra/admin-api/Spacebar.Cdn/Controllers/Internal/GetImageController.cs
@@ -1,9 +1,9 @@
+// #if DEBUG
// using ArcaneLibs;
// using ArcaneLibs.Collections;
// using ImageMagick;
// using Microsoft.AspNetCore.Mvc;
// using Spacebar.AdminApi.TestClient.Services.Services;
-// using Spacebar.Cdn.Extensions;
// using Spacebar.Interop.Cdn.Abstractions;
//
// namespace Spacebar.Cdn.Controllers.Internal;
@@ -156,7 +156,8 @@
// var img = new MagickImageCollection();
//
// var ms = new MemoryStream();
-//
+//
// return new FileContentResult(ms.ToArray(), "image/gif");
// }
-// }
\ No newline at end of file
+// }
+// #endif
\ No newline at end of file
diff --git a/extra/admin-api/Spacebar.Cdn/Controllers/StaticAssetController.cs b/extra/admin-api/Spacebar.Cdn/Controllers/StaticAssetController.cs
index ce64bc47..fcf5a6ef 100644
--- a/extra/admin-api/Spacebar.Cdn/Controllers/StaticAssetController.cs
+++ b/extra/admin-api/Spacebar.Cdn/Controllers/StaticAssetController.cs
@@ -1,6 +1,5 @@
using ArcaneLibs.Extensions.Streams;
using Microsoft.AspNetCore.Mvc;
-using Microsoft.OpenApi;
using Spacebar.AdminApi.TestClient.Services.Services;
using Spacebar.Cdn.Extensions;
using Spacebar.Cdn.Services;
@@ -15,17 +14,15 @@ public class StaticAssetController(LruFileCache lfc, IFileSource fs, CdnWorkerSe
public async Task<IActionResult> GetUserAvatar(string avatarIdx, string ext = "webp") {
DiscordImageResizeParams resizeParams = Request.GetResizeParams();
var cacheKey = Request.Path + resizeParams.ToSerializedName();
- LruFileCache.Entry? entry;
- entry = await lfc.GetOrAdd(cacheKey, async () => {
-
- var res = await cws.GetRawClient("q8").GetAsync(Request.Path + Request.QueryString);
- var outStream = await res.Content.ReadAsStreamAsync();
+ var entry = await lfc.GetOrAdd(cacheKey, async () => {
+ var res = await cws.GetRawClient("q8").GetAsync(Request.Path + Request.QueryString);
+ var outStream = await res.Content.ReadAsStreamAsync();
- return new LruFileCache.Entry() {
- Data = outStream.ReadToEnd().ToArray(),
- MimeType = res.Content.Headers.ContentType?.ToString() ?? Mimes.GetMime(Mimes.GetFormatForExtension(ext))
- };
- });
+ return new LruFileCache.Entry() {
+ Data = outStream.ReadToEnd().ToArray(),
+ MimeType = res.Content.Headers.ContentType?.ToString() ?? Mimes.GetMime(Mimes.GetFormatForExtension(ext))
+ };
+ });
return new FileContentResult(entry.Data, entry.MimeType);
}
diff --git a/extra/admin-api/Spacebar.Cdn/Controllers/UserController.cs b/extra/admin-api/Spacebar.Cdn/Controllers/UserController.cs
index eaf8feb7..3777f840 100644
--- a/extra/admin-api/Spacebar.Cdn/Controllers/UserController.cs
+++ b/extra/admin-api/Spacebar.Cdn/Controllers/UserController.cs
@@ -8,12 +8,11 @@ using Spacebar.Interop.Cdn.Abstractions;
namespace Spacebar.Cdn.Controllers;
[ApiController]
-public class UserController(LruFileCache lfc, IFileSource fs, CdnWorkerService cws) : ControllerBase {
- [HttpGet("/avatars/{userId}/{hash}")]
+public class UserController(LruFileCache lfc, IFileSource fs, CdnWorkerService cws) : ImageController(lfc, fs, cws) {
+ [HttpGet("/avatars/{userId}/{hash}")] // technically an invalid request?
[HttpGet("/avatars/{userId}/{hash}.{ext}")]
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();
LruFileCache.Entry? entry;
if (!Request.Query.Any() || resizeParams.Passthrough) {
@@ -29,7 +28,7 @@ public class UserController(LruFileCache lfc, IFileSource fs, CdnWorkerService c
var res = await cws.GetRawClient("q8").GetAsync("/scale" + Request.Path + Request.QueryString);
var outStream = await res.Content.ReadAsStreamAsync();
- return new LruFileCache.Entry() {
+ return new LruFileCache.Entry {
Data = outStream.ReadToEnd().ToArray(),
MimeType = res.Content.Headers.ContentType?.ToString() ?? original.MimeType
};
diff --git a/extra/admin-api/Spacebar.Cdn/Extensions/HttpRequestExtensions.cs b/extra/admin-api/Spacebar.Cdn/Extensions/HttpRequestExtensions.cs
new file mode 100644
index 00000000..f8178540
--- /dev/null
+++ b/extra/admin-api/Spacebar.Cdn/Extensions/HttpRequestExtensions.cs
@@ -0,0 +1,35 @@
+using Microsoft.AspNetCore.Mvc;
+using Spacebar.AdminApi.TestClient.Services.Services;
+
+namespace Spacebar.Cdn.Extensions;
+
+
+public static class HttpRequestExtensions {
+ extension(HttpRequest request) {
+ public DiscordImageResizeParams GetResizeParams() {
+ return new() {
+ Size = request.Query.ContainsKey("size") && uint.TryParse(request.Query["size"], out uint size) ? size : null,
+ Quality = request.Query.ContainsKey("quality") && Enum.TryParse<DiscordImageResizeQuality>(request.Query["quality"], true, out var quality)
+ ? quality
+ : DiscordImageResizeQuality.High,
+ KeepAspectRatio = !request.Query.ContainsKey("keepAspectRatio") || !bool.TryParse(request.Query["keepAspectRatio"], out bool kar) || kar,
+ Passthrough = request.Query.ContainsKey("passthrough") && bool.TryParse(request.Query["passthrough"], out bool pt) && pt,
+ Animated = request.Query.ContainsKey("animated") && bool.TryParse(request.Query["animated"], out bool an) && an,
+ SpacebarAllowUpscale = request.Query.ContainsKey("allowUpscale") && bool.TryParse(request.Query["allowUpscale"], out bool au) && au,
+ SpacebarOptimiseGif = request.Query.ContainsKey("optimiseGif") && bool.TryParse(request.Query["optimiseGif"], out bool og) && og,
+ };
+ }
+ }
+
+ extension (HttpResponse response) {
+ public void SetSuccessCacheHeader() {
+ int cacheDuration = (int)TimeSpan.FromHours(6).TotalSeconds;
+ response.Headers.CacheControl = $"public, max-age={cacheDuration}, s-maxage={cacheDuration}, immutable";
+ }
+
+ public void SetFailureCacheHeader() {
+ int cacheDuration = (int)TimeSpan.FromMinutes(5).TotalSeconds;
+ response.Headers.CacheControl = $"public, max-age={cacheDuration}, s-maxage={cacheDuration}, immutable";
+ }
+ }
+}
\ No newline at end of file
diff --git a/extra/admin-api/Spacebar.Cdn/Extensions/ImageController.cs b/extra/admin-api/Spacebar.Cdn/Extensions/ImageController.cs
index f8178540..9a70fd0d 100644
--- a/extra/admin-api/Spacebar.Cdn/Extensions/ImageController.cs
+++ b/extra/admin-api/Spacebar.Cdn/Extensions/ImageController.cs
@@ -1,35 +1,33 @@
+using ArcaneLibs.Extensions.Streams;
using Microsoft.AspNetCore.Mvc;
using Spacebar.AdminApi.TestClient.Services.Services;
+using Spacebar.Cdn.Services;
+using Spacebar.Interop.Cdn.Abstractions;
namespace Spacebar.Cdn.Extensions;
+[ApiController]
+public class ImageController(LruFileCache lfc, IFileSource fs, CdnWorkerService cws) : ControllerBase {
+ public async Task<IActionResult> GetImage(string path) {
+ DiscordImageResizeParams resizeParams = Request.GetResizeParams();
+ var cacheKey = path + resizeParams.ToSerializedName();
+ if (!Request.Query.Any() || resizeParams.Passthrough) {
+ await using var original = await fs.GetFile(path);
+ return new FileContentResult(original.Stream.ReadToEnd().ToArray(), original.MimeType);
+ }
+
+ var entry = await lfc.GetOrAdd(cacheKey, async () => {
+ var original = await fs.GetFile(path);
+ var res = await cws.GetRawClient("q8").GetAsync("/scale" + path + Request.QueryString);
+ var outStream = await res.Content.ReadAsStreamAsync();
-public static class HttpRequestExtensions {
- extension(HttpRequest request) {
- public DiscordImageResizeParams GetResizeParams() {
- return new() {
- Size = request.Query.ContainsKey("size") && uint.TryParse(request.Query["size"], out uint size) ? size : null,
- Quality = request.Query.ContainsKey("quality") && Enum.TryParse<DiscordImageResizeQuality>(request.Query["quality"], true, out var quality)
- ? quality
- : DiscordImageResizeQuality.High,
- KeepAspectRatio = !request.Query.ContainsKey("keepAspectRatio") || !bool.TryParse(request.Query["keepAspectRatio"], out bool kar) || kar,
- Passthrough = request.Query.ContainsKey("passthrough") && bool.TryParse(request.Query["passthrough"], out bool pt) && pt,
- Animated = request.Query.ContainsKey("animated") && bool.TryParse(request.Query["animated"], out bool an) && an,
- SpacebarAllowUpscale = request.Query.ContainsKey("allowUpscale") && bool.TryParse(request.Query["allowUpscale"], out bool au) && au,
- SpacebarOptimiseGif = request.Query.ContainsKey("optimiseGif") && bool.TryParse(request.Query["optimiseGif"], out bool og) && og,
+ return new LruFileCache.Entry() {
+ Data = outStream.ReadToEnd().ToArray(),
+ MimeType = res.Content.Headers.ContentType?.ToString() ?? original.MimeType
};
- }
- }
-
- extension (HttpResponse response) {
- public void SetSuccessCacheHeader() {
- int cacheDuration = (int)TimeSpan.FromHours(6).TotalSeconds;
- response.Headers.CacheControl = $"public, max-age={cacheDuration}, s-maxage={cacheDuration}, immutable";
- }
+ });
- public void SetFailureCacheHeader() {
- int cacheDuration = (int)TimeSpan.FromMinutes(5).TotalSeconds;
- response.Headers.CacheControl = $"public, max-age={cacheDuration}, s-maxage={cacheDuration}, immutable";
- }
+ // byte array with mime type result
+ return new FileContentResult(entry.Data, entry.MimeType);
}
}
\ No newline at end of file
diff --git a/extra/admin-api/Spacebar.Cdn/Services/SpacebarCdnWorkerConfiguration.cs b/extra/admin-api/Spacebar.Cdn/Services/SpacebarCdnWorkerConfiguration.cs
index 68e9a300..0d3e1023 100644
--- a/extra/admin-api/Spacebar.Cdn/Services/SpacebarCdnWorkerConfiguration.cs
+++ b/extra/admin-api/Spacebar.Cdn/Services/SpacebarCdnWorkerConfiguration.cs
@@ -1,4 +1,4 @@
-using Newtonsoft.Json;
+using System.Text.Json.Serialization;
namespace Spacebar.Cdn.Services;
@@ -7,12 +7,12 @@ public class SpacebarCdnWorkerConfiguration {
config.GetRequiredSection("Spacebar").GetRequiredSection("Cdn").GetRequiredSection("Workers").Bind(this);
}
- [JsonProperty("q8")]
+ [JsonPropertyName("q8")]
public List<string> Q8Workers { get; set; } = [];
- [JsonProperty("q16")]
+ [JsonPropertyName("q16")]
public List<string> Q16Workers { get; set; } = [];
- [JsonProperty("q16-hdri")]
+ [JsonPropertyName("q16-hdri")]
public List<string> Q16HdriWorkers { get; set; } = [];
}
\ No newline at end of file
|