5.2 ImageController.GetImage
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -136,7 +136,7 @@ Each type lives in `src/FrameProcessor/Domain/`. Tests in `tests/FrameProcessor.
|
|||||||
- Call `ImagePipeline.Process`, then `ImageStore.WriteAsync`.
|
- Call `ImagePipeline.Process`, then `ImageStore.WriteAsync`.
|
||||||
- Return `200 { frame, mac, url, processedAt, mqttPublished: false }` (MQTT stubbed).
|
- Return `200 { frame, mac, url, processedAt, mqttPublished: false }` (MQTT stubbed).
|
||||||
|
|
||||||
### [ ] 5.2 `ImageController.GetImage`
|
### [x] 5.2 `ImageController.GetImage`
|
||||||
- Route: `GET /i/{mac}.png`.
|
- Route: `GET /i/{mac}.png`.
|
||||||
- Normalize `{mac}` via `MacAddress.TryParse` → 404 on bad form.
|
- Normalize `{mac}` via `MacAddress.TryParse` → 404 on bad form.
|
||||||
- Look up frame by MAC → 404 if unknown or file absent.
|
- Look up frame by MAC → 404 if unknown or file absent.
|
||||||
|
|||||||
40
src/FrameProcessor/Controllers/ImageController.cs
Normal file
40
src/FrameProcessor/Controllers/ImageController.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
using FrameProcessor.Configuration;
|
||||||
|
using FrameProcessor.Domain;
|
||||||
|
using FrameProcessor.Storage;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace FrameProcessor.Controllers;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
public sealed class ImageController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly FramesRegistry _frames;
|
||||||
|
private readonly ImageStore _store;
|
||||||
|
|
||||||
|
public ImageController(FramesRegistry frames, ImageStore store)
|
||||||
|
{
|
||||||
|
_frames = frames;
|
||||||
|
_store = store;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("/i/{mac}.png")]
|
||||||
|
public IActionResult GetImage(string mac)
|
||||||
|
{
|
||||||
|
if (!MacAddress.TryParse(mac, out var macAddress) || !_frames.TryGetByMac(macAddress, out _))
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_store.TryGetPath(macAddress, out var path))
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
var mtime = System.IO.File.GetLastWriteTimeUtc(path);
|
||||||
|
Response.Headers.CacheControl = "no-store";
|
||||||
|
Response.Headers.ETag = $"\"{mtime.Ticks:x}\"";
|
||||||
|
|
||||||
|
var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||||
|
return File(stream, "image/png");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user