pub trait Gate:
Send
+ Sync
+ 'static {
type Ticket: Send + 'static;
// Required methods
fn admit(
&self,
info: &ConnectionInfo,
stage: AdmitStage,
) -> Result<Admitted<Self::Ticket>, Refusal>;
fn readmit(
&self,
ticket: &mut Self::Ticket,
info: &ConnectionInfo,
) -> Result<(), Refusal>;
fn check(
&self,
ticket: &mut Self::Ticket,
write: &WriteCheck,
) -> Result<(), Denial>;
// Provided method
fn closed(
&self,
ticket: Self::Ticket,
info: &ConnectionInfo,
reason: CloseReason,
) { ... }
}Expand description
Decides who may connect and whether bytes may still leave.
net-io calls admit after accept and before any read, readmit after a
trusted PROXY header, check before every write system call, and closed
exactly once when an admitted connection closes. A method that panics counts
as a refusal or a denial (fail closed).
§Examples
use net_io::{Admitted, AdmitStage, CloseReason, ConnectionInfo, Denial, Gate, GateTag, Lane, Refusal, WriteCheck};
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
/// One global kill switch and a count of open connections.
struct Switch { revoked: AtomicBool, open: AtomicU64 }
impl Gate for Switch {
type Ticket = ();
fn admit(&self, info: &ConnectionInfo, _stage: AdmitStage) -> Result<Admitted<()>, Refusal> {
if self.revoked.load(Ordering::Acquire) {
return Err(Refusal::Reset { code: 1 });
}
let lane = if info.client_addr().is_some_and(|a| a.ip().is_loopback()) { Lane(0) } else { Lane(3) };
self.open.fetch_add(1, Ordering::Relaxed);
Ok(Admitted { lane, ticket: (), tag: GateTag(0) })
}
fn readmit(&self, _ticket: &mut (), _info: &ConnectionInfo) -> Result<(), Refusal> {
Ok(())
}
fn check(&self, _ticket: &mut (), _write: &WriteCheck) -> Result<(), Denial> {
if self.revoked.load(Ordering::Acquire) { Err(Denial { code: 503 }) } else { Ok(()) }
}
fn closed(&self, _ticket: (), _info: &ConnectionInfo, _reason: CloseReason) {
self.open.fetch_sub(1, Ordering::Relaxed);
}
}
let gate = Switch { revoked: AtomicBool::new(false), open: AtomicU64::new(0) };
let info = ConnectionInfo::for_testing("127.0.0.1:9".parse().unwrap());
let admitted = gate.admit(&info, AdmitStage::Accept).unwrap();
assert_eq!(admitted.lane, Lane(0));Required Associated Types§
Required Methods§
Sourcefn admit(
&self,
info: &ConnectionInfo,
stage: AdmitStage,
) -> Result<Admitted<Self::Ticket>, Refusal>
fn admit( &self, info: &ConnectionInfo, stage: AdmitStage, ) -> Result<Admitted<Self::Ticket>, Refusal>
Provided Methods§
Sourcefn closed(
&self,
ticket: Self::Ticket,
info: &ConnectionInfo,
reason: CloseReason,
)
fn closed( &self, ticket: Self::Ticket, info: &ConnectionInfo, reason: CloseReason, )
Exactly once per admitted connection, after it closed, with its one close reason.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".