1use core::fmt;
4
5#[derive(Clone, Copy, Debug, Eq, PartialEq)]
7pub enum Http2ParseError {
8 Incomplete {
10 required: usize,
12 available: usize,
14 },
15 ClientPrefaceMismatch {
17 offset: usize,
19 expected: u8,
21 actual: u8,
23 },
24 PayloadTooLarge {
26 maximum: usize,
28 actual: usize,
30 },
31 WrongFrameType {
33 expected: super::types::Http2FrameType,
35 actual: super::types::Http2FrameType,
37 },
38 ZeroStreamId,
40 ExpectedZeroStreamId,
42 FrameSizeMismatch {
44 expected: usize,
46 actual: usize,
48 },
49 ZeroWindowIncrement,
51 SettingsPayloadLength {
53 actual: usize,
55 },
56 SettingsAckPayload {
58 actual: usize,
60 },
61 InvalidSettingValue {
63 id: super::types::Http2SettingId,
65 value: u32,
67 },
68 ZeroPromisedStreamId,
70 InvalidPadding {
72 padding_length: u8,
74 payload_length: usize,
76 },
77 MalformedPayload {
79 required: usize,
81 available: usize,
83 },
84}
85
86impl fmt::Display for Http2ParseError {
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 match self {
89 Self::Incomplete {
90 required,
91 available,
92 } => write!(
93 f,
94 "HTTP/2 input is incomplete: need {required} bytes, have {available}"
95 ),
96 Self::ClientPrefaceMismatch {
97 offset,
98 expected,
99 actual,
100 } => write!(
101 f,
102 "HTTP/2 client preface mismatch at byte {offset}: expected {expected}, got {actual}"
103 ),
104 Self::PayloadTooLarge { maximum, actual } => write!(
105 f,
106 "HTTP/2 frame payload is too large: maximum {maximum}, got {actual}"
107 ),
108 Self::WrongFrameType { expected, actual } => write!(
109 f,
110 "HTTP/2 frame type mismatch: expected {}, got {}",
111 expected.raw(),
112 actual.raw()
113 ),
114 Self::ZeroStreamId => f.write_str("HTTP/2 frame requires a nonzero stream identifier"),
115 Self::ExpectedZeroStreamId => {
116 f.write_str("HTTP/2 frame requires a zero stream identifier")
117 }
118 Self::FrameSizeMismatch { expected, actual } => write!(
119 f,
120 "HTTP/2 fixed-layout frame payload length mismatch: expected {expected}, got {actual}"
121 ),
122 Self::ZeroWindowIncrement => {
123 f.write_str("HTTP/2 WINDOW_UPDATE frame requires a nonzero increment")
124 }
125 Self::SettingsPayloadLength { actual } => write!(
126 f,
127 "HTTP/2 SETTINGS payload length must be a multiple of 6, got {actual}"
128 ),
129 Self::SettingsAckPayload { actual } => write!(
130 f,
131 "HTTP/2 SETTINGS ACK frame must have an empty payload, got {actual} bytes"
132 ),
133 Self::InvalidSettingValue { id, value } => write!(
134 f,
135 "HTTP/2 SETTINGS parameter {} has invalid value {value}",
136 id.raw()
137 ),
138 Self::ZeroPromisedStreamId => {
139 f.write_str("HTTP/2 PUSH_PROMISE requires a nonzero promised stream identifier")
140 }
141 Self::InvalidPadding {
142 padding_length,
143 payload_length,
144 } => write!(
145 f,
146 "HTTP/2 padding length {padding_length} is invalid for payload length {payload_length}"
147 ),
148 Self::MalformedPayload {
149 required,
150 available,
151 } => write!(
152 f,
153 "HTTP/2 payload section is truncated: need {required} bytes, have {available}"
154 ),
155 }
156 }
157}
158
159#[derive(Clone, Copy, Debug, Eq, PartialEq)]
161pub enum Http2StreamIdError {
162 ReservedBitSet,
164}
165
166impl fmt::Display for Http2StreamIdError {
167 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
168 match self {
169 Self::ReservedBitSet => {
170 f.write_str("HTTP/2 stream identifier has its reserved bit set")
171 }
172 }
173 }
174}
175
176#[derive(Clone, Copy, Debug, Eq, PartialEq)]
178pub enum Http2BuildError {
179 ZeroStreamId,
181 ReservedStreamId,
183 ZeroWindowIncrement,
185 ReservedWindowIncrement,
187 SettingsAckPayload {
189 actual: usize,
191 },
192 InvalidSettingValue {
194 id: super::types::Http2SettingId,
196 value: u32,
198 },
199 ReservedLastStreamId,
201 DataPaddedFlagSet,
203 HeadersPaddedFlagSet,
205 HeadersPriorityFlagSet,
207 PushPromisePaddedFlagSet,
209 ZeroPromisedStreamId,
211 ReservedPromisedStreamId,
213 PayloadTooLarge {
215 maximum: usize,
217 actual: usize,
219 },
220 BufferTooShort {
222 required: usize,
224 available: usize,
226 },
227}
228
229impl fmt::Display for Http2BuildError {
230 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231 match self {
232 Self::ZeroStreamId => {
233 f.write_str("outgoing HTTP/2 frame requires a nonzero stream identifier")
234 }
235 Self::ReservedStreamId => {
236 f.write_str("outgoing HTTP/2 stream identifier has its reserved bit set")
237 }
238 Self::ZeroWindowIncrement => {
239 f.write_str("outgoing HTTP/2 WINDOW_UPDATE requires a nonzero increment")
240 }
241 Self::ReservedWindowIncrement => f.write_str(
242 "outgoing HTTP/2 WINDOW_UPDATE increment has its reserved bit set",
243 ),
244 Self::SettingsAckPayload { actual } => write!(
245 f,
246 "outgoing HTTP/2 SETTINGS ACK frame must have an empty payload, got {actual} bytes"
247 ),
248 Self::InvalidSettingValue { id, value } => write!(
249 f,
250 "outgoing HTTP/2 SETTINGS parameter {} has invalid value {value}",
251 id.raw()
252 ),
253 Self::ReservedLastStreamId => {
254 f.write_str("outgoing HTTP/2 GOAWAY last-stream identifier has its reserved bit set")
255 }
256 Self::DataPaddedFlagSet => f.write_str(
257 "outgoing HTTP/2 DATA flags must not include PADDED; use the padding length argument",
258 ),
259 Self::HeadersPaddedFlagSet => f.write_str(
260 "outgoing HTTP/2 HEADERS flags must not include PADDED; use the padding length argument",
261 ),
262 Self::HeadersPriorityFlagSet => f.write_str(
263 "outgoing HTTP/2 HEADERS flags must not include PRIORITY; use the priority argument",
264 ),
265 Self::PushPromisePaddedFlagSet => f.write_str(
266 "outgoing HTTP/2 PUSH_PROMISE flags must not include PADDED; use the padding length argument",
267 ),
268 Self::ZeroPromisedStreamId => {
269 f.write_str("outgoing HTTP/2 PUSH_PROMISE requires a nonzero promised stream identifier")
270 }
271 Self::ReservedPromisedStreamId => f.write_str(
272 "outgoing HTTP/2 PUSH_PROMISE promised stream identifier has its reserved bit set",
273 ),
274 Self::PayloadTooLarge { maximum, actual } => write!(
275 f,
276 "HTTP/2 payload is too large: maximum {maximum}, got {actual}"
277 ),
278 Self::BufferTooShort {
279 required,
280 available,
281 } => write!(
282 f,
283 "HTTP/2 buffer is too short: need {required} bytes, have {available}"
284 ),
285 }
286 }
287}