Skip to main content

ntex_h2/
control.rs

1use std::io;
2
3use crate::frame::Frame;
4use crate::{error, frame, stream::StreamRef};
5
6#[derive(Debug)]
7pub enum Control<E> {
8    /// Connection is prepared to disconnect
9    Disconnect(Reason<E>),
10    /// Protocol dispatcher is terminated
11    Terminated(Terminated),
12}
13
14#[derive(Debug)]
15/// Disconnect reason
16pub enum Reason<E> {
17    /// Application level error from publish service
18    Error(Error<E>),
19    /// Protocol level error
20    ProtocolError(ConnectionError),
21    /// Remote `GoAway` is received
22    GoAway(GoAway),
23    /// Peer is gone
24    PeerGone(PeerGone),
25}
26
27#[derive(Clone, Debug)]
28pub struct ControlAck {
29    pub(crate) frame: Option<Frame>,
30}
31
32impl<E> Control<E> {
33    /// Create a new `Control` message for app level errors
34    pub(super) fn error(err: E, stream: Option<&StreamRef>) -> Self {
35        Control::Disconnect(Reason::Error(Error::new(err, stream)))
36    }
37
38    /// Create a new `Control` message from GOAWAY packet.
39    pub(super) fn go_away(frm: frame::GoAway) -> Self {
40        Control::Disconnect(Reason::GoAway(GoAway(frm)))
41    }
42
43    /// Create a new `Control` message from DISCONNECT packet.
44    pub(super) fn peer_gone(err: Option<io::Error>) -> Self {
45        Control::Disconnect(Reason::PeerGone(PeerGone(err)))
46    }
47
48    /// Create a new `Control` message for protocol level errors
49    pub(super) fn proto_error(err: error::ConnectionError) -> Self {
50        Control::Disconnect(Reason::ProtocolError(ConnectionError::new(err)))
51    }
52
53    pub(super) fn terminated() -> Self {
54        Control::Terminated(Terminated)
55    }
56
57    /// Default ack impl
58    pub fn ack(self) -> ControlAck {
59        match self {
60            Control::Disconnect(item) => item.ack(),
61            Control::Terminated(item) => item.ack(),
62        }
63    }
64}
65
66impl<E> Reason<E> {
67    /// Default ack impl
68    pub fn ack(self) -> ControlAck {
69        match self {
70            Reason::Error(item) => item.ack(),
71            Reason::ProtocolError(item) => item.ack(),
72            Reason::GoAway(item) => item.ack(),
73            Reason::PeerGone(item) => item.ack(),
74        }
75    }
76}
77
78/// Application level error
79#[derive(Debug)]
80pub struct Error<E> {
81    err: E,
82    goaway: frame::GoAway,
83}
84
85impl<E> Error<E> {
86    fn new(err: E, stream: Option<&StreamRef>) -> Self {
87        let goaway = if let Some(stream) = stream {
88            frame::GoAway::new(frame::Reason::INTERNAL_ERROR).set_last_stream_id(stream.id())
89        } else {
90            frame::GoAway::new(frame::Reason::INTERNAL_ERROR)
91        };
92
93        Self { err, goaway }
94    }
95
96    #[inline]
97    /// Returns reference to mqtt error
98    pub fn get_ref(&self) -> &E {
99        &self.err
100    }
101
102    #[inline]
103    #[must_use]
104    /// Set reason code for go away packet
105    pub fn reason(mut self, reason: frame::Reason) -> Self {
106        self.goaway = self.goaway.set_reason(reason);
107        self
108    }
109
110    #[inline]
111    /// Ack service error, return disconnect packet and close connection.
112    pub fn ack(self) -> ControlAck {
113        ControlAck {
114            frame: Some(self.goaway.into()),
115        }
116    }
117}
118
119/// Dispatcher has been terminated
120#[derive(Debug)]
121pub struct Terminated;
122
123impl Terminated {
124    #[inline]
125    /// convert packet to a result
126    pub fn ack(self) -> ControlAck {
127        ControlAck { frame: None }
128    }
129}
130
131/// Protocol level error
132#[derive(Debug)]
133pub struct ConnectionError {
134    err: error::ConnectionError,
135    frm: frame::GoAway,
136}
137
138impl ConnectionError {
139    pub fn new(err: error::ConnectionError) -> Self {
140        Self {
141            frm: err.to_goaway(),
142            err,
143        }
144    }
145
146    #[inline]
147    /// Returns reference to a protocol error
148    pub fn get_ref(&self) -> &error::ConnectionError {
149        &self.err
150    }
151
152    #[inline]
153    #[must_use]
154    /// Set reason code for go away packet
155    pub fn reason(mut self, reason: frame::Reason) -> Self {
156        self.frm = self.frm.set_reason(reason);
157        self
158    }
159
160    #[inline]
161    /// Ack protocol error, return disconnect packet and close connection.
162    pub fn ack(self) -> ControlAck {
163        ControlAck {
164            frame: Some(self.frm.into()),
165        }
166    }
167}
168
169#[derive(Debug)]
170pub struct PeerGone(pub(super) Option<io::Error>);
171
172impl PeerGone {
173    /// Returns error reference
174    pub fn err(&self) -> Option<&io::Error> {
175        self.0.as_ref()
176    }
177
178    /// Take error
179    pub fn take(&mut self) -> Option<io::Error> {
180        self.0.take()
181    }
182
183    pub fn ack(self) -> ControlAck {
184        ControlAck { frame: None }
185    }
186}
187
188#[derive(Debug)]
189pub struct GoAway(frame::GoAway);
190
191impl GoAway {
192    /// Returns error reference
193    pub fn frame(&self) -> &frame::GoAway {
194        &self.0
195    }
196
197    pub fn ack(self) -> ControlAck {
198        ControlAck { frame: None }
199    }
200}