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#[derive(Debug)]
33pub struct Event<'a> {
34    /// What happened.
35    pub kind: EventKind,
36    /// The request's reference.
37    pub id: RequestId,
38    /// The matched route's pattern, if routing got that far.
39    pub route: Option<&'a str>,
40    /// The status answered.
41    pub status: u16,
42    /// A stable code (`"url.encoded_slash"`, a gate's code, a handler's).
43    pub code: &'static str,
44    /// The underlying error, for the logs only.
45    pub source: Option<&'a (dyn std::error::Error + 'static)>,
46}
47
48/// Where web-net reports. Every method has an empty default; the default
49/// implementation, [`NoEvents`], reports nothing.
50///
51/// Called on the request path: keep it to a counter or a queue push.
52pub trait Events: Send + Sync + 'static {
53    /// One event.
54    fn event(&self, event: &Event<'_>) {
55        let _ = event;
56    }
57}
58
59/// Reports nothing.
60#[derive(Clone, Copy, Debug, Default)]
61pub struct NoEvents;
62
63impl Events for NoEvents {}
64
65/// A point in web-net's pipeline where a checkpoint runs.
66#[non_exhaustive]
67#[derive(Clone, Copy, Debug, PartialEq, Eq)]
68pub enum Stage {
69    /// After the route's access check passed, before any hook or handler.
70    Authorized,
71    /// Before a page is rendered.
72    BeforeRender,
73}
74
75/// Revocation in flight: a ban, a revoked session, or a lockdown that
76/// arrives while a request is being handled. serve-net's own checkpoint
77/// covers admission and the moment before the reply leaves; this one covers
78/// the points in between that only web-net knows.
79///
80/// A checkpoint backed by remote state fails closed (denies) when the
81/// remote cannot be reached.
82pub trait Checkpoint: Send + Sync + 'static {
83    /// Decides at one stage.
84    fn check(&self, env: &Envelope, at: Stage) -> Verdict;
85}