Skip to main content

web_net/
events.rs

1//! What web-net tells the rest of the system, and where it asks whether a
2//! request may continue.
3//!
4//! A security component that cannot report what it sees is a detour, not a
5//! defence. Every refusal, denial, and failure is reported through
6//! [`Events`], so a detection or gate layer hears about a probe the moment
7//! web-net turns it away. Events carry ids, codes, and statuses, never
8//! request bytes.
9
10use serve_net::{Envelope, Verdict};
11
12use crate::RequestId;
13
14/// What kind of thing happened.
15#[non_exhaustive]
16#[derive(Clone, Copy, Debug, PartialEq, Eq)]
17pub enum EventKind {
18    /// Refused before a handler: a malformed path, an unknown host, no
19    /// route, a method the route does not take.
20    Refused,
21    /// A gate denied the request.
22    Denied,
23    /// A handler or render failed (any handler error, and every 5xx).
24    Failed,
25    /// A handler panicked; answered with 500.
26    Panicked,
27    /// A checkpoint stopped the request in flight.
28    Revoked,
29}
30
31/// One event.
32#[non_exhaustive]
33#[derive(Debug)]
34pub struct Event<'a> {
35    /// What happened.
36    pub kind: EventKind,
37    /// The request's reference.
38    pub id: RequestId,
39    /// The matched route's pattern, if routing got that far.
40    pub route: Option<&'a str>,
41    /// The status answered.
42    pub status: u16,
43    /// A stable code (`"url.encoded_slash"`, a gate's code, a handler's).
44    pub code: &'static str,
45    /// The underlying error, for the logs only.
46    pub source: Option<&'a (dyn std::error::Error + 'static)>,
47}
48
49/// Where web-net reports. Every method has an empty default; the default
50/// implementation, [`NoEvents`], reports nothing.
51///
52/// Called on the request path: keep it to a counter or a queue push.
53pub trait Events: Send + Sync + 'static {
54    /// One event.
55    fn event(&self, event: &Event<'_>) {
56        let _ = event;
57    }
58}
59
60/// Reports nothing.
61#[derive(Clone, Copy, Debug, Default)]
62pub struct NoEvents;
63
64impl Events for NoEvents {}
65
66/// A point in web-net's pipeline where a checkpoint runs.
67#[non_exhaustive]
68#[derive(Clone, Copy, Debug, PartialEq, Eq)]
69pub enum Stage {
70    /// After the route's access check passed, before any hook or handler.
71    Authorized,
72    /// Before a page is rendered.
73    BeforeRender,
74}
75
76/// Revocation in flight: a ban, a revoked session, or a lockdown that
77/// arrives while a request is being handled. serve-net's own checkpoint
78/// covers admission and the moment before the reply leaves; this one covers
79/// the points in between that only web-net knows.
80///
81/// A checkpoint backed by remote state fails closed (denies) when the
82/// remote cannot be reached.
83pub trait Checkpoint: Send + Sync + 'static {
84    /// Decides at one stage.
85    fn check(&self, env: &Envelope, at: Stage) -> Verdict;
86}