1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 use std::ops::{Deref, DerefMut};
15
16 use super::frame::StreamId;
17 use super::{Frame, H2Error};
18 use crate::error::ErrorKind::H2;
19 use crate::h2;
20 use crate::h2::decoder::Stage::{Header, Payload};
21 use crate::h2::error::ErrorCode;
22 use crate::h2::frame::{
23 Data, FrameFlags, Goaway, Ping, Priority, RstStream, WindowUpdate, ACK_MASK, END_HEADERS_MASK,
24 END_STREAM_MASK, HEADERS_PRIORITY_MASK, PADDED_MASK,
25 };
26 use crate::h2::{frame, HpackDecoder, Parts, Setting, Settings};
27 use crate::headers::Headers;
28
29 const FRAME_HEADER_LENGTH: usize = 9;
30 const DEFAULT_MAX_FRAME_SIZE: u32 = 2 << 13;
31 const MAX_ALLOWED_MAX_FRAME_SIZE: u32 = (2 << 23) - 1;
32 const DEFAULT_HEADER_TABLE_SIZE: usize = 4096;
33 const DEFAULT_MAX_HEADER_LIST_SIZE: usize = 16 << 20;
34 const MAX_INITIAL_WINDOW_SIZE: usize = (1 << 31) - 1;
35
36 /// A set of consecutive Frames.
37 /// When Headers Frames or Continuation Frames are not End Headers, they are
38 /// represented as `FrameKind::Partial`.
39 ///
40 /// - use `Frames` iterator.
41 ///
42 /// # Examples
43 ///
44 /// ```
45 /// use ylong_http::h2::Frames;
46 ///
47 /// # fn get_frames_iter(frames: Frames) {
48 /// let mut iter = frames.iter();
49 /// let next_frame = iter.next();
50 /// # }
51 /// ```
52 ///
53 /// - use `Frames` consuming iterator.
54 ///
55 /// # Examples
56 ///
57 /// ```
58 /// use ylong_http::h2::Frames;
59 ///
60 /// # fn get_frames_into_iter(frames: Frames) {
61 /// let mut iter = frames.into_iter();
62 /// let next_frame = iter.next();
63 /// # }
64 /// ```
65 pub struct Frames {
66 list: Vec<FrameKind>,
67 }
68
69 /// An iterator of `Frames`.
70 pub struct FramesIter<'a> {
71 iter: core::slice::Iter<'a, FrameKind>,
72 }
73
74 /// A consuming iterator of `Frames`.
75 pub struct FramesIntoIter {
76 into_iter: std::vec::IntoIter<FrameKind>,
77 }
78
79 impl Frames {
80 /// Returns an iterator over `Frames`.
81 ///
82 /// # Examples
83 ///
84 /// ```
85 /// use ylong_http::h2::Frames;
86 ///
87 /// # fn get_frames_iter(frames: Frames) {
88 /// let mut iter = frames.iter();
89 /// let next_frame = iter.next();
90 /// # }
91 /// ```
iter(&self) -> FramesIter92 pub fn iter(&self) -> FramesIter {
93 FramesIter {
94 iter: self.list.iter(),
95 }
96 }
97
98 /// Returns the size of `Frames`.
len(&self) -> usize99 pub fn len(&self) -> usize {
100 self.list.len()
101 }
102
103 /// Checks if the `Frames` is empty.
is_empty(&self) -> bool104 pub fn is_empty(&self) -> bool {
105 self.len() == 0
106 }
107 }
108
109 impl<'a> Deref for FramesIter<'a> {
110 type Target = core::slice::Iter<'a, FrameKind>;
111
deref(&self) -> &Self::Target112 fn deref(&self) -> &Self::Target {
113 &self.iter
114 }
115 }
116
117 impl<'a> DerefMut for FramesIter<'a> {
deref_mut(&mut self) -> &mut Self::Target118 fn deref_mut(&mut self) -> &mut Self::Target {
119 &mut self.iter
120 }
121 }
122
123 // TODO Added the Iterator trait implementation of ChunksIter.
124 impl<'a> Iterator for FramesIter<'a> {
125 type Item = &'a FrameKind;
126
next(&mut self) -> Option<Self::Item>127 fn next(&mut self) -> Option<Self::Item> {
128 self.iter.next()
129 }
130 }
131
132 impl Iterator for FramesIntoIter {
133 type Item = FrameKind;
134
next(&mut self) -> Option<Self::Item>135 fn next(&mut self) -> Option<Self::Item> {
136 self.into_iter.next()
137 }
138 }
139
140 impl core::iter::IntoIterator for Frames {
141 type Item = FrameKind;
142 type IntoIter = FramesIntoIter;
143
into_iter(self) -> Self::IntoIter144 fn into_iter(self) -> Self::IntoIter {
145 FramesIntoIter {
146 into_iter: self.list.into_iter(),
147 }
148 }
149 }
150
151 /// When Headers Frames or Continuation Frames are not End Headers, they are
152 /// represented as `FrameKind::Partial`.
153 pub enum FrameKind {
154 /// PUSH_PROMISE or HEADERS frame parsing completed.
155 Complete(Frame),
156 /// Partial decoded of PUSH_PROMISE or HEADERS frame.
157 Partial,
158 }
159
160 /// Frame bytes sequence decoder, supporting fragment deserialization of Frames.
161 ///
162 /// # Examples
163 ///
164 /// ```
165 /// use ylong_http::h2::FrameDecoder;
166 ///
167 /// let mut decoder = FrameDecoder::new();
168 /// decoder.set_max_header_list_size(30);
169 /// let data_frame_bytes = &[0, 0, 5, 0, 0, 0, 0, 0, 1, b'h', b'e', b'l', b'l', b'o'];
170 /// let decoded_frames = decoder.decode(data_frame_bytes).unwrap();
171 /// let frame_kind = decoded_frames.iter().next().unwrap();
172 /// ```
173 pub struct FrameDecoder {
174 buffer: Vec<u8>,
175 // buffer's length
176 offset: usize,
177 max_frame_size: u32,
178 // Current decode Stage of decoder
179 stage: Stage,
180 // 9-byte header information of the current frame
181 header: FrameHeader,
182 hpack: HpackDecoderLayer,
183 // The Headers Frame flags information is saved to ensure the continuity between Headers Frames
184 // and Continuation Frames.
185 continuations: Continuations,
186 }
187
188 enum Stage {
189 Header,
190 Payload,
191 }
192
193 struct HpackDecoderLayer {
194 hpack: HpackDecoder,
195 }
196
197 #[derive(Default)]
198 struct FrameHeader {
199 stream_id: StreamId,
200 flags: u8,
201 frame_type: u8,
202 payload_length: usize,
203 }
204
205 struct Continuations {
206 flags: u8,
207 is_end_stream: bool,
208 stream_id: StreamId,
209 is_end_headers: bool,
210 promised_stream_id: StreamId,
211 }
212
213 impl HpackDecoderLayer {
new() -> Self214 fn new() -> Self {
215 Self {
216 hpack: HpackDecoder::with_max_size(
217 DEFAULT_HEADER_TABLE_SIZE,
218 DEFAULT_MAX_HEADER_LIST_SIZE,
219 ),
220 }
221 }
222
hpack_decode(&mut self, buf: &[u8]) -> Result<(), H2Error>223 fn hpack_decode(&mut self, buf: &[u8]) -> Result<(), H2Error> {
224 self.hpack.decode(buf)
225 }
226
hpack_finish(&mut self) -> Result<Parts, H2Error>227 fn hpack_finish(&mut self) -> Result<Parts, H2Error> {
228 self.hpack.finish()
229 }
230
set_max_header_list_size(&mut self, size: usize)231 pub fn set_max_header_list_size(&mut self, size: usize) {
232 self.hpack.update_header_list_size(size)
233 }
234 }
235
236 impl FrameHeader {
new() -> Self237 fn new() -> Self {
238 FrameHeader::default()
239 }
240
reset(&mut self)241 fn reset(&mut self) {
242 self.stream_id = 0;
243 self.flags = 0;
244 self.frame_type = 0;
245 self.payload_length = 0
246 }
247
is_end_stream(&self) -> bool248 fn is_end_stream(&self) -> bool {
249 END_STREAM_MASK & self.flags == END_STREAM_MASK
250 }
251
is_padded(&self) -> bool252 fn is_padded(&self) -> bool {
253 PADDED_MASK & self.flags == PADDED_MASK
254 }
255
is_end_headers(&self) -> bool256 fn is_end_headers(&self) -> bool {
257 END_HEADERS_MASK & self.flags == END_HEADERS_MASK
258 }
259
is_headers_priority(&self) -> bool260 fn is_headers_priority(&self) -> bool {
261 HEADERS_PRIORITY_MASK & self.flags == HEADERS_PRIORITY_MASK
262 }
263
is_ack(&self) -> bool264 fn is_ack(&self) -> bool {
265 ACK_MASK & self.flags == ACK_MASK
266 }
267 }
268
269 impl Continuations {
new() -> Self270 fn new() -> Self {
271 Continuations {
272 flags: 0,
273 is_end_stream: false,
274 stream_id: 0,
275 // The initial value is true.
276 is_end_headers: true,
277 promised_stream_id: 0,
278 }
279 }
280
reset(&mut self)281 fn reset(&mut self) {
282 self.flags = 0;
283 self.is_end_stream = false;
284 self.is_end_headers = true;
285 self.stream_id = 0;
286 self.promised_stream_id = 0;
287 }
288 }
289
290 impl Default for FrameDecoder {
default() -> Self291 fn default() -> Self {
292 FrameDecoder {
293 buffer: vec![],
294 offset: 0,
295 max_frame_size: DEFAULT_MAX_FRAME_SIZE,
296 stage: Stage::Header,
297 header: FrameHeader::new(),
298 hpack: HpackDecoderLayer::new(),
299 continuations: Continuations::new(),
300 }
301 }
302 }
303
304 impl Frames {
new() -> Self305 fn new() -> Self {
306 Frames { list: vec![] }
307 }
push(&mut self, frame: FrameKind)308 fn push(&mut self, frame: FrameKind) {
309 self.list.push(frame)
310 }
311 }
312
313 impl FrameDecoder {
314 /// `FrameDecoder` constructor. Three parameters are defined in SETTINGS
315 /// Frame.
new() -> Self316 pub fn new() -> Self {
317 FrameDecoder::default()
318 }
319
320 /// Updates the SETTINGS_MAX_FRAME_SIZE.
set_max_frame_size(&mut self, size: u32) -> Result<(), H2Error>321 pub fn set_max_frame_size(&mut self, size: u32) -> Result<(), H2Error> {
322 if !(DEFAULT_MAX_FRAME_SIZE..=MAX_ALLOWED_MAX_FRAME_SIZE).contains(&size) {
323 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
324 }
325 self.max_frame_size = size;
326 Ok(())
327 }
328
329 /// Updates the SETTINGS_MAX_HEADER_LIST_SIZE.
set_max_header_list_size(&mut self, size: usize)330 pub fn set_max_header_list_size(&mut self, size: usize) {
331 self.hpack.set_max_header_list_size(size)
332 }
333
334 /// Frames deserialization interface, supporting segment decode.
335 ///
336 /// # Examples
337 ///
338 /// ```
339 /// use ylong_http::h2::FrameDecoder;
340 ///
341 /// let mut decoder = FrameDecoder::new();
342 /// decoder.set_max_header_list_size(30);
343 /// let data_frame_bytes = &[0, 0, 5, 0, 0, 0, 0, 0, 1, b'h', b'e', b'l', b'l', b'o'];
344 /// let decoded_frames = decoder.decode(&data_frame_bytes[..9]).unwrap();
345 /// assert_eq!(decoded_frames.len(), 0);
346 /// let decoded_frames = decoder.decode(&data_frame_bytes[9..]).unwrap();
347 /// assert_eq!(decoded_frames.len(), 1);
348 /// ```
decode(&mut self, buf: &[u8]) -> Result<Frames, H2Error>349 pub fn decode(&mut self, buf: &[u8]) -> Result<Frames, H2Error> {
350 let mut frames = Frames::new();
351 let mut buffer = buf;
352 loop {
353 match self.stage {
354 Header => match self.decode_frame_header(buffer)? {
355 Some(remain) => {
356 buffer = remain;
357 self.stage = Payload;
358 }
359 None => {
360 break;
361 }
362 },
363 Payload => match self.decode_frame_payload(buffer)? {
364 Some((remain, frame)) => {
365 frames.push(frame);
366 buffer = remain;
367 self.stage = Header;
368 }
369 None => {
370 break;
371 }
372 },
373 }
374 }
375 Ok(frames)
376 }
377
decode_frame_payload<'a>( &mut self, buf: &'a [u8], ) -> Result<Option<(&'a [u8], FrameKind)>, H2Error>378 fn decode_frame_payload<'a>(
379 &mut self,
380 buf: &'a [u8],
381 ) -> Result<Option<(&'a [u8], FrameKind)>, H2Error> {
382 // Frames of other types or streams are not allowed between Headers Frame and
383 // Continuation Frame.
384 if !self.continuations.is_end_headers
385 && (self.header.stream_id != self.continuations.stream_id
386 || self.header.frame_type != 9)
387 {
388 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
389 }
390
391 let frame_end_index = self.header.payload_length - self.offset;
392 if buf.len() < frame_end_index {
393 self.offset += buf.len();
394 self.buffer.extend_from_slice(buf);
395 Ok(None)
396 } else {
397 let frame = match self.header.frame_type {
398 0 => self.decode_data_payload(&buf[..frame_end_index])?,
399 1 => self.decode_headers_payload(&buf[..frame_end_index])?,
400 2 => self.decode_priority_payload(&buf[..frame_end_index])?,
401 3 => self.decode_reset_payload(&buf[..frame_end_index])?,
402 4 => self.decode_settings_payload(&buf[..frame_end_index])?,
403 5 => self.decode_push_promise_payload(&buf[..frame_end_index])?,
404 6 => self.decode_ping_payload(&buf[..frame_end_index])?,
405 7 => self.decode_goaway_payload(&buf[..frame_end_index])?,
406 8 => self.decode_window_update_payload(&buf[..frame_end_index])?,
407 9 => self.decode_continuation_payload(&buf[..frame_end_index])?,
408 _ => {
409 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
410 }
411 };
412 self.header.reset();
413 if self.offset != 0 {
414 self.offset = 0;
415 self.buffer.clear()
416 }
417 Ok(Some((&buf[frame_end_index..], frame)))
418 }
419 }
420
decode_ping_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error>421 fn decode_ping_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error> {
422 if !is_connection_frame(self.header.stream_id) {
423 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
424 }
425 let buf = if self.offset != 0 {
426 self.buffer.extend_from_slice(buf);
427 self.offset += buf.len();
428 self.buffer.as_slice()
429 } else {
430 buf
431 };
432 if self.header.payload_length != 8 || buf.len() != 8 {
433 return Err(H2Error::ConnectionError(ErrorCode::FrameSizeError));
434 }
435 let mut opaque_data = [0; 8];
436 opaque_data.copy_from_slice(buf);
437 let ping = Frame::new(
438 self.header.stream_id,
439 FrameFlags::new(self.header.flags),
440 frame::Payload::Ping(Ping::new(opaque_data)),
441 );
442 Ok(FrameKind::Complete(ping))
443 }
444
decode_priority_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error>445 fn decode_priority_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error> {
446 const EXCLUSIVE_MASK: u8 = 0x80;
447
448 if is_connection_frame(self.header.stream_id) {
449 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
450 }
451 if self.header.payload_length != 5 || buf.len() != 5 {
452 return Err(H2Error::StreamError(
453 self.header.stream_id,
454 ErrorCode::FrameSizeError,
455 ));
456 }
457 let buf = if self.offset != 0 {
458 self.buffer.extend_from_slice(buf);
459 self.offset += buf.len();
460 self.buffer.as_slice()
461 } else {
462 buf
463 };
464 let exclusive = buf[0] & EXCLUSIVE_MASK == EXCLUSIVE_MASK;
465 let stream_dependency = get_stream_id(&buf[..4]);
466 let weight = buf[4];
467 let priority = Frame::new(
468 self.header.stream_id,
469 FrameFlags::new(self.header.flags),
470 frame::Payload::Priority(Priority::new(exclusive, stream_dependency, weight)),
471 );
472 Ok(FrameKind::Complete(priority))
473 }
474
decode_goaway_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error>475 fn decode_goaway_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error> {
476 if !is_connection_frame(self.header.stream_id) {
477 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
478 }
479 let buf = if self.offset != 0 {
480 self.buffer.extend_from_slice(buf);
481 self.offset += buf.len();
482 self.buffer.as_slice()
483 } else {
484 buf
485 };
486 if self.header.payload_length < 8 || buf.len() < 8 {
487 return Err(H2Error::ConnectionError(ErrorCode::FrameSizeError));
488 }
489 let last_stream_id = get_stream_id(&buf[..4]);
490 let error_code = get_code_value(&buf[4..8]);
491 let mut debug_data = vec![];
492 debug_data.extend_from_slice(&buf[8..]);
493 let goaway = Frame::new(
494 self.header.stream_id,
495 FrameFlags::new(self.header.flags),
496 frame::Payload::Goaway(Goaway::new(error_code, last_stream_id, debug_data)),
497 );
498 Ok(FrameKind::Complete(goaway))
499 }
500
501 // window_update frame contains stream frame and connection frame
decode_window_update_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error>502 fn decode_window_update_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error> {
503 let buf = if self.offset != 0 {
504 self.buffer.extend_from_slice(buf);
505 self.offset += buf.len();
506 self.buffer.as_slice()
507 } else {
508 buf
509 };
510 if self.header.payload_length != 4 || buf.len() != 4 {
511 return Err(H2Error::ConnectionError(ErrorCode::FrameSizeError));
512 }
513 let increment_size = (((0x7f & buf[0]) as u32) << 24)
514 | ((buf[1] as u32) << 16)
515 | ((buf[2] as u32) << 8)
516 | (buf[3] as u32);
517 if increment_size == 0 {
518 return Err(H2Error::StreamError(
519 self.header.stream_id,
520 ErrorCode::ProtocolError,
521 ));
522 }
523 let window_update = Frame::new(
524 self.header.stream_id,
525 FrameFlags::new(self.header.flags),
526 frame::Payload::WindowUpdate(WindowUpdate::new(increment_size)),
527 );
528 Ok(FrameKind::Complete(window_update))
529 }
530
decode_reset_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error>531 fn decode_reset_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error> {
532 if is_connection_frame(self.header.stream_id) {
533 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
534 }
535 let buf = if self.offset != 0 {
536 self.buffer.extend_from_slice(buf);
537 self.offset += buf.len();
538 self.buffer.as_slice()
539 } else {
540 buf
541 };
542 if self.header.payload_length != 4 || buf.len() != 4 {
543 return Err(H2Error::ConnectionError(ErrorCode::FrameSizeError));
544 }
545 let code = get_code_value(&buf[..4]);
546 let reset = Frame::new(
547 self.header.stream_id,
548 FrameFlags::new(self.header.flags),
549 frame::Payload::RstStream(RstStream::new(code)),
550 );
551 Ok(FrameKind::Complete(reset))
552 }
553
decode_settings_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error>554 fn decode_settings_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error> {
555 if !is_connection_frame(self.header.stream_id) {
556 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
557 }
558 let buf = if self.offset != 0 {
559 self.buffer.extend_from_slice(buf);
560 self.offset += buf.len();
561 self.buffer.as_slice()
562 } else {
563 buf
564 };
565 if self.header.payload_length % 6 != 0 {
566 return Err(H2Error::ConnectionError(ErrorCode::FrameSizeError));
567 }
568 if self.header.is_ack() {
569 if self.header.payload_length != 0 || !buf.is_empty() {
570 return Err(H2Error::ConnectionError(ErrorCode::FrameSizeError));
571 }
572 let settings = Frame::new(
573 self.header.stream_id,
574 FrameFlags::new(self.header.flags),
575 frame::Payload::Settings(Settings::new(vec![])),
576 );
577
578 return Ok(FrameKind::Complete(settings));
579 }
580 let mut settings = vec![];
581 for chunk in buf.chunks(6) {
582 if let Some(setting) = split_token_to_setting(chunk)? {
583 settings.push(setting);
584 }
585 }
586 let frame = Frame::new(
587 self.header.stream_id,
588 FrameFlags::new(self.header.flags),
589 frame::Payload::Settings(Settings::new(settings)),
590 );
591 Ok(FrameKind::Complete(frame))
592 }
593
decode_data_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error>594 fn decode_data_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error> {
595 if is_connection_frame(self.header.stream_id) {
596 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
597 }
598 let buf = if self.offset != 0 {
599 self.buffer.extend_from_slice(buf);
600 self.offset += buf.len();
601 self.buffer.as_slice()
602 } else {
603 buf
604 };
605 if self.header.payload_length == 0 {
606 let frame = Frame::new(
607 self.header.stream_id,
608 FrameFlags::new(self.header.flags),
609 frame::Payload::Data(Data::new(vec![])),
610 );
611 return Ok(FrameKind::Complete(frame));
612 }
613 let is_padded = self.header.is_padded();
614 let data = if is_padded {
615 let padded_length = buf[0] as usize;
616 if self.header.payload_length <= padded_length {
617 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
618 }
619 let data_end_index = self.header.payload_length - padded_length;
620 let mut data: Vec<u8> = vec![];
621 data.extend_from_slice(&buf[1..data_end_index]);
622 data
623 } else {
624 let mut data: Vec<u8> = vec![];
625 data.extend_from_slice(&buf[..self.header.payload_length]);
626 data
627 };
628 let frame = Frame::new(
629 self.header.stream_id,
630 FrameFlags::new(self.header.flags),
631 frame::Payload::Data(Data::new(data)),
632 );
633 Ok(FrameKind::Complete(frame))
634 }
635
decode_continuation_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error>636 fn decode_continuation_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error> {
637 if is_connection_frame(self.header.stream_id) {
638 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
639 }
640 let buf = if self.offset != 0 {
641 self.buffer.extend_from_slice(buf);
642 self.offset += buf.len();
643 self.buffer.as_slice()
644 } else {
645 buf
646 };
647 let end_headers = self.header.is_end_headers();
648 if end_headers {
649 self.hpack.hpack_decode(buf)?;
650 let headers = self.hpack.hpack_finish()?;
651 let frame = if self.continuations.promised_stream_id != 0 {
652 Frame::new(
653 self.continuations.stream_id,
654 FrameFlags::new(self.continuations.flags),
655 frame::Payload::PushPromise(frame::PushPromise::new(
656 self.continuations.promised_stream_id,
657 headers,
658 )),
659 )
660 } else {
661 Frame::new(
662 self.continuations.stream_id,
663 FrameFlags::new(self.continuations.flags),
664 frame::Payload::Headers(frame::Headers::new(headers)),
665 )
666 };
667 self.continuations.reset();
668 Ok(FrameKind::Complete(frame))
669 } else {
670 self.hpack.hpack_decode(buf)?;
671 Ok(FrameKind::Partial)
672 }
673 }
674
decode_headers_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error>675 fn decode_headers_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error> {
676 if is_connection_frame(self.header.stream_id) {
677 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
678 }
679 let buf = if self.offset != 0 {
680 self.buffer.extend_from_slice(buf);
681 self.offset += buf.len();
682 self.buffer.as_slice()
683 } else {
684 buf
685 };
686 let priority = self.header.is_headers_priority();
687 let is_padded = self.header.is_padded();
688 let end_headers = self.header.is_end_headers();
689 let end_stream = self.header.is_end_stream();
690
691 let mut fragment_start_index = 0;
692 let mut fragment_end_index = self.header.payload_length;
693 if is_padded {
694 let padded_length = buf[0] as usize;
695 if self.header.payload_length <= padded_length {
696 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
697 }
698 fragment_start_index += 1;
699 fragment_end_index -= padded_length;
700 }
701 if priority {
702 fragment_start_index += 5;
703 }
704
705 if fragment_start_index > fragment_end_index {
706 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
707 }
708 if end_headers {
709 self.hpack
710 .hpack_decode(&buf[fragment_start_index..fragment_end_index])?;
711 let headers = self.hpack.hpack_finish()?;
712 let frame = Frame::new(
713 self.header.stream_id,
714 FrameFlags::new(self.header.flags),
715 frame::Payload::Headers(h2::frame::Headers::new(headers)),
716 );
717 Ok(FrameKind::Complete(frame))
718 } else {
719 self.continuations.flags = self.header.flags;
720 self.continuations.is_end_stream = end_stream;
721 self.continuations.is_end_headers = false;
722 self.continuations.stream_id = self.header.stream_id;
723
724 // TODO Performance optimization, The storage structure Vec is optimized. When a
725 // complete field block exists in the buffer, fragments do not need to be copied
726 // to the Vec.
727 self.hpack
728 .hpack_decode(&buf[fragment_start_index..fragment_end_index])?;
729 Ok(FrameKind::Partial)
730 }
731 }
732
decode_push_promise_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error>733 fn decode_push_promise_payload(&mut self, buf: &[u8]) -> Result<FrameKind, H2Error> {
734 if is_connection_frame(self.header.stream_id) {
735 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
736 }
737 let buf = if self.offset != 0 {
738 self.buffer.extend_from_slice(buf);
739 self.offset += buf.len();
740 self.buffer.as_slice()
741 } else {
742 buf
743 };
744 let is_padded = self.header.is_padded();
745 let end_headers = self.header.is_end_headers();
746 let mut fragment_start_index = 4;
747 let mut fragment_end_index = self.header.payload_length;
748 if is_padded {
749 let padded_length = buf[0] as usize;
750 if self.header.payload_length <= padded_length {
751 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
752 }
753 fragment_start_index += 1;
754 fragment_end_index -= padded_length;
755 }
756 if fragment_start_index > fragment_end_index {
757 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
758 }
759 self.hpack.hpack_decode(buf)?;
760 let promised_stream_id = if is_padded {
761 get_stream_id(&buf[1..5])
762 } else {
763 get_stream_id(&buf[..4])
764 };
765 if is_connection_frame(promised_stream_id) {
766 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
767 }
768 self.push_promise_framing(end_headers, promised_stream_id)
769 }
770
push_promise_framing( &mut self, end_headers: bool, promised_stream_id: StreamId, ) -> Result<FrameKind, H2Error>771 fn push_promise_framing(
772 &mut self,
773 end_headers: bool,
774 promised_stream_id: StreamId,
775 ) -> Result<FrameKind, H2Error> {
776 if end_headers {
777 let headers = self.hpack.hpack_finish()?;
778 let frame = Frame::new(
779 self.header.stream_id,
780 FrameFlags::new(self.header.flags),
781 frame::Payload::PushPromise(h2::frame::PushPromise::new(
782 promised_stream_id,
783 headers,
784 )),
785 );
786 Ok(FrameKind::Complete(frame))
787 } else {
788 self.continuations.flags = self.header.flags;
789 self.continuations.is_end_headers = false;
790 self.continuations.stream_id = self.header.stream_id;
791 self.continuations.promised_stream_id = promised_stream_id;
792 Ok(FrameKind::Partial)
793 }
794 }
795
decode_frame_header<'a>(&mut self, buf: &'a [u8]) -> Result<Option<&'a [u8]>, H2Error>796 fn decode_frame_header<'a>(&mut self, buf: &'a [u8]) -> Result<Option<&'a [u8]>, H2Error> {
797 let payload_pos = FRAME_HEADER_LENGTH - self.offset;
798 return if buf.len() < payload_pos {
799 self.offset += buf.len();
800 self.buffer.extend_from_slice(buf);
801 Ok(None)
802 } else {
803 let header_buffer = if self.offset == 0 {
804 buf
805 } else {
806 self.buffer.extend_from_slice(&buf[..payload_pos]);
807 self.buffer.as_slice()
808 };
809 let payload_length = ((header_buffer[0] as usize) << 16)
810 + ((header_buffer[1] as usize) << 8)
811 + (header_buffer[2] as usize);
812 if payload_length > self.max_frame_size as usize {
813 return Err(H2Error::ConnectionError(ErrorCode::FrameSizeError));
814 }
815 let frame_type = header_buffer[3];
816 let flags = header_buffer[4];
817 let stream_id = get_stream_id(&header_buffer[5..9]);
818 let frame_header = FrameHeader {
819 stream_id,
820 flags,
821 frame_type,
822 payload_length,
823 };
824 if self.offset != 0 {
825 self.offset = 0;
826 self.buffer.clear();
827 }
828 self.header = frame_header;
829 Ok(Some(&buf[payload_pos..]))
830 };
831 }
832 }
833
is_connection_frame(id: StreamId) -> bool834 fn is_connection_frame(id: StreamId) -> bool {
835 id == 0
836 }
837
get_stream_id(token: &[u8]) -> StreamId838 fn get_stream_id(token: &[u8]) -> StreamId {
839 (((token[0] & 0x7f) as u32) << 24)
840 | ((token[1] as u32) << 16)
841 | ((token[2] as u32) << 8)
842 | (token[3] as u32)
843 }
844
get_code_value(token: &[u8]) -> u32845 fn get_code_value(token: &[u8]) -> u32 {
846 ((token[0] as u32) << 24)
847 | ((token[1] as u32) << 16)
848 | ((token[2] as u32) << 8)
849 | (token[3] as u32)
850 }
851
split_token_to_setting(token: &[u8]) -> Result<Option<Setting>, H2Error>852 fn split_token_to_setting(token: &[u8]) -> Result<Option<Setting>, H2Error> {
853 let id = u16::from(token[0]) << 8 | u16::from(token[1]);
854 let value = get_code_value(&token[2..6]);
855 get_setting(id, value)
856 }
857
get_setting(id: u16, value: u32) -> Result<Option<Setting>, H2Error>858 pub fn get_setting(id: u16, value: u32) -> Result<Option<Setting>, H2Error> {
859 match id {
860 1 => Ok(Some(Setting::HeaderTableSize(value))),
861 2 => {
862 let enable_push = match value {
863 0 => false,
864 1 => true,
865 _ => return Err(H2Error::ConnectionError(ErrorCode::ProtocolError)),
866 };
867 Ok(Some(Setting::EnablePush(enable_push)))
868 }
869 3 => Ok(Some(Setting::MaxConcurrentStreams(value))),
870 4 => {
871 if value as usize > MAX_INITIAL_WINDOW_SIZE {
872 return Err(H2Error::ConnectionError(ErrorCode::FlowControlError));
873 }
874 Ok(Some(Setting::InitialWindowSize(value)))
875 }
876 5 => {
877 if !(DEFAULT_MAX_FRAME_SIZE..=MAX_ALLOWED_MAX_FRAME_SIZE).contains(&value) {
878 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
879 }
880 Ok(Some(Setting::MaxFrameSize(value)))
881 }
882 6 => Ok(Some(Setting::MaxHeaderListSize(value))),
883 _ => Ok(None),
884 }
885 }
886
887 #[cfg(test)]
888 mod ut_frame_decoder {
889 use crate::h2::decoder::{get_setting, FrameDecoder, FrameHeader, FrameKind};
890 use crate::h2::frame::{Payload, Ping, Setting};
891 use crate::h2::{ErrorCode, H2Error, PseudoHeaders};
892 use crate::util::test_util::decode;
893
894 macro_rules! check_complete_frame {
895 (
896 @header;
897 FrameKind: $frame_kind:expr,
898 Frame: {
899 StreamId: $stream_id:expr,
900 Flags: $flags:expr,
901 Payload: $payload:expr,
902 $(Padding: $frame_padding:expr,)?
903 },
904 ) => {
905 match $frame_kind {
906 FrameKind::Complete(frame) => {
907 assert_eq!(frame.stream_id(), $stream_id);
908 assert_eq!(frame.flags().bits(), $flags);
909 match frame.payload() {
910 Payload::Headers(headers_frame) => {
911 let (pseudo, header) = headers_frame.parts();
912 assert_eq!(
913 header.len(),
914 $payload.1.len(),
915 "assert header length failed"
916 );
917 for (key, value) in $payload.1.iter() {
918 assert_eq!(header.get(*key).unwrap().to_string().unwrap(), *value);
919 }
920 for (key, value) in $payload.0.iter() {
921 match *key {
922 ":method" => {
923 assert_eq!(
924 pseudo.method().expect("pseudo.method get failed !"),
925 *value
926 );
927 }
928 ":scheme" => {
929 assert_eq!(
930 pseudo.scheme().expect("pseudo.scheme get failed !"),
931 *value
932 );
933 }
934 ":authority" => {
935 assert_eq!(
936 pseudo
937 .authority()
938 .expect("pseudo.authority get failed !"),
939 *value
940 );
941 }
942 ":path" => {
943 assert_eq!(
944 pseudo.path().expect("pseudo.path get failed !"),
945 *value
946 );
947 }
948 ":status" => {
949 assert_eq!(
950 pseudo.status().expect("pseudo.status get failed !"),
951 *value
952 );
953 }
954 _ => {
955 panic!("Unexpected pseudo header input !");
956 }
957 }
958 }
959 }
960 _ => {
961 panic!("Unrecognized frame type !");
962 }
963 }
964 }
965 FrameKind::Partial => {
966 panic!("Incorrect decode result !");
967 }
968 };
969 };
970 (
971 @data;
972 FrameKind: $frame_kind:expr,
973 Frame: {
974 StreamId: $stream_id:expr,
975 Flags: $flags:expr,
976 Payload: $payload:expr,
977 $(Padding: $frame_padding:expr,)?
978 },
979 ) => {
980 match $frame_kind {
981 FrameKind::Complete(frame) => {
982 assert_eq!(frame.stream_id(), $stream_id);
983 assert_eq!(frame.flags().bits(), $flags);
984 match frame.payload() {
985 Payload::Data(data) => {
986 assert_eq!(data.data().as_slice(), $payload.as_bytes())
987 }
988 _ => {
989 panic!("Unrecognized frame type !");
990 }
991 }
992 }
993 FrameKind::Partial => {
994 panic!("Incorrect decode result !");
995 }
996 };
997 };
998 (
999 @partial;
1000 FrameKind: $frame_kind:expr,
1001 ) => {
1002 match $frame_kind {
1003 FrameKind::Complete(_) => {
1004 panic!("Incorrect decode result !");
1005 }
1006 FrameKind::Partial => {}
1007 }
1008 };
1009 }
1010
1011 macro_rules! decode_frames {
1012 (
1013 @data;
1014 Bytes: $frame_hex:expr,
1015 Count: $frame_count:expr,
1016 $(
1017 Frame: {
1018 StreamId: $stream_id:expr,
1019 Flags: $flags:expr,
1020 Payload: $payload:expr,
1021 $(Padding: $frame_padding:expr,)?
1022 },
1023 )*
1024
1025 ) => {
1026 let mut decoder = FrameDecoder::default();
1027 let frame_bytes = decode($frame_hex).expect("convert frame hex to bytes failed !");
1028 let decoded_frames = decoder.decode(frame_bytes.as_slice()).expect("decode frame bytes failed !");
1029 assert_eq!(decoded_frames.len(), $frame_count);
1030 let mut frames_iter = decoded_frames.iter();
1031 $(
1032 check_complete_frame!(
1033 @data;
1034 FrameKind: frames_iter.next().expect("take next frame from iterator failed !"),
1035 Frame: {
1036 StreamId: $stream_id,
1037 Flags: $flags,
1038 Payload: $payload,
1039 },
1040 );
1041 )*
1042
1043 };
1044 (
1045 @header;
1046 Bytes: $frame_hex:expr,
1047 Count: $frame_count:expr,
1048 $(
1049 Frame: {
1050 StreamId: $stream_id:expr,
1051 Flags: $flags:expr,
1052 Payload: $payload:expr,
1053 $(Padding: $frame_padding:expr,)?
1054 },
1055 )*
1056 ) => {
1057 let mut decoder = FrameDecoder::default();
1058 let frame_bytes = decode($frame_hex).expect("convert frame hex to bytes failed !");
1059 let decoded_frames = decoder.decode(frame_bytes.as_slice()).expect("decode frame bytes failed !");
1060 assert_eq!(decoded_frames.len(), $frame_count);
1061 let mut frames_iter = decoded_frames.iter();
1062 $(
1063 check_complete_frame!(
1064 @header;
1065 FrameKind: frames_iter.next().expect("take next frame from iterator failed !"),
1066 Frame: {
1067 StreamId: $stream_id,
1068 Flags: $flags,
1069 Payload: $payload,
1070 },
1071 );
1072 )*
1073 };
1074 (
1075 @error;
1076 Bytes: $frame_hex:expr,
1077 Decoder: {
1078 MAX_HEADER_LIST_SIZE: $header_list_size: expr,
1079 MAX_FRAME_SIZE: $max_frame_size: expr,
1080 },
1081 Error: $error_type:expr,
1082 ) => {
1083 let mut decoder = FrameDecoder::new();
1084 decoder.set_max_header_list_size($header_list_size);
1085 decoder.set_max_frame_size($max_frame_size).expect("Illegal size of SETTINGS_MAX_FRAME_SIZE !");
1086 let frame_bytes = decode($frame_hex).expect("convert frame hex to bytes failed !");
1087 let decoded_frames = decoder.decode(frame_bytes.as_slice());
1088 assert!(decoded_frames.is_err());
1089 assert_eq!(decoded_frames.err().expect("Get Error type failed !"), $error_type);
1090 };
1091 }
1092
1093 /// UT test cases for `FrameDecoder::decode`.
1094 ///
1095 /// # Brief
1096 ///
1097 /// Test a simple complete DATA frame.
1098 /// 1. Creates a `FrameDecoder`.
1099 /// 2. Calls its `FrameDecoder::decode` method.
1100 /// 3. Checks the results.
1101 #[test]
ut_frame_decoder_with_complete_data_frame()1102 fn ut_frame_decoder_with_complete_data_frame() {
1103 decode_frames!(
1104 @data;
1105 Bytes: "00000b00010000000168656c6c6f20776f726c64",
1106 Count: 1,
1107 Frame: {
1108 StreamId: 1,
1109 Flags: 1,
1110 Payload: "hello world",
1111 },
1112 );
1113 }
1114
1115 /// UT test cases for `FrameDecoder::decode`.
1116 ///
1117 /// # Brief
1118 ///
1119 /// Test a complete padded DATA frame with padding.
1120 /// 1. Creates a `FrameDecoder`.
1121 /// 2. Calls its `FrameDecoder::decode` method.
1122 /// 3. Checks the results.
1123 #[test]
ut_frame_decoder_with_complete_padded_data_frame()1124 fn ut_frame_decoder_with_complete_padded_data_frame() {
1125 decode_frames!(
1126 @data;
1127 Bytes: "0000140008000000020648656C6C6F2C20776F726C6421486F77647921",
1128 Count: 1,
1129 Frame: {
1130 StreamId: 2,
1131 Flags: 8,
1132 Payload: "Hello, world!",
1133 Padding: "Howdy!",
1134 },
1135 );
1136 }
1137
1138 /// UT test cases for `FrameDecoder::decode`.
1139 ///
1140 /// # Brief
1141 ///
1142 /// Test Data Frames in Segments.
1143 /// 1. Creates a `FrameDecoder`.
1144 /// 2. Calls its `FrameDecoder::decode` method.
1145 /// 3. Checks the results.
1146 #[test]
ut_frame_decoder_with_segmented_data_frame()1147 fn ut_frame_decoder_with_segmented_data_frame() {
1148 // (stream_id, flags, is_end_stream, content)
1149 let mut decoder = FrameDecoder::default();
1150 let frame_bytes = decode("00000b00010000000168656c6c6f20776f726c640000140008000000020648656C6C6F2C20776F726C6421486F77647921").unwrap();
1151 let frame_bytes = frame_bytes.as_slice();
1152 let decoded_frames = decoder.decode(&frame_bytes[..8]).unwrap();
1153 assert_eq!(decoded_frames.len(), 0);
1154 let decoded_frames = decoder.decode(&frame_bytes[8..12]).unwrap();
1155 assert_eq!(decoded_frames.len(), 0);
1156 let decoded_frames = decoder.decode(&frame_bytes[12..24]).unwrap();
1157 assert_eq!(decoded_frames.len(), 1);
1158 let mut frames_iter = decoded_frames.iter();
1159 check_complete_frame!(
1160 @data;
1161 FrameKind: frames_iter.next().expect("take next frame from iterator failed !"),
1162 Frame: {
1163 StreamId: 1,
1164 Flags: 1,
1165 Payload: "hello world",
1166 },
1167 );
1168 let decoded_frames = decoder.decode(&frame_bytes[24..]).unwrap();
1169 let mut frames_iter = decoded_frames.iter();
1170 check_complete_frame!(
1171 @data;
1172 FrameKind: frames_iter.next().expect("take next frame from iterator failed !"),
1173 Frame: {
1174 StreamId: 2,
1175 Flags: 8,
1176 Payload: "Hello, world!",
1177 },
1178 );
1179 }
1180
1181 /// UT test cases for `FrameDecoder::decode`.
1182 ///
1183 /// # Brief
1184 ///
1185 /// Test a complete Request HEADERS Frames with padding and priority.
1186 /// 1. Creates a `FrameDecoder`.
1187 /// 2. Calls its `FrameDecoder::decode` method.
1188 /// 3. Checks the results.
1189 #[test]
ut_frame_decoder_with_complete_padded_priority_headers_frame()1190 fn ut_frame_decoder_with_complete_padded_priority_headers_frame() {
1191 decode_frames!(
1192 @header;
1193 Bytes: "000040012D000000011080000014098286418a089d5c0b8170dc640007048762c2a0f6d842ff6687089d5c0b8170ff5388352398ac74acb37f546869732069732070616464696E672E",
1194 Count: 1,
1195 Frame: {
1196 StreamId: 1,
1197 Flags: 45,
1198 Payload:(
1199 [(":method", "GET"), (":scheme", "http"), (":authority", "127.0.0.1:3000"), (":path", "/resource")],
1200 [("host", "127.0.0.1"), ("accept", "image/jpeg")]),
1201 Padding: "This is padding.",
1202 },
1203 );
1204 }
1205
1206 /// UT test cases for `FrameDecoder::decode`.
1207 ///
1208 /// # Brief
1209 ///
1210 /// Test a complete Response HEADERS Frames.
1211 /// 1. Creates a `FrameDecoder`.
1212 /// 2. Calls its `FrameDecoder::decode` method.
1213 /// 3. Checks the results.
1214 #[test]
ut_frame_decoder_with_complete_response_headers_frame()1215 fn ut_frame_decoder_with_complete_response_headers_frame() {
1216 decode_frames!(
1217 @header;
1218 Bytes: "0000390105000000018b0f1385f3ebdfbf5f6496dc34fd2826d4d03b141004ca8015c0b9702053168dff6196dc34fd2826d4d03b141004ca806ee361b82654c5a37f",
1219 Count: 1,
1220 Frame: {
1221 StreamId: 1,
1222 Flags: 5,
1223 Payload:(
1224 [(":status", "304")],
1225 [("etag", "xyzzy"), ("expires", "Sat, 25 Mar 2023 02:16:10 GMT"), ("date", "Sat, 25 Mar 2023 05:51:23 GMT")]),
1226 },
1227 );
1228 }
1229
1230 /// UT test cases for `FrameDecoder::decode`.
1231 ///
1232 /// # Brief
1233 ///
1234 /// Test HEADERS Frames exceeded by SETTINGS_MAX_HEADER_LIST_SIZE.
1235 /// 1. Creates a `FrameDecoder`.
1236 /// 2. Calls its `FrameDecoder::decode` method.
1237 /// 3. Checks the results.
1238 #[test]
ut_frame_decoder_with_size_exceeded_headers_frame()1239 fn ut_frame_decoder_with_size_exceeded_headers_frame() {
1240 decode_frames!(
1241 @error;
1242 Bytes: "00002a0105000000018286418a089d5c0b8170dc640007048762c2a0f6d842ff6687089d5c0b8170ff5388352398ac74acb37f",
1243 Decoder: {
1244 MAX_HEADER_LIST_SIZE: 60,
1245 MAX_FRAME_SIZE: 2 << 13,
1246 },
1247 Error: H2Error::ConnectionError(ErrorCode::ConnectError),
1248 );
1249 }
1250
1251 /// UT test cases for `FrameDecoder::decode`.
1252 ///
1253 /// # Brief
1254 ///
1255 /// Test a series of complete request Frames.
1256 /// 1. Creates a `FrameDecoder`.
1257 /// 2. Calls its `FrameDecoder::decode` method.
1258 /// 3. Checks the results.
1259 /// Test a complete `Request` frames.
1260 #[test]
ut_frame_decoder_with_series_request_frames()1261 fn ut_frame_decoder_with_series_request_frames() {
1262 let mut decoder = FrameDecoder::default();
1263 let frame_bytes = decode("00002e0100000000018286418a089d5c0b8170dc640007048762c2a0f6d842ff6687089d5c0b8170ff5388352398ac74acb37f0f0d817f0000040904000000010f0d817f0000090001000000017468697320626f6479").unwrap();
1264 let decoded_frames = decoder.decode(frame_bytes.as_slice()).unwrap();
1265 assert_eq!(decoded_frames.len(), 3);
1266 let mut frames_iter = decoded_frames.iter();
1267
1268 // HEADERS frame END_HEADERS Flag is false, so it returns Partial
1269 check_complete_frame!(
1270 @partial;
1271 FrameKind: frames_iter.next().expect("take next frame from iterator failed !"),
1272 );
1273
1274 // continuation is ("content-length", "9"), so it will append to headers'
1275 // content-length because of repeat.
1276 check_complete_frame!(
1277 @header;
1278 FrameKind: frames_iter.next().expect("take next frame from iterator failed !"),
1279 Frame: {
1280 StreamId: 1,
1281 Flags: 0,
1282 Payload: (
1283 [(":method", "GET"), (":scheme", "http"), (":authority", "127.0.0.1:3000"), (":path", "/resource"),],
1284 [("host", "127.0.0.1"), ("accept", "image/jpeg"), ("content-length", "9, 9")]),
1285 },
1286 );
1287 check_complete_frame!(
1288 @data;
1289 FrameKind: frames_iter.next().expect("take next frame from iterator failed !"),
1290 Frame: {
1291 StreamId: 1,
1292 Flags: 1,
1293 Payload: "this body",
1294 },
1295 );
1296 }
1297
1298 /// UT test cases for `FrameDecoder::decode`.
1299 ///
1300 /// # Brief
1301 ///
1302 /// Test the function of inserting HEADERS of other streams between HEADERS
1303 /// and CONTINUATION of the same stream.
1304 /// 1. Creates a `FrameDecoder`.
1305 /// 2. Calls its `FrameDecoder::decode` method.
1306 /// 3. Checks the results.
1307 #[test]
ut_frame_decoder_with_headers_frame_in_another_stream()1308 fn ut_frame_decoder_with_headers_frame_in_another_stream() {
1309 decode_frames!(
1310 @error;
1311 Bytes: "00002e0100000000018286418a089d5c0b8170dc640007048762c2a0f6d842ff6687089d5c0b8170ff5388352398ac74acb37f0f0d817f00002e0104000000028286418a089d5c0b8170dc640007048762c2a0f6d842ff6687089d5c0b8170ff5388352398ac74acb37f0f0d817f0000040904000000010f0d817f0000090001000000017468697320626f6479",
1312 Decoder: {
1313 MAX_HEADER_LIST_SIZE: 16 << 20,
1314 MAX_FRAME_SIZE: 2 << 13,
1315 },
1316 Error: H2Error::ConnectionError(ErrorCode::ProtocolError),
1317 );
1318 }
1319
1320 /// UT test cases for `FrameDecoder::decode`.
1321 ///
1322 /// # Brief
1323 ///
1324 /// Test the function of inserting CONTINUATION of other streams between
1325 /// HEADERS and CONTINUATION of the same stream.
1326 /// 1. Creates a `FrameDecoder`.
1327 /// 2. Calls its `FrameDecoder::decode` method.
1328 /// 3. Checks the results.
1329 #[test]
ut_frame_decoder_with_continuation_frame_in_another_stream()1330 fn ut_frame_decoder_with_continuation_frame_in_another_stream() {
1331 decode_frames!(
1332 @error;
1333 Bytes: "00002e0100000000018286418a089d5c0b8170dc640007048762c2a0f6d842ff6687089d5c0b8170ff5388352398ac74acb37f0f0d817f0000040904000000020f0d817f0000090001000000017468697320626f6479",
1334 Decoder: {
1335 MAX_HEADER_LIST_SIZE: 16 << 20,
1336 MAX_FRAME_SIZE: 2 << 13,
1337 },
1338 Error: H2Error::ConnectionError(ErrorCode::ProtocolError),
1339 );
1340 }
1341
1342 /// UT test cases for `FrameDecoder::decode`.
1343 ///
1344 /// # Brief
1345 ///
1346 /// Test a complete Request HEADERS Frames with padding and priority, the
1347 /// purpose is to test the method of `FrameFlags`.
1348 ///
1349 /// 1. Creates a `FrameDecoder`.
1350 /// 2. Calls its `FrameDecoder::decode` method.
1351 /// 3. Checks the results.
1352 #[test]
ut_frame_decoder_with_padded_end_stream_headers_frame()1353 fn ut_frame_decoder_with_padded_end_stream_headers_frame() {
1354 let mut decoder = FrameDecoder::default();
1355 let frame_bytes = decode("000040012D000000011080000014098286418a089d5c0b8170dc640007048762c2a0f6d842ff6687089d5c0b8170ff5388352398ac74acb37f546869732069732070616464696E672E").unwrap();
1356 let decoded_frames = decoder.decode(frame_bytes.as_slice()).unwrap();
1357 let frames_kind = decoded_frames.iter().next().unwrap();
1358 match frames_kind {
1359 FrameKind::Complete(frame) => {
1360 assert!(frame.flags().is_padded());
1361 assert!(frame.flags().is_end_stream());
1362 assert_eq!(frame.flags().bits(), 0x2D);
1363 }
1364 FrameKind::Partial => {
1365 panic!("Unexpected FrameKind !")
1366 }
1367 }
1368 }
1369
1370 /// UT test cases for `FrameDecoder::decode_ping_payload`.
1371 ///
1372 /// # Brief
1373 ///
1374 /// Tests the case of a ping payload.
1375 ///
1376 /// 1. Creates a `FrameDecoder`.
1377 /// 2. Calls its `FrameDecoder::decode_ping_payload` method.
1378 /// 3. Checks the results.
1379 #[test]
ut_decode_ping_payload()1380 fn ut_decode_ping_payload() {
1381 let mut decoder = FrameDecoder::new();
1382 decoder.header = FrameHeader {
1383 payload_length: 8,
1384 frame_type: 0x6,
1385 flags: 0x0,
1386 stream_id: 0x0,
1387 };
1388 let ping_payload = &[b'p', b'i', b'n', b'g', b't', b'e', b's', b't'];
1389 let frame_kind = decoder.decode_ping_payload(ping_payload).unwrap();
1390 match frame_kind {
1391 FrameKind::Complete(frame) => match frame.payload() {
1392 Payload::Ping(ping) => {
1393 let data = ping.data();
1394 assert_eq!(data.len(), 8);
1395 assert_eq!(data[0], 112);
1396 assert_eq!(data[7], 116);
1397 }
1398 _ => panic!("Unexpected payload type!"),
1399 },
1400 FrameKind::Partial => {
1401 panic!("Unexpected FrameKind!")
1402 }
1403 }
1404
1405 // Tests the case where the payload length is not 8, which should return an
1406 // error.
1407 decoder.header.payload_length = 7;
1408 let result = decoder.decode_ping_payload(ping_payload);
1409 assert!(matches!(
1410 result,
1411 Err(H2Error::ConnectionError(ErrorCode::FrameSizeError))
1412 ));
1413
1414 // Tests the case where the stream id is not 0, which should return an error.
1415 decoder.header.stream_id = 1;
1416 let result = decoder.decode_ping_payload(ping_payload);
1417 assert!(matches!(
1418 result,
1419 Err(H2Error::ConnectionError(ErrorCode::ProtocolError))
1420 ));
1421 }
1422
1423 /// UT test cases for `FrameDecoder::decode_priority_payload`.
1424 ///
1425 /// # Brief
1426 ///
1427 /// This test case checks the behavior of the `decode_priority_payload`
1428 /// method in two scenarios.
1429 ///
1430 /// 1. Creates a `FrameDecoder`.
1431 /// 2. Calls its `decode_priority_payload` method with a valid
1432 /// `priority_payload`.
1433 /// 3. Verifies the method correctly decodes the payload and returns the
1434 /// expected values.
1435 /// 4. Sets the `stream_id` in the header to 0 and checks if the method
1436 /// returns an error as expected.
1437 #[test]
ut_decode_priority_payload()1438 fn ut_decode_priority_payload() {
1439 let mut decoder = FrameDecoder::new();
1440 decoder.header = FrameHeader {
1441 payload_length: 5,
1442 frame_type: 0x2,
1443 flags: 0x0,
1444 stream_id: 0x1,
1445 };
1446 let priority_payload = &[0x80, 0x0, 0x0, 0x1, 0x20];
1447 let frame_kind = decoder.decode_priority_payload(priority_payload).unwrap();
1448 match frame_kind {
1449 FrameKind::Complete(frame) => match frame.payload() {
1450 Payload::Priority(priority) => {
1451 assert!(priority.get_exclusive());
1452 assert_eq!(priority.get_stream_dependency(), 1);
1453 assert_eq!(priority.get_weight(), 32);
1454 }
1455 _ => panic!("Unexpected payload type!"),
1456 },
1457 FrameKind::Partial => {
1458 panic!("Unexpected FrameKind!")
1459 }
1460 }
1461
1462 // Tests the case where the stream id is 0, which should return an error.
1463 decoder.header.stream_id = 0;
1464 let result = decoder.decode_priority_payload(priority_payload);
1465 assert!(matches!(
1466 result,
1467 Err(H2Error::ConnectionError(ErrorCode::ProtocolError))
1468 ));
1469 }
1470
1471 /// UT test cases for `FrameDecoder::decode_goaway_payload`.
1472 ///
1473 /// # Brief
1474 ///
1475 /// This test case checks the behavior of the `decode_goaway_payload` method
1476 /// in two scenarios.
1477 ///
1478 /// 1. Creates a `FrameDecoder`.
1479 /// 2. Calls its `decode_goaway_payload` method with a valid
1480 /// `goaway_payload`.
1481 /// 3. Verifies the method correctly decodes the payload and returns the
1482 /// expected values.
1483 /// 4. Sets the `stream_id` in the header to a non-zero value and checks if
1484 /// the method returns an error as expected.
1485 #[test]
ut_decode_goaway_payload()1486 fn ut_decode_goaway_payload() {
1487 let mut decoder = FrameDecoder::new();
1488 decoder.header = FrameHeader {
1489 payload_length: 13,
1490 frame_type: 0x7,
1491 flags: 0x0,
1492 stream_id: 0x0,
1493 };
1494 let goaway_payload = &[
1495 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, b'd', b'e', b'b', b'u', b'g',
1496 ];
1497 let frame_kind = decoder.decode_goaway_payload(goaway_payload).unwrap();
1498 match frame_kind {
1499 FrameKind::Complete(frame) => match frame.payload() {
1500 Payload::Goaway(goaway) => {
1501 assert_eq!(goaway.get_last_stream_id(), 1);
1502 assert_eq!(goaway.get_error_code(), 2);
1503 assert_eq!(goaway.get_debug_data(), b"debug");
1504 }
1505 _ => panic!("Unexpected payload type!"),
1506 },
1507 FrameKind::Partial => {
1508 panic!("Unexpected FrameKind!")
1509 }
1510 }
1511
1512 // Tests the case where the stream id is not 0, which should return an error.
1513 decoder.header.stream_id = 1;
1514 let result = decoder.decode_goaway_payload(goaway_payload);
1515 assert!(matches!(
1516 result,
1517 Err(H2Error::ConnectionError(ErrorCode::ProtocolError))
1518 ));
1519 }
1520
1521 /// UT test cases for `FrameDecoder::decode_window_update_payload`.
1522 ///
1523 /// # Brief
1524 ///
1525 /// Tests the case of a window update payload.
1526 ///
1527 /// 1. Creates a `FrameDecoder`.
1528 /// 2. Calls its `FrameDecoder::decode_window_update_payload` method.
1529 /// 3. Checks the results.
1530 #[test]
ut_decode_window_update_payload()1531 fn ut_decode_window_update_payload() {
1532 let mut decoder = FrameDecoder::new();
1533 decoder.header = FrameHeader {
1534 payload_length: 4,
1535 frame_type: 0x8,
1536 flags: 0x0,
1537 stream_id: 0x1,
1538 };
1539 let window_update_payload = &[0x0, 0x0, 0x0, 0x1];
1540 let frame_kind = decoder
1541 .decode_window_update_payload(window_update_payload)
1542 .unwrap();
1543 match frame_kind {
1544 FrameKind::Complete(frame) => match frame.payload() {
1545 Payload::WindowUpdate(_) => {
1546 // println!("{:?}", window_update.get_increment());
1547 }
1548 _ => panic!("Unexpected payload type!"),
1549 },
1550 FrameKind::Partial => {
1551 panic!("Unexpected FrameKind!")
1552 }
1553 }
1554
1555 // Tests the case where the payload length is not 4, which should return an
1556 // error.
1557 decoder.header.payload_length = 5;
1558 let result = decoder.decode_window_update_payload(window_update_payload);
1559 assert!(matches!(
1560 result,
1561 Err(H2Error::ConnectionError(ErrorCode::FrameSizeError))
1562 ));
1563 }
1564
1565 /// UT test cases for `FrameDecoder::decode_reset_payload`.
1566 ///
1567 /// # Brief
1568 ///
1569 /// Tests the case of a reset payload.
1570 ///
1571 /// 1. Creates a `FrameDecoder`.
1572 /// 2. Calls its `FrameDecoder::decode_reset_payload` method.
1573 /// 3. Checks the results.
1574 #[test]
ut_decode_reset_payload()1575 fn ut_decode_reset_payload() {
1576 let mut decoder = FrameDecoder::new();
1577 decoder.header = FrameHeader {
1578 payload_length: 4,
1579 frame_type: 0x3,
1580 flags: 0x0,
1581 stream_id: 0x1,
1582 };
1583 let reset_payload = &[0x0, 0x0, 0x0, 0x1];
1584 let frame_kind = decoder.decode_reset_payload(reset_payload).unwrap();
1585 match frame_kind {
1586 FrameKind::Complete(frame) => match frame.payload() {
1587 Payload::RstStream(reset_stream) => {
1588 assert_eq!(reset_stream.error_code(), 1);
1589 }
1590 _ => panic!("Unexpected payload type!"),
1591 },
1592 FrameKind::Partial => {
1593 panic!("Unexpected FrameKind!")
1594 }
1595 }
1596
1597 // Tests the case where the payload length is not 4, which should return an
1598 // error.
1599 decoder.header.payload_length = 5;
1600 let result = decoder.decode_reset_payload(reset_payload);
1601 assert!(matches!(
1602 result,
1603 Err(H2Error::ConnectionError(ErrorCode::FrameSizeError))
1604 ));
1605
1606 // Tests the case where the stream id is 0, which should return an error.
1607 decoder.header.stream_id = 0;
1608 let result = decoder.decode_reset_payload(reset_payload);
1609 assert!(matches!(
1610 result,
1611 Err(H2Error::ConnectionError(ErrorCode::ProtocolError))
1612 ));
1613 }
1614
1615 /// UT test cases for `FrameDecoder::decode_settings_payload`.
1616 ///
1617 /// # Brief
1618 ///
1619 /// Tests the case of a settings payload.
1620 ///
1621 /// 1. Creates a `FrameDecoder`.
1622 /// 2. Calls its `FrameDecoder::decode_settings_payload` method.
1623 /// 3. Checks the results.
1624 #[test]
ut_decode_settings_payload()1625 fn ut_decode_settings_payload() {
1626 let mut decoder = FrameDecoder::new();
1627 decoder.header = FrameHeader {
1628 payload_length: 12,
1629 frame_type: 0x4,
1630 flags: 0x0,
1631 stream_id: 0x0,
1632 };
1633
1634 // Mock a settings payload: [0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x02,
1635 // 0x00, 0x00, 0x00, 0x01] Setting 1: Header Table Size, Value: 128
1636 // Setting 2: Enable Push, Value: 1
1637 let settings_payload = &[
1638 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
1639 ];
1640 let frame_kind = decoder.decode_settings_payload(settings_payload).unwrap();
1641 match frame_kind {
1642 FrameKind::Complete(frame) => match frame.payload() {
1643 Payload::Settings(settings) => {
1644 let settings_vec = settings.get_settings();
1645 assert_eq!(settings_vec.len(), 2);
1646 assert_eq!(settings_vec[0], Setting::HeaderTableSize(128));
1647 assert_eq!(settings_vec[1], Setting::EnablePush(true));
1648 }
1649 _ => panic!("Unexpected payload type!"),
1650 },
1651 FrameKind::Partial => {
1652 panic!("Unexpected FrameKind!")
1653 }
1654 }
1655
1656 // Test the case where the settings frame is an acknowledgment.
1657 // For this, we should set the ACK flag (0x1) and the payload length should be
1658 // 0.
1659 decoder.header = FrameHeader {
1660 payload_length: 0,
1661 frame_type: 0x4,
1662 flags: 0x1,
1663 stream_id: 0x0,
1664 };
1665 let frame_kind = decoder.decode_settings_payload(&[]).unwrap();
1666 match frame_kind {
1667 FrameKind::Complete(frame) => match frame.payload() {
1668 Payload::Settings(settings) => {
1669 let settings_vec = settings.get_settings();
1670 assert_eq!(settings_vec.len(), 0);
1671 }
1672 _ => panic!("Unexpected payload type!"),
1673 },
1674 FrameKind::Partial => {
1675 panic!("Unexpected FrameKind!")
1676 }
1677 }
1678
1679 // Tests the case where the payload length is not a multiple of 6, which should
1680 // return an error.
1681 decoder.header.payload_length = 5;
1682 let result = decoder.decode_settings_payload(settings_payload);
1683 assert!(matches!(
1684 result,
1685 Err(H2Error::ConnectionError(ErrorCode::FrameSizeError))
1686 ));
1687
1688 // Tests the case where the stream id is not 0, which should return an error.
1689 decoder.header.stream_id = 1;
1690 let result = decoder.decode_settings_payload(settings_payload);
1691 assert!(matches!(
1692 result,
1693 Err(H2Error::ConnectionError(ErrorCode::ProtocolError))
1694 ));
1695 }
1696
1697 /// UT test cases for `FrameDecoder::decode_push_promise_payload`.
1698 ///
1699 /// # Brief
1700 ///
1701 /// Tests the case of a push promise payload.
1702 ///
1703 /// 1. Creates a `FrameDecoder`.
1704 /// 2. Calls its `FrameDecoder::decode_push_promise_payload` method.
1705 /// 3. Checks the results.
1706 #[test]
ut_decode_push_promise_payload()1707 fn ut_decode_push_promise_payload() {
1708 let mut decoder = FrameDecoder::new();
1709 decoder.header = FrameHeader {
1710 payload_length: 10,
1711 frame_type: 0x5,
1712 flags: 0x88,
1713 stream_id: 0x1,
1714 };
1715 let push_promise_payload = &[0x0, 0x0, 0x0, 0x2, b'h', b'e', b'l', b'l', b'o', b'w'];
1716
1717 // Tests the case where the payload is a valid push promise.
1718 let frame_kind = decoder
1719 .decode_push_promise_payload(push_promise_payload)
1720 .unwrap();
1721 match frame_kind {
1722 FrameKind::Complete(frame) => match frame.payload() {
1723 Payload::PushPromise(_) => {}
1724 _ => panic!("Unexpected payload type!"),
1725 },
1726
1727 FrameKind::Partial => {}
1728 }
1729
1730 // Tests the case where the payload length is less than the promised_stream_id
1731 // size, which should return an error.
1732 decoder.header.payload_length = 3;
1733 let result = decoder.decode_push_promise_payload(push_promise_payload);
1734 assert!(matches!(
1735 result,
1736 Err(H2Error::ConnectionError(ErrorCode::ProtocolError))
1737 ));
1738
1739 // Tests the case where the stream id is 0, which should return an error.
1740 decoder.header.stream_id = 0;
1741 let result = decoder.decode_push_promise_payload(push_promise_payload);
1742 assert!(matches!(
1743 result,
1744 Err(H2Error::ConnectionError(ErrorCode::ProtocolError))
1745 ));
1746 }
1747
1748 /// UT test cases for `FrameDecoder::get_setting`.
1749 ///
1750 /// # Brief
1751 ///
1752 /// Tests the case of a settings payload.
1753 ///
1754 /// 1. Creates a `FrameDecoder`.
1755 /// 2. Calls its `FrameDecoder::get_setting` method.
1756 /// 3. Checks the results.
1757 #[test]
ut_get_setting()1758 fn ut_get_setting() {
1759 // Test the case where the id is for a HeaderTableSize
1760 match get_setting(1, 4096).unwrap() {
1761 Some(Setting::HeaderTableSize(size)) => {
1762 assert_eq!(size, 4096);
1763 }
1764 _ => panic!("Unexpected Setting!"),
1765 };
1766
1767 // Test the case where the id is for an EnablePush
1768 match get_setting(2, 0).unwrap() {
1769 Some(Setting::EnablePush(push)) => {
1770 assert!(!push);
1771 }
1772 _ => panic!("Unexpected Setting!"),
1773 };
1774
1775 // Test the case where the id is for a MaxConcurrentStreams
1776 match get_setting(3, 100).unwrap() {
1777 Some(Setting::MaxConcurrentStreams(streams)) => {
1778 assert_eq!(streams, 100);
1779 }
1780 _ => panic!("Unexpected Setting!"),
1781 };
1782
1783 // Test the case where the id is for an InitialWindowSize
1784 match get_setting(4, 20000).unwrap() {
1785 Some(Setting::InitialWindowSize(size)) => {
1786 assert_eq!(size, 20000);
1787 }
1788 _ => panic!("Unexpected Setting!"),
1789 };
1790
1791 // Test the case where the id is for a MaxFrameSize
1792 match get_setting(5, 16384).unwrap() {
1793 Some(Setting::MaxFrameSize(size)) => {
1794 assert_eq!(size, 16384);
1795 }
1796 _ => panic!("Unexpected Setting!"),
1797 };
1798
1799 // Test the case where the id is for a MaxHeaderListSize
1800 match get_setting(6, 8192).unwrap() {
1801 Some(Setting::MaxHeaderListSize(size)) => {
1802 assert_eq!(size, 8192);
1803 }
1804 _ => panic!("Unexpected Setting!"),
1805 };
1806
1807 // Test the case where the id is not recognized
1808 match get_setting(7, 1000).unwrap() {
1809 None => {}
1810 _ => panic!("Unexpected Setting!"),
1811 };
1812
1813 // Test the case where the id is for an EnablePush, but the value is invalid
1814 let result = get_setting(2, 2);
1815 assert!(matches!(
1816 result,
1817 Err(H2Error::ConnectionError(ErrorCode::ProtocolError))
1818 ));
1819
1820 // Test the case where the id is for an InitialWindowSize, but the value is too
1821 // large
1822 let result = get_setting(4, 2usize.pow(31) as u32);
1823 assert!(matches!(
1824 result,
1825 Err(H2Error::ConnectionError(ErrorCode::FlowControlError))
1826 ));
1827 }
1828 }
1829