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 use self::Frame::*;
89
90 match *self {
91 Data(ref frame) => fmt::Debug::fmt(frame, fmt),
92 Headers(ref frame) => fmt::Debug::fmt(frame, fmt),
93 Priority(ref frame) => fmt::Debug::fmt(frame, fmt),
94 Settings(ref frame) => fmt::Debug::fmt(frame, fmt),
95 Ping(ref frame) => fmt::Debug::fmt(frame, fmt),
96 GoAway(ref frame) => fmt::Debug::fmt(frame, fmt),
97 WindowUpdate(ref frame) => fmt::Debug::fmt(frame, fmt),
98 Reset(ref frame) => fmt::Debug::fmt(frame, fmt),
99 }
100 }
101}
102
103#[derive(thiserror::Error, Debug, Copy, Clone, PartialEq, Eq)]
105pub enum FrameError {
106 #[error("A length value other than 8 was set on a PING message")]
108 BadFrameSize,
109
110 #[error("Frame size exceeded")]
112 MaxFrameSize,
113
114 #[error("The padding length was larger than the frame-header-specified length of the payload")]
117 TooMuchPadding,
118
119 #[error("An invalid setting value was provided")]
121 InvalidSettingValue,
122
123 #[error(
126 "The payload length specified by the frame header was not the value necessary for the specific frame type"
127 )]
128 InvalidPayloadLength,
129
130 #[error("Received a payload with an ACK settings frame")]
132 InvalidPayloadAckSettings,
133
134 #[error("An invalid stream identifier was provided")]
139 InvalidStreamId,
140
141 #[error("A request or response is malformed")]
143 MalformedMessage,
144
145 #[error("An invalid stream dependency ID was provided")]
150 InvalidDependencyId,
151
152 #[error("An invalid preface")]
154 InvalidPreface,
155
156 #[error("Unexpected push promise")]
158 UnexpectedPushPromise,
159
160 #[error("{0}")]
162 Continuation(#[from] FrameContinuationError),
163
164 #[error("{0}")]
166 Hpack(#[from] hpack::DecoderError),
167}
168
169#[derive(thiserror::Error, Debug, Copy, Clone, PartialEq, Eq)]
170pub enum FrameContinuationError {
171 #[error("Continuation frame is expected")]
173 Expected,
174
175 #[error("Continuation frame is unexpected")]
177 Unexpected,
178
179 #[error("Continuation frame's stream id is unexpected")]
181 UnknownStreamId,
182
183 #[error("Max left over size")]
185 MaxLeftoverSize,
186
187 #[error("Max count of Continuations")]
189 MaxContinuations,
190
191 #[error("Malformed frame")]
193 Malformed,
194}