1use std::fmt;
2
3macro_rules! unpack_octets_4 {
16 ($buf:expr, $offset:expr, $tip:ty) => {
18 (($buf[$offset + 0] as $tip) << 24)
19 | (($buf[$offset + 1] as $tip) << 16)
20 | (($buf[$offset + 2] as $tip) << 8)
21 | (($buf[$offset + 3] as $tip) << 0)
22 };
23}
24
25#[cfg(test)]
26mod tests {
27 #[test]
28 fn test_unpack_octets_4() {
29 let buf: [u8; 4] = [0, 0, 0, 1];
30 assert_eq!(1u32, unpack_octets_4!(buf, 0, u32));
31 }
32}
33
34mod data;
35mod go_away;
36mod head;
37mod headers;
38mod ping;
39mod priority;
40mod protocol;
41mod reason;
42mod reset;
43mod settings;
44mod stream_id;
45mod util;
46mod window_update;
47
48pub use self::data::Data;
49pub use self::go_away::GoAway;
50pub use self::head::{Head, Kind};
51pub use self::headers::{Headers, PseudoHeaders};
52pub use self::ping::Ping;
53pub use self::priority::{Priority, StreamDependency};
54pub use self::protocol::Protocol;
55pub use self::reason::Reason;
56pub use self::reset::Reset;
57pub use self::settings::Settings;
58pub use self::stream_id::{StreamId, StreamIdOverflow};
59pub use self::window_update::WindowUpdate;
60
61pub use self::settings::{
63 DEFAULT_INITIAL_WINDOW_SIZE, DEFAULT_MAX_FRAME_SIZE, DEFAULT_SETTINGS_HEADER_TABLE_SIZE,
64 MAX_INITIAL_WINDOW_SIZE, MAX_MAX_FRAME_SIZE,
65};
66
67use crate::hpack;
68
69pub type FrameSize = u32;
70pub type WindowSize = u32;
71
72pub const HEADER_LEN: usize = 9;
73
74#[derive(Clone)]
75pub enum Frame {
76 Data(Data),
77 Headers(Headers),
78 Priority(Priority),
79 Settings(Settings),
80 Ping(Ping),
81 GoAway(GoAway),
82 WindowUpdate(WindowUpdate),
83 Reset(Reset),
84}
85
86impl fmt::Debug for Frame {
87 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
88 match self {
89 Frame::Data(frame) => fmt::Debug::fmt(frame, fmt),
90 Frame::Headers(frame) => fmt::Debug::fmt(frame, fmt),
91 Frame::Priority(frame) => fmt::Debug::fmt(frame, fmt),
92 Frame::Settings(frame) => fmt::Debug::fmt(frame, fmt),
93 Frame::Ping(frame) => fmt::Debug::fmt(frame, fmt),
94 Frame::GoAway(frame) => fmt::Debug::fmt(frame, fmt),
95 Frame::WindowUpdate(frame) => fmt::Debug::fmt(frame, fmt),
96 Frame::Reset(frame) => fmt::Debug::fmt(frame, fmt),
97 }
98 }
99}
100
101#[derive(thiserror::Error, Debug, Copy, Clone, PartialEq, Eq)]
103pub enum FrameError {
104 #[error("A length value other than 8 was set on a PING message")]
106 BadFrameSize,
107
108 #[error("Frame size exceeded")]
110 MaxFrameSize,
111
112 #[error("The padding length was larger than the frame-header-specified length of the payload")]
115 TooMuchPadding,
116
117 #[error("An invalid setting value was provided")]
119 InvalidSettingValue,
120
121 #[error(
124 "The payload length specified by the frame header was not the value necessary for the specific frame type"
125 )]
126 InvalidPayloadLength,
127
128 #[error("Received a payload with an ACK settings frame")]
130 InvalidPayloadAckSettings,
131
132 #[error("An invalid stream identifier was provided")]
137 InvalidStreamId,
138
139 #[error("A request or response is malformed")]
141 MalformedMessage,
142
143 #[error("An invalid stream dependency ID was provided")]
148 InvalidDependencyId,
149
150 #[error("An invalid preface")]
152 InvalidPreface,
153
154 #[error("Unexpected push promise")]
156 UnexpectedPushPromise,
157
158 #[error("{0}")]
160 Continuation(#[from] FrameContinuationError),
161
162 #[error("{0}")]
164 Hpack(#[from] hpack::DecoderError),
165}
166
167#[derive(thiserror::Error, Debug, Copy, Clone, PartialEq, Eq)]
168pub enum FrameContinuationError {
169 #[error("Continuation frame is expected")]
171 Expected,
172
173 #[error("Continuation frame is unexpected")]
175 Unexpected,
176
177 #[error("Continuation frame's stream id is unexpected")]
179 UnknownStreamId,
180
181 #[error("Max left over size")]
183 MaxLeftoverSize,
184
185 #[error("Max count of Continuations")]
187 MaxContinuations,
188
189 #[error("Malformed frame")]
191 Malformed,
192}