feat: add public image proxy and wire TrackCard cover art to api/image/{entryKey}
This commit is contained in:
@@ -12,7 +12,7 @@
|
|||||||
<a href="@trackHref" class="deepdrft-track-card-link">
|
<a href="@trackHref" class="deepdrft-track-card-link">
|
||||||
@if (!string.IsNullOrEmpty(TrackModel?.ImagePath))
|
@if (!string.IsNullOrEmpty(TrackModel?.ImagePath))
|
||||||
{
|
{
|
||||||
<div class="deepdrft-track-card-bg" style="background-image: url('@TrackModel.ImagePath');">
|
<div class="deepdrft-track-card-bg" style="background-image: url('api/image/@Uri.EscapeDataString(TrackModel.ImagePath)');">
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
}
|
}
|
||||||
else if (!string.IsNullOrEmpty(TrackModel?.ImagePath))
|
else if (!string.IsNullOrEmpty(TrackModel?.ImagePath))
|
||||||
{
|
{
|
||||||
<div class="deepdrft-track-card-bg" style="background-image: url('@TrackModel.ImagePath');">
|
<div class="deepdrft-track-card-bg" style="background-image: url('api/image/@Uri.EscapeDataString(TrackModel.ImagePath)');">
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace DeepDrftPublic.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Proxies public image API calls to DeepDrftAPI so the browser never makes
|
||||||
|
/// cross-origin requests. Mirrors <see cref="TrackProxyController"/>: the WASM
|
||||||
|
/// client issues relative <c>api/image/{entryKey}</c> requests against this host,
|
||||||
|
/// which forwards them upstream. SSR prerender calls DeepDrftAPI directly via the
|
||||||
|
/// same named client — no proxy hop needed on the server side.
|
||||||
|
/// </summary>
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/image")]
|
||||||
|
public class ImageProxyController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly HttpClient _upstream;
|
||||||
|
private readonly ILogger<ImageProxyController> _logger;
|
||||||
|
|
||||||
|
public ImageProxyController(IHttpClientFactory httpClientFactory, ILogger<ImageProxyController> logger)
|
||||||
|
{
|
||||||
|
_upstream = httpClientFactory.CreateClient("DeepDrft.API");
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Proxies image binary streaming by vault entry key from DeepDrftAPI.</summary>
|
||||||
|
[HttpGet("{entryKey}")]
|
||||||
|
public async Task<ActionResult> GetImage(string entryKey, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Proxying image {EntryKey}", entryKey);
|
||||||
|
|
||||||
|
var path = $"api/image/{Uri.EscapeDataString(entryKey)}";
|
||||||
|
|
||||||
|
HttpResponseMessage upstream;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
upstream = await _upstream.GetAsync(path, HttpCompletionOption.ResponseHeadersRead, ct);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Upstream call to DeepDrftAPI image/{EntryKey} failed", entryKey);
|
||||||
|
return StatusCode(502, "Upstream unavailable");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!upstream.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
upstream.Dispose();
|
||||||
|
_logger.LogWarning("DeepDrftAPI image/{EntryKey} returned {Status}", entryKey, (int)upstream.StatusCode);
|
||||||
|
return StatusCode((int)upstream.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do NOT dispose upstream here — File() takes ownership of the response stream
|
||||||
|
// and disposes it after the body is sent.
|
||||||
|
var contentType = upstream.Content.Headers.ContentType?.ToString() ?? "application/octet-stream";
|
||||||
|
var contentLength = upstream.Content.Headers.ContentLength;
|
||||||
|
|
||||||
|
if (contentLength.HasValue)
|
||||||
|
Response.ContentLength = contentLength.Value;
|
||||||
|
|
||||||
|
var stream = await upstream.Content.ReadAsStreamAsync(ct);
|
||||||
|
HttpContext.Response.RegisterForDispose(upstream);
|
||||||
|
return File(stream, contentType, enableRangeProcessing: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user