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