Skip to main content

actix_proxy_protocol/service/
error.rs

1use std::{convert::Infallible, fmt, io};
2
3use proxyproto::ParseError;
4
5/// Controls whether incoming streams must start with a PROXY protocol header.
6#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
7pub enum HeaderPolicy {
8    /// Reject streams that do not start with a PROXY protocol header.
9    #[default]
10    Required,
11
12    /// Accept streams without a PROXY protocol header and replay any bytes read during detection.
13    Optional,
14}
15
16impl HeaderPolicy {
17    pub(super) const fn is_required(self) -> bool {
18        matches!(self, Self::Required)
19    }
20}
21
22/// PROXY protocol acceptor or stream parsing error.
23#[derive(Debug)]
24pub enum ProxyProtocolError<SvcErr = Infallible> {
25    /// An I/O error occurred while reading the header prelude.
26    Io(io::Error),
27
28    /// The stream did not start with a PROXY protocol header.
29    MissingHeader,
30
31    /// The stream started with a PROXY protocol header, but it was invalid.
32    Parse(ParseError),
33
34    /// Wraps service errors.
35    Service(SvcErr),
36}
37
38impl<SvcErr> fmt::Display for ProxyProtocolError<SvcErr>
39where
40    SvcErr: fmt::Display,
41{
42    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43        match self {
44            Self::Io(err) => write!(f, "I/O error while reading PROXY protocol header: {err}"),
45            Self::MissingHeader => f.write_str("missing PROXY protocol header"),
46            Self::Parse(err) => write!(f, "invalid PROXY protocol header: {err}"),
47            Self::Service(err) => fmt::Display::fmt(err, f),
48        }
49    }
50}
51
52impl<SvcErr> std::error::Error for ProxyProtocolError<SvcErr>
53where
54    SvcErr: std::error::Error + 'static,
55{
56    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
57        match self {
58            Self::Io(err) => Some(err),
59            Self::MissingHeader => None,
60            Self::Parse(err) => Some(err),
61            Self::Service(err) => Some(err),
62        }
63    }
64}
65
66impl ProxyProtocolError<Infallible> {
67    /// Casts the infallible service error type returned from acceptors into caller's type.
68    pub fn into_service_error<SvcErr>(self) -> ProxyProtocolError<SvcErr> {
69        match self {
70            Self::Io(err) => ProxyProtocolError::Io(err),
71            Self::MissingHeader => ProxyProtocolError::MissingHeader,
72            Self::Parse(err) => ProxyProtocolError::Parse(err),
73            Self::Service(err) => match err {},
74        }
75    }
76}
77
78impl<SvcErr> From<io::Error> for ProxyProtocolError<SvcErr> {
79    fn from(err: io::Error) -> Self {
80        Self::Io(err)
81    }
82}
83
84impl<SvcErr> From<ParseError> for ProxyProtocolError<SvcErr> {
85    fn from(err: ParseError) -> Self {
86        Self::Parse(err)
87    }
88}