using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace ZB.MOM.WW.ScadaBridge.InboundAPI;
///
/// Endpoint filter applied to POST /api/{methodName} that enforces two
/// cross-cutting guards before the request handler runs:
///
///
///
/// Request body size cap. Oversized bodies are rejected with HTTP
/// 413 before being buffered into a JsonDocument — and before any relay,
/// so a standby never buffers or forwards a body the active node would refuse.
///
///
/// Active-node gating. Method scripts execute only on the active central node.
/// A standby RELAYS the request to the active peer through
/// when peers are configured
/// (), and otherwise
/// returns HTTP 503 STANDBY_NODE. A request that already carries
/// is never
/// relayed again (one-hop loop guard) — it gets the 503, stamped with
/// so the relaying
/// peer knows to try its next endpoint.
///
///
///
public sealed class InboundApiEndpointFilter : IEndpointFilter
{
///
/// key set when this node relayed the request to the
/// active peer. AuditWriteMiddleware reads it to skip its own audit row (the
/// active node audits the call it executed).
///
public const string RelayedToActiveItemKey = "ScadaBridge.InboundApi.RelayedToActive";
private readonly ILogger _logger;
private readonly IOptionsMonitor _options;
/// Initializes a new with the given logger and options.
/// Logger for request rejection diagnostics.
/// Live-reloadable inbound API options, read per-request.
public InboundApiEndpointFilter(
ILogger logger,
IOptionsMonitor options)
{
_logger = logger;
_options = options;
}
/// Applies the request body size check and active-node gating/relay before delegating to the next filter or handler.
/// The endpoint filter invocation context containing the HTTP context and arguments.
/// The next filter or endpoint handler in the pipeline.
/// A value task that resolves to the filter pipeline result, a relayed peer response, or an error result if gating fails.
public async ValueTask