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 !(DEFAULT_MAX_FRAME_SIZE..=MAX_ALLOWED_MAX_FRAME_SIZE).contains(&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 self.hpack.hpack_decode(buf)?;
759 let promised_stream_id = if is_padded {
760 get_stream_id(&buf[1..5])
761 } else {
762 get_stream_id(&buf[..4])
763 };
764 if is_connection_frame(promised_stream_id as usize) {
765 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
766 }
767 self.push_promise_framing(end_headers, promised_stream_id)
768 }
769
push_promise_framing( &mut self, end_headers: bool, promised_stream_id: u32, ) -> Result<FrameKind, H2Error>770 fn push_promise_framing(
771 &mut self,
772 end_headers: bool,
773 promised_stream_id: u32,
774 ) -> Result<FrameKind, H2Error> {
775 if end_headers {
776 let headers = self.hpack.hpack_finish()?;
777 let frame = Frame::new(
778 self.header.stream_id,
779 FrameFlags::new(self.header.flags),
780 frame::Payload::PushPromise(h2::frame::PushPromise::new(
781 promised_stream_id,
782 headers,
783 )),
784 );
785 Ok(FrameKind::Complete(frame))
786 } else {
787 self.continuations.flags = self.header.flags;
788 self.continuations.is_end_headers = false;
789 self.continuations.stream_id = self.header.stream_id;
790 self.continuations.promised_stream_id = promised_stream_id;
791 Ok(FrameKind::Partial)
792 }
793 }
794
decode_frame_header<'a>(&mut self, buf: &'a [u8]) -> Result<Option<&'a [u8]>, H2Error>795 fn decode_frame_header<'a>(&mut self, buf: &'a [u8]) -> Result<Option<&'a [u8]>, H2Error> {
796 let payload_pos = FRAME_HEADER_LENGTH - self.offset;
797 return if buf.len() < payload_pos {
798 self.offset += buf.len();
799 self.buffer.extend_from_slice(buf);
800 Ok(None)
801 } else {
802 let header_buffer = if self.offset == 0 {
803 buf
804 } else {
805 self.buffer.extend_from_slice(&buf[..payload_pos]);
806 self.buffer.as_slice()
807 };
808 let payload_length = ((header_buffer[0] as usize) << 16)
809 + ((header_buffer[1] as usize) << 8)
810 + (header_buffer[2] as usize);
811 if payload_length > self.max_frame_size as usize {
812 return Err(H2Error::ConnectionError(ErrorCode::FrameSizeError));
813 }
814 let frame_type = header_buffer[3];
815 let flags = header_buffer[4];
816 let stream_id = get_stream_id(&header_buffer[5..9]) as usize;
817 let frame_header = FrameHeader {
818 stream_id,
819 flags,
820 frame_type,
821 payload_length,
822 };
823 if self.offset != 0 {
824 self.offset = 0;
825 self.buffer.clear();
826 }
827 self.header = frame_header;
828 Ok(Some(&buf[payload_pos..]))
829 };
830 }
831 }
832
is_connection_frame(id: usize) -> bool833 fn is_connection_frame(id: usize) -> bool {
834 id == 0
835 }
836
get_stream_id(token: &[u8]) -> u32837 fn get_stream_id(token: &[u8]) -> u32 {
838 (((token[0] & 0x7f) as u32) << 24)
839 | ((token[1] as u32) << 16)
840 | ((token[2] as u32) << 8)
841 | (token[3] as u32)
842 }
843
get_code_value(token: &[u8]) -> u32844 fn get_code_value(token: &[u8]) -> u32 {
845 ((token[0] as u32) << 24)
846 | ((token[1] as u32) << 16)
847 | ((token[2] as u32) << 8)
848 | (token[3] as u32)
849 }
850
split_token_to_setting(token: &[u8]) -> Result<Option<Setting>, H2Error>851 fn split_token_to_setting(token: &[u8]) -> Result<Option<Setting>, H2Error> {
852 let id = u16::from(token[0]) << 8 | u16::from(token[1]);
853 let value = get_code_value(&token[2..6]);
854 get_setting(id, value)
855 }
856
get_setting(id: u16, value: u32) -> Result<Option<Setting>, H2Error>857 pub fn get_setting(id: u16, value: u32) -> Result<Option<Setting>, H2Error> {
858 match id {
859 1 => Ok(Some(Setting::HeaderTableSize(value))),
860 2 => {
861 let enable_push = match value {
862 0 => false,
863 1 => true,
864 _ => return Err(H2Error::ConnectionError(ErrorCode::ProtocolError)),
865 };
866 Ok(Some(Setting::EnablePush(enable_push)))
867 }
868 3 => Ok(Some(Setting::MaxConcurrentStreams(value))),
869 4 => {
870 if value as usize > MAX_INITIAL_WINDOW_SIZE {
871 return Err(H2Error::ConnectionError(ErrorCode::FlowControlError));
872 }
873 Ok(Some(Setting::InitialWindowSize(value)))
874 }
875 5 => {
876 if !(DEFAULT_MAX_FRAME_SIZE..=MAX_ALLOWED_MAX_FRAME_SIZE).contains(&value) {
877 return Err(H2Error::ConnectionError(ErrorCode::ProtocolError));
878 }
879 Ok(Some(Setting::MaxFrameSize(value)))
880 }
881 6 => Ok(Some(Setting::MaxHeaderListSize(value))),
882 _ => Ok(None),
883 }
884 }
885
886 #[cfg(test)]
887 mod ut_frame_decoder {
888 use crate::h2::decoder::{get_setting, FrameDecoder, FrameHeader, FrameKind};
889 use crate::h2::frame::{Payload, Ping, Setting};
890 use crate::h2::{ErrorCode, H2Error, PseudoHeaders};
891 use crate::util::test_util::decode;
892
893 macro_rules! check_complete_frame {
894 (
895 @header;
896 FrameKind: $frame_kind:expr,
897 Frame: {
898 StreamId: $stream_id:expr,
899 Flags: $flags:expr,
900 Payload: $payload:expr,
901 $(Padding: $frame_padding:expr,)?
902 },
903 ) => {
904 match $frame_kind {
905 FrameKind::Complete(frame) => {
906 assert_eq!(frame.stream_id(), $stream_id);
907 assert_eq!(frame.flags().bits(), $flags);
908 match frame.payload() {
909 Payload::Headers(headers_frame) => {
910 let (pseudo, header) = headers_frame.parts();
911 assert_eq!(
912 header.len(),
913 $payload.1.len(),
914 "assert header length failed"
915 );
916 for (key, value) in $payload.1.iter() {
917 assert_eq!(header.get(*key).unwrap().to_string().unwrap(), *value);
918 }
919 for (key, value) in $payload.0.iter() {
920 match *key {
921 ":method" => {
922 assert_eq!(
923 pseudo.method().expect("pseudo.method get failed !"),
924 *value
925 );
926 }
927 ":scheme" => {
928 assert_eq!(
929 pseudo.scheme().expect("pseudo.scheme get failed !"),
930 *value
931 );
932 }
933 ":authority" => {
934 assert_eq!(
935 pseudo
936 .authority()
937 .expect("pseudo.authority get failed !"),
938 *value
939 );
940 }
941 ":path" => {
942 assert_eq!(
943 pseudo.path().expect("pseudo.path get failed !"),
944 *value
945 );
946 }
947 ":status" => {
948 assert_eq!(
949 pseudo.status().expect("pseudo.status get failed !"),
950 *value
951 );
952 }
953 _ => {
954 panic!("Unexpected pseudo header input !");
955 }
956 }
957 }
958 }
959 _ => {
960 panic!("Unrecognized frame type !");
961 }
962 }
963 }
964 FrameKind::Partial => {
965 panic!("Incorrect decode result !");
966 }
967 };
968 };
969 (
970 @data;
971 FrameKind: $frame_kind:expr,
972 Frame: {
973 StreamId: $stream_id:expr,
974 Flags: $flags:expr,
975 Payload: $payload:expr,
976 $(Padding: $frame_padding:expr,)?
977 },
978 ) => {
979 match $frame_kind {
980 FrameKind::Complete(frame) => {
981 assert_eq!(frame.stream_id(), $stream_id);
982 assert_eq!(frame.flags().bits(), $flags);
983 match frame.payload() {
984 Payload::Data(data) => {
985 assert_eq!(data.data().as_slice(), $payload.as_bytes())
986 }
987 _ => {
988 panic!("Unrecognized frame type !");
989 }
990 }
991 }
992 FrameKind::Partial => {
993 panic!("Incorrect decode result !");
994 }
995 };
996 };
997 (
998 @partial;
999 FrameKind: $frame_kind:expr,
1000 ) => {
1001 match $frame_kind {
1002 FrameKind::Complete(_) => {
1003 panic!("Incorrect decode result !");
1004 }
1005 FrameKind::Partial => {}
1006 }
1007 };
1008 }
1009
1010 macro_rules! decode_frames {
1011 (
1012 @data;
1013 Bytes: $frame_hex:expr,
1014 Count: $frame_count:expr,
1015 $(
1016 Frame: {
1017 StreamId: $stream_id:expr,
1018 Flags: $flags:expr,
1019 Payload: $payload:expr,
1020 $(Padding: $frame_padding:expr,)?
1021 },
1022 )*
1023
1024 ) => {
1025 let mut decoder = FrameDecoder::default();
1026 let frame_bytes = decode($frame_hex).expect("convert frame hex to bytes failed !");
1027 let decoded_frames = decoder.decode(frame_bytes.as_slice()).expect("decode frame bytes failed !");
1028 assert_eq!(decoded_frames.len(), $frame_count);
1029 let mut frames_iter = decoded_frames.iter();
1030 $(
1031 check_complete_frame!(
1032 @data;
1033 FrameKind: frames_iter.next().expect("take next frame from iterator failed !"),
1034 Frame: {
1035 StreamId: $stream_id,
1036 Flags: $flags,
1037 Payload: $payload,
1038 },
1039 );
1040 )*
1041
1042 };
1043 (
1044 @header;
1045 Bytes: $frame_hex:expr,
1046 Count: $frame_count:expr,
1047 $(
1048 Frame: {
1049 StreamId: $stream_id:expr,
1050 Flags: $flags:expr,
1051 Payload: $payload:expr,
1052 $(Padding: $frame_padding:expr,)?
1053 },
1054 )*
1055 ) => {
1056 let mut decoder = FrameDecoder::default();
1057 let frame_bytes = decode($frame_hex).expect("convert frame hex to bytes failed !");
1058 let decoded_frames = decoder.decode(frame_bytes.as_slice()).expect("decode frame bytes failed !");
1059 assert_eq!(decoded_frames.len(), $frame_count);
1060 let mut frames_iter = decoded_frames.iter();
1061 $(
1062 check_complete_frame!(
1063 @header;
1064 FrameKind: frames_iter.next().expect("take next frame from iterator failed !"),
1065 Frame: {
1066 StreamId: $stream_id,
1067 Flags: $flags,
1068 Payload: $payload,
1069 },
1070 );
1071 )*
1072 };
1073 (
1074 @error;
1075 Bytes: $frame_hex:expr,
1076 Decoder: {
1077 MAX_HEADER_LIST_SIZE: $header_list_size: expr,
1078 MAX_FRAME_SIZE: $max_frame_size: expr,
1079 },
1080 Error: $error_type:expr,
1081 ) => {
1082 let mut decoder = FrameDecoder::new();
1083 decoder.set_max_header_list_size($header_list_size);
1084 decoder.set_max_frame_size($max_frame_size).expect("Illegal size of SETTINGS_MAX_FRAME_SIZE !");
1085 let frame_bytes = decode($frame_hex).expect("convert frame hex to bytes failed !");
1086 let decoded_frames = decoder.decode(frame_bytes.as_slice());
1087 assert!(decoded_frames.is_err());
1088 assert_eq!(decoded_frames.err().expect("Get Error type failed !"), $error_type);
1089 };
1090 }
1091
1092 /// UT test cases for `FrameDecoder::decode`.
1093 ///
1094 /// # Brief
1095 ///
1096 /// Test a simple complete DATA frame.
1097 /// 1. Creates a `FrameDecoder`.
1098 /// 2. Calls its `FrameDecoder::decode` method.
1099 /// 3. Checks the results.
1100 #[test]
ut_frame_decoder_with_complete_data_frame()1101 fn ut_frame_decoder_with_complete_data_frame() {
1102 decode_frames!(
1103 @data;
1104 Bytes: "00000b00010000000168656c6c6f20776f726c64",
1105 Count: 1,
1106 Frame: {
1107 StreamId: 1,
1108 Flags: 1,
1109 Payload: "hello world",
1110 },
1111 );
1112 }
1113
1114 /// UT test cases for `FrameDecoder::decode`.
1115 ///
1116 /// # Brief
1117 ///
1118 /// Test a complete padded DATA frame with padding.
1119 /// 1. Creates a `FrameDecoder`.
1120 /// 2. Calls its `FrameDecoder::decode` method.
1121 /// 3. Checks the results.
1122 #[test]
ut_frame_decoder_with_complete_padded_data_frame()1123 fn ut_frame_decoder_with_complete_padded_data_frame() {
1124 decode_frames!(
1125 @data;
1126 Bytes: "0000140008000000020648656C6C6F2C20776F726C6421486F77647921",
1127 Count: 1,
1128 Frame: {
1129 StreamId: 2,
1130 Flags: 8,
1131 Payload: "Hello, world!",
1132 Padding: "Howdy!",
1133 },
1134 );
1135 }
1136
1137 /// UT test cases for `FrameDecoder::decode`.
1138 ///
1139 /// # Brief
1140 ///
1141 /// Test Data Frames in Segments.
1142 /// 1. Creates a `FrameDecoder`.
1143 /// 2. Calls its `FrameDecoder::decode` method.
1144 /// 3. Checks the results.
1145 #[test]
ut_frame_decoder_with_segmented_data_frame()1146 fn ut_frame_decoder_with_segmented_data_frame() {
1147 // (stream_id, flags, is_end_stream, content)
1148 let mut decoder = FrameDecoder::default();
1149 let frame_bytes = decode("00000b00010000000168656c6c6f20776f726c640000140008000000020648656C6C6F2C20776F726C6421486F77647921").unwrap();
1150 let frame_bytes = frame_bytes.as_slice();
1151 let decoded_frames = decoder.decode(&frame_bytes[..8]).unwrap();
1152 assert_eq!(decoded_frames.len(), 0);
1153 let decoded_frames = decoder.decode(&frame_bytes[8..12]).unwrap();
1154 assert_eq!(decoded_frames.len(), 0);
1155 let decoded_frames = decoder.decode(&frame_bytes[12..24]).unwrap();
1156 assert_eq!(decoded_frames.len(), 1);
1157 let mut frames_iter = decoded_frames.iter();
1158 check_complete_frame!(
1159 @data;
1160 FrameKind: frames_iter.next().expect("take next frame from iterator failed !"),
1161 Frame: {
1162 StreamId: 1,
1163 Flags: 1,
1164 Payload: "hello world",
1165 },
1166 );
1167 let decoded_frames = decoder.decode(&frame_bytes[24..]).unwrap();
1168 let mut frames_iter = decoded_frames.iter();
1169 check_complete_frame!(
1170 @data;
1171 FrameKind: frames_iter.next().expect("take next frame from iterator failed !"),
1172 Frame: {
1173 StreamId: 2,
1174 Flags: 8,
1175 Payload: "Hello, world!",
1176 },
1177 );
1178 }
1179
1180 /// UT test cases for `FrameDecoder::decode`.
1181 ///
1182 /// # Brief
1183 ///
1184 /// Test a complete Request HEADERS Frames with padding and priority.
1185 /// 1. Creates a `FrameDecoder`.
1186 /// 2. Calls its `FrameDecoder::decode` method.
1187 /// 3. Checks the results.
1188 #[test]
ut_frame_decoder_with_complete_padded_priority_headers_frame()1189 fn ut_frame_decoder_with_complete_padded_priority_headers_frame() {
1190 decode_frames!(
1191 @header;
1192 Bytes: "000040012D000000011080000014098286418a089d5c0b8170dc640007048762c2a0f6d842ff6687089d5c0b8170ff5388352398ac74acb37f546869732069732070616464696E672E",
1193 Count: 1,
1194 Frame: {
1195 StreamId: 1,
1196 Flags: 45,
1197 Payload:(
1198 [(":method", "GET"), (":scheme", "http"), (":authority", "127.0.0.1:3000"), (":path", "/resource")],
1199 [("host", "127.0.0.1"), ("accept", "image/jpeg")]),
1200 Padding: "This is padding.",
1201 },
1202 );
1203 }
1204
1205 /// UT test cases for `FrameDecoder::decode`.
1206 ///
1207 /// # Brief
1208 ///
1209 /// Test a complete Response HEADERS Frames.
1210 /// 1. Creates a `FrameDecoder`.
1211 /// 2. Calls its `FrameDecoder::decode` method.
1212 /// 3. Checks the results.
1213 #[test]
ut_frame_decoder_with_complete_response_headers_frame()1214 fn ut_frame_decoder_with_complete_response_headers_frame() {
1215 decode_frames!(
1216 @header;
1217 Bytes: "0000390105000000018b0f1385f3ebdfbf5f6496dc34fd2826d4d03b141004ca8015c0b9702053168dff6196dc34fd2826d4d03b141004ca806ee361b82654c5a37f",
1218 Count: 1,
1219 Frame: {
1220 StreamId: 1,
1221 Flags: 5,
1222 Payload:(
1223 [(":status", "304")],
1224 [("etag", "xyzzy"), ("expires", "Sat, 25 Mar 2023 02:16:10 GMT"), ("date", "Sat, 25 Mar 2023 05:51:23 GMT")]),
1225 },
1226 );
1227 }
1228
1229 /// UT test cases for `FrameDecoder::decode`.
1230 ///
1231 /// # Brief
1232 ///
1233 /// Test HEADERS Frames exceeded by SETTINGS_MAX_HEADER_LIST_SIZE.
1234 /// 1. Creates a `FrameDecoder`.
1235 /// 2. Calls its `FrameDecoder::decode` method.
1236 /// 3. Checks the results.
1237 #[test]
ut_frame_decoder_with_size_exceeded_headers_frame()1238 fn ut_frame_decoder_with_size_exceeded_headers_frame() {
1239 decode_frames!(
1240 @error;
1241 Bytes: "00002a0105000000018286418a089d5c0b8170dc640007048762c2a0f6d842ff6687089d5c0b8170ff5388352398ac74acb37f",
1242 Decoder: {
1243 MAX_HEADER_LIST_SIZE: 60,
1244 MAX_FRAME_SIZE: 2 << 13,
1245 },
1246 Error: H2Error::ConnectionError(ErrorCode::ConnectError),
1247 );
1248 }
1249
1250 /// UT test cases for `FrameDecoder::decode`.
1251 ///
1252 /// # Brief
1253 ///
1254 /// Test a series of complete request Frames.
1255 /// 1. Creates a `FrameDecoder`.
1256 /// 2. Calls its `FrameDecoder::decode` method.
1257 /// 3. Checks the results.
1258 /// Test a complete `Request` frames.
1259 #[test]
ut_frame_decoder_with_series_request_frames()1260 fn ut_frame_decoder_with_series_request_frames() {
1261 let mut decoder = FrameDecoder::default();
1262 let frame_bytes = decode("00002e0100000000018286418a089d5c0b8170dc640007048762c2a0f6d842ff6687089d5c0b8170ff5388352398ac74acb37f0f0d817f0000040904000000010f0d817f0000090001000000017468697320626f6479").unwrap();
1263 let decoded_frames = decoder.decode(frame_bytes.as_slice()).unwrap();
1264 assert_eq!(decoded_frames.len(), 3);
1265 let mut frames_iter = decoded_frames.iter();
1266
1267 // HEADERS frame END_HEADERS Flag is false, so it returns Partial
1268 check_complete_frame!(
1269 @partial;
1270 FrameKind: frames_iter.next().expect("take next frame from iterator failed !"),
1271 );
1272
1273 // continuation is ("content-length", "9"), so it will append to headers'
1274 // content-length because of repeat.
1275 check_complete_frame!(
1276 @header;
1277 FrameKind: frames_iter.next().expect("take next frame from iterator failed !"),
1278 Frame: {
1279 StreamId: 1,
1280 Flags: 0,
1281 Payload: (
1282 [(":method", "GET"), (":scheme", "http"), (":authority", "127.0.0.1:3000"), (":path", "/resource"),],
1283 [("host", "127.0.0.1"), ("accept", "image/jpeg"), ("content-length", "9, 9")]),
1284 },
1285 );
1286 check_complete_frame!(
1287 @data;
1288 FrameKind: frames_iter.next().expect("take next frame from iterator failed !"),
1289 Frame: {
1290 StreamId: 1,
1291 Flags: 1,
1292 Payload: "this body",
1293 },
1294 );
1295 }
1296
1297 /// UT test cases for `FrameDecoder::decode`.
1298 ///
1299 /// # Brief
1300 ///
1301 /// Test the function of inserting HEADERS of other streams between HEADERS
1302 /// and CONTINUATION of the same stream.
1303 /// 1. Creates a `FrameDecoder`.
1304 /// 2. Calls its `FrameDecoder::decode` method.
1305 /// 3. Checks the results.
1306 #[test]
ut_frame_decoder_with_headers_frame_in_another_stream()1307 fn ut_frame_decoder_with_headers_frame_in_another_stream() {
1308 decode_frames!(
1309 @error;
1310 Bytes: "00002e0100000000018286418a089d5c0b8170dc640007048762c2a0f6d842ff6687089d5c0b8170ff5388352398ac74acb37f0f0d817f00002e0104000000028286418a089d5c0b8170dc640007048762c2a0f6d842ff6687089d5c0b8170ff5388352398ac74acb37f0f0d817f0000040904000000010f0d817f0000090001000000017468697320626f6479",
1311 Decoder: {
1312 MAX_HEADER_LIST_SIZE: 16 << 20,
1313 MAX_FRAME_SIZE: 2 << 13,
1314 },
1315 Error: H2Error::ConnectionError(ErrorCode::ProtocolError),
1316 );
1317 }
1318
1319 /// UT test cases for `FrameDecoder::decode`.
1320 ///
1321 /// # Brief
1322 ///
1323 /// Test the function of inserting CONTINUATION of other streams between
1324 /// HEADERS and CONTINUATION of the same stream.
1325 /// 1. Creates a `FrameDecoder`.
1326 /// 2. Calls its `FrameDecoder::decode` method.
1327 /// 3. Checks the results.
1328 #[test]
ut_frame_decoder_with_continuation_frame_in_another_stream()1329 fn ut_frame_decoder_with_continuation_frame_in_another_stream() {
1330 decode_frames!(
1331 @error;
1332 Bytes: "00002e0100000000018286418a089d5c0b8170dc640007048762c2a0f6d842ff6687089d5c0b8170ff5388352398ac74acb37f0f0d817f0000040904000000020f0d817f0000090001000000017468697320626f6479",
1333 Decoder: {
1334 MAX_HEADER_LIST_SIZE: 16 << 20,
1335 MAX_FRAME_SIZE: 2 << 13,
1336 },
1337 Error: H2Error::ConnectionError(ErrorCode::ProtocolError),
1338 );
1339 }
1340
1341 /// UT test cases for `FrameDecoder::decode`.
1342 ///
1343 /// # Brief
1344 ///
1345 /// Test a complete Request HEADERS Frames with padding and priority, the
1346 /// purpose is to test the method of `FrameFlags`.
1347 ///
1348 /// 1. Creates a `FrameDecoder`.
1349 /// 2. Calls its `FrameDecoder::decode` method.
1350 /// 3. Checks the results.
1351 #[test]
ut_frame_decoder_with_padded_end_stream_headers_frame()1352 fn ut_frame_decoder_with_padded_end_stream_headers_frame() {
1353 let mut decoder = FrameDecoder::default();
1354 let frame_bytes = decode("000040012D000000011080000014098286418a089d5c0b8170dc640007048762c2a0f6d842ff6687089d5c0b8170ff5388352398ac74acb37f546869732069732070616464696E672E").unwrap();
1355 let decoded_frames = decoder.decode(frame_bytes.as_slice()).unwrap();
1356 let frames_kind = decoded_frames.iter().next().unwrap();
1357 match frames_kind {
1358 FrameKind::Complete(frame) => {
1359 assert!(frame.flags().is_padded());
1360 assert!(frame.flags().is_end_stream());
1361 assert_eq!(frame.flags().bits(), 0x2D);
1362 }
1363 FrameKind::Partial => {
1364 panic!("Unexpected FrameKind !")
1365 }
1366 }
1367 }
1368
1369 /// UT test cases for `FrameDecoder::decode_ping_payload`.
1370 ///
1371 /// # Brief
1372 ///
1373 /// Tests the case of a ping payload.
1374 ///
1375 /// 1. Creates a `FrameDecoder`.
1376 /// 2. Calls its `FrameDecoder::decode_ping_payload` method.
1377 /// 3. Checks the results.
1378 #[test]
ut_decode_ping_payload()1379 fn ut_decode_ping_payload() {
1380 let mut decoder = FrameDecoder::new();
1381 decoder.header = FrameHeader {
1382 payload_length: 8,
1383 frame_type: 0x6,
1384 flags: 0x0,
1385 stream_id: 0x0,
1386 };
1387 let ping_payload = &[b'p', b'i', b'n', b'g', b't', b'e', b's', b't'];
1388 let frame_kind = decoder.decode_ping_payload(ping_payload).unwrap();
1389 match frame_kind {
1390 FrameKind::Complete(frame) => match frame.payload() {
1391 Payload::Ping(ping) => {
1392 let data = ping.data();
1393 assert_eq!(data.len(), 8);
1394 assert_eq!(data[0], 112);
1395 assert_eq!(data[7], 116);
1396 }
1397 _ => panic!("Unexpected payload type!"),
1398 },
1399 FrameKind::Partial => {
1400 panic!("Unexpected FrameKind!")
1401 }
1402 }
1403
1404 // Tests the case where the payload length is not 8, which should return an
1405 // error.
1406 decoder.header.payload_length = 7;
1407 let result = decoder.decode_ping_payload(ping_payload);
1408 assert!(matches!(
1409 result,
1410 Err(H2Error::ConnectionError(ErrorCode::FrameSizeError))
1411 ));
1412
1413 // Tests the case where the stream id is not 0, which should return an error.
1414 decoder.header.stream_id = 1;
1415 let result = decoder.decode_ping_payload(ping_payload);
1416 assert!(matches!(
1417 result,
1418 Err(H2Error::ConnectionError(ErrorCode::ProtocolError))
1419 ));
1420 }
1421
1422 /// UT test cases for `FrameDecoder::decode_priority_payload`.
1423 ///
1424 /// # Brief
1425 ///
1426 /// This test case checks the behavior of the `decode_priority_payload`
1427 /// method in two scenarios.
1428 ///
1429 /// 1. Creates a `FrameDecoder`.
1430 /// 2. Calls its `decode_priority_payload` method with a valid
1431 /// `priority_payload`.
1432 /// 3. Verifies the method correctly decodes the payload and returns the
1433 /// expected values.
1434 /// 4. Sets the `stream_id` in the header to 0 and checks if the method
1435 /// returns an error as expected.
1436 #[test]
ut_decode_priority_payload()1437 fn ut_decode_priority_payload() {
1438 let mut decoder = FrameDecoder::new();
1439 decoder.header = FrameHeader {
1440 payload_length: 5,
1441 frame_type: 0x2,
1442 flags: 0x0,
1443 stream_id: 0x1,
1444 };
1445 let priority_payload = &[0x80, 0x0, 0x0, 0x1, 0x20];
1446 let frame_kind = decoder.decode_priority_payload(priority_payload).unwrap();
1447 match frame_kind {
1448 FrameKind::Complete(frame) => match frame.payload() {
1449 Payload::Priority(priority) => {
1450 assert!(priority.get_exclusive());
1451 assert_eq!(priority.get_stream_dependency(), 1);
1452 assert_eq!(priority.get_weight(), 32);
1453 }
1454 _ => panic!("Unexpected payload type!"),
1455 },
1456 FrameKind::Partial => {
1457 panic!("Unexpected FrameKind!")
1458 }
1459 }
1460
1461 // Tests the case where the stream id is 0, which should return an error.
1462 decoder.header.stream_id = 0;
1463 let result = decoder.decode_priority_payload(priority_payload);
1464 assert!(matches!(
1465 result,
1466 Err(H2Error::ConnectionError(ErrorCode::ProtocolError))
1467 ));
1468 }
1469
1470 /// UT test cases for `FrameDecoder::decode_goaway_payload`.
1471 ///
1472 /// # Brief
1473 ///
1474 /// This test case checks the behavior of the `decode_goaway_payload` method
1475 /// in two scenarios.
1476 ///
1477 /// 1. Creates a `FrameDecoder`.
1478 /// 2. Calls its `decode_goaway_payload` method with a valid
1479 /// `goaway_payload`.
1480 /// 3. Verifies the method correctly decodes the payload and returns the
1481 /// expected values.
1482 /// 4. Sets the `stream_id` in the header to a non-zero value and checks if
1483 /// the method returns an error as expected.
1484 #[test]
ut_decode_goaway_payload()1485 fn ut_decode_goaway_payload() {
1486 let mut decoder = FrameDecoder::new();
1487 decoder.header = FrameHeader {
1488 payload_length: 13,
1489 frame_type: 0x7,
1490 flags: 0x0,
1491 stream_id: 0x0,
1492 };
1493 let goaway_payload = &[
1494 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, b'd', b'e', b'b', b'u', b'g',
1495 ];
1496 let frame_kind = decoder.decode_goaway_payload(goaway_payload).unwrap();
1497 match frame_kind {
1498 FrameKind::Complete(frame) => match frame.payload() {
1499 Payload::Goaway(goaway) => {
1500 assert_eq!(goaway.get_last_stream_id(), 1);
1501 assert_eq!(goaway.get_error_code(), 2);
1502 assert_eq!(goaway.get_debug_data(), b"debug");
1503 }
1504 _ => panic!("Unexpected payload type!"),
1505 },
1506 FrameKind::Partial => {
1507 panic!("Unexpected FrameKind!")
1508 }
1509 }
1510
1511 // Tests the case where the stream id is not 0, which should return an error.
1512 decoder.header.stream_id = 1;
1513 let result = decoder.decode_goaway_payload(goaway_payload);
1514 assert!(matches!(
1515 result,
1516 Err(H2Error::ConnectionError(ErrorCode::ProtocolError))
1517 ));
1518 }
1519
1520 /// UT test cases for `FrameDecoder::decode_window_update_payload`.
1521 ///
1522 /// # Brief
1523 ///
1524 /// Tests the case of a window update payload.
1525 ///
1526 /// 1. Creates a `FrameDecoder`.
1527 /// 2. Calls its `FrameDecoder::decode_window_update_payload` method.
1528 /// 3. Checks the results.
1529 #[test]
ut_decode_window_update_payload()1530 fn ut_decode_window_update_payload() {
1531 let mut decoder = FrameDecoder::new();
1532 decoder.header = FrameHeader {
1533 payload_length: 4,
1534 frame_type: 0x8,
1535 flags: 0x0,
1536 stream_id: 0x1,
1537 };
1538 let window_update_payload = &[0x0, 0x0, 0x0, 0x1];
1539 let frame_kind = decoder
1540 .decode_window_update_payload(window_update_payload)
1541 .unwrap();
1542 match frame_kind {
1543 FrameKind::Complete(frame) => match frame.payload() {
1544 Payload::WindowUpdate(_) => {
1545 // println!("{:?}", window_update.get_increment());
1546 }
1547 _ => panic!("Unexpected payload type!"),
1548 },
1549 FrameKind::Partial => {
1550 panic!("Unexpected FrameKind!")
1551 }
1552 }
1553
1554 // Tests the case where the payload length is not 4, which should return an
1555 // error.
1556 decoder.header.payload_length = 5;
1557 let result = decoder.decode_window_update_payload(window_update_payload);
1558 assert!(matches!(
1559 result,
1560 Err(H2Error::ConnectionError(ErrorCode::FrameSizeError))
1561 ));
1562 }
1563
1564 /// UT test cases for `FrameDecoder::decode_reset_payload`.
1565 ///
1566 /// # Brief
1567 ///
1568 /// Tests the case of a reset payload.
1569 ///
1570 /// 1. Creates a `FrameDecoder`.
1571 /// 2. Calls its `FrameDecoder::decode_reset_payload` method.
1572 /// 3. Checks the results.
1573 #[test]
ut_decode_reset_payload()1574 fn ut_decode_reset_payload() {
1575 let mut decoder = FrameDecoder::new();
1576 decoder.header = FrameHeader {
1577 payload_length: 4,
1578 frame_type: 0x3,
1579 flags: 0x0,
1580 stream_id: 0x1,
1581 };
1582 let reset_payload = &[0x0, 0x0, 0x0, 0x1];
1583 let frame_kind = decoder.decode_reset_payload(reset_payload).unwrap();
1584 match frame_kind {
1585 FrameKind::Complete(frame) => match frame.payload() {
1586 Payload::RstStream(reset_stream) => {
1587 assert_eq!(reset_stream.error_code(), 1);
1588 }
1589 _ => panic!("Unexpected payload type!"),
1590 },
1591 FrameKind::Partial => {
1592 panic!("Unexpected FrameKind!")
1593 }
1594 }
1595
1596 // Tests the case where the payload length is not 4, which should return an
1597 // error.
1598 decoder.header.payload_length = 5;
1599 let result = decoder.decode_reset_payload(reset_payload);
1600 assert!(matches!(
1601 result,
1602 Err(H2Error::ConnectionError(ErrorCode::FrameSizeError))
1603 ));
1604
1605 // Tests the case where the stream id is 0, which should return an error.
1606 decoder.header.stream_id = 0;
1607 let result = decoder.decode_reset_payload(reset_payload);
1608 assert!(matches!(
1609 result,
1610 Err(H2Error::ConnectionError(ErrorCode::ProtocolError))
1611 ));
1612 }
1613
1614 /// UT test cases for `FrameDecoder::decode_settings_payload`.
1615 ///
1616 /// # Brief
1617 ///
1618 /// Tests the case of a settings payload.
1619 ///
1620 /// 1. Creates a `FrameDecoder`.
1621 /// 2. Calls its `FrameDecoder::decode_settings_payload` method.
1622 /// 3. Checks the results.
1623 #[test]
ut_decode_settings_payload()1624 fn ut_decode_settings_payload() {
1625 let mut decoder = FrameDecoder::new();
1626 decoder.header = FrameHeader {
1627 payload_length: 12,
1628 frame_type: 0x4,
1629 flags: 0x0,
1630 stream_id: 0x0,
1631 };
1632
1633 // Mock a settings payload: [0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x02,
1634 // 0x00, 0x00, 0x00, 0x01] Setting 1: Header Table Size, Value: 128
1635 // Setting 2: Enable Push, Value: 1
1636 let settings_payload = &[
1637 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01,
1638 ];
1639 let frame_kind = decoder.decode_settings_payload(settings_payload).unwrap();
1640 match frame_kind {
1641 FrameKind::Complete(frame) => match frame.payload() {
1642 Payload::Settings(settings) => {
1643 let settings_vec = settings.get_settings();
1644 assert_eq!(settings_vec.len(), 2);
1645 assert_eq!(settings_vec[0], Setting::HeaderTableSize(128));
1646 assert_eq!(settings_vec[1], Setting::EnablePush(true));
1647 }
1648 _ => panic!("Unexpected payload type!"),
1649 },
1650 FrameKind::Partial => {
1651 panic!("Unexpected FrameKind!")
1652 }
1653 }
1654
1655 // Test the case where the settings frame is an acknowledgment.
1656 // For this, we should set the ACK flag (0x1) and the payload length should be
1657 // 0.
1658 decoder.header = FrameHeader {
1659 payload_length: 0,
1660 frame_type: 0x4,
1661 flags: 0x1,
1662 stream_id: 0x0,
1663 };
1664 let frame_kind = decoder.decode_settings_payload(&[]).unwrap();
1665 match frame_kind {
1666 FrameKind::Complete(frame) => match frame.payload() {
1667 Payload::Settings(settings) => {
1668 let settings_vec = settings.get_settings();
1669 assert_eq!(settings_vec.len(), 0);
1670 }
1671 _ => panic!("Unexpected payload type!"),
1672 },
1673 FrameKind::Partial => {
1674 panic!("Unexpected FrameKind!")
1675 }
1676 }
1677
1678 // Tests the case where the payload length is not a multiple of 6, which should
1679 // return an error.
1680 decoder.header.payload_length = 5;
1681 let result = decoder.decode_settings_payload(settings_payload);
1682 assert!(matches!(
1683 result,
1684 Err(H2Error::ConnectionError(ErrorCode::FrameSizeError))
1685 ));
1686
1687 // Tests the case where the stream id is not 0, which should return an error.
1688 decoder.header.stream_id = 1;
1689 let result = decoder.decode_settings_payload(settings_payload);
1690 assert!(matches!(
1691 result,
1692 Err(H2Error::ConnectionError(ErrorCode::ProtocolError))
1693 ));
1694 }
1695
1696 /// UT test cases for `FrameDecoder::decode_push_promise_payload`.
1697 ///
1698 /// # Brief
1699 ///
1700 /// Tests the case of a push promise payload.
1701 ///
1702 /// 1. Creates a `FrameDecoder`.
1703 /// 2. Calls its `FrameDecoder::decode_push_promise_payload` method.
1704 /// 3. Checks the results.
1705 #[test]
ut_decode_push_promise_payload()1706 fn ut_decode_push_promise_payload() {
1707 let mut decoder = FrameDecoder::new();
1708 decoder.header = FrameHeader {
1709 payload_length: 10,
1710 frame_type: 0x5,
1711 flags: 0x88,
1712 stream_id: 0x1,
1713 };
1714 let push_promise_payload = &[0x0, 0x0, 0x0, 0x2, b'h', b'e', b'l', b'l', b'o', b'w'];
1715
1716 // Tests the case where the payload is a valid push promise.
1717 let frame_kind = decoder
1718 .decode_push_promise_payload(push_promise_payload)
1719 .unwrap();
1720 match frame_kind {
1721 FrameKind::Complete(frame) => match frame.payload() {
1722 Payload::PushPromise(_) => {}
1723 _ => panic!("Unexpected payload type!"),
1724 },
1725
1726 FrameKind::Partial => {}
1727 }
1728
1729 // Tests the case where the payload length is less than the promised_stream_id
1730 // size, which should return an error.
1731 decoder.header.payload_length = 3;
1732 let result = decoder.decode_push_promise_payload(push_promise_payload);
1733 assert!(matches!(
1734 result,
1735 Err(H2Error::ConnectionError(ErrorCode::ProtocolError))
1736 ));
1737
1738 // Tests the case where the stream id is 0, which should return an error.
1739 decoder.header.stream_id = 0;
1740 let result = decoder.decode_push_promise_payload(push_promise_payload);
1741 assert!(matches!(
1742 result,
1743 Err(H2Error::ConnectionError(ErrorCode::ProtocolError))
1744 ));
1745 }
1746
1747 /// UT test cases for `FrameDecoder::get_setting`.
1748 ///
1749 /// # Brief
1750 ///
1751 /// Tests the case of a settings payload.
1752 ///
1753 /// 1. Creates a `FrameDecoder`.
1754 /// 2. Calls its `FrameDecoder::get_setting` method.
1755 /// 3. Checks the results.
1756 #[test]
ut_get_setting()1757 fn ut_get_setting() {
1758 // Test the case where the id is for a HeaderTableSize
1759 match get_setting(1, 4096).unwrap() {
1760 Some(Setting::HeaderTableSize(size)) => {
1761 assert_eq!(size, 4096);
1762 }
1763 _ => panic!("Unexpected Setting!"),
1764 };
1765
1766 // Test the case where the id is for an EnablePush
1767 match get_setting(2, 0).unwrap() {
1768 Some(Setting::EnablePush(push)) => {
1769 assert!(!push);
1770 }
1771 _ => panic!("Unexpected Setting!"),
1772 };
1773
1774 // Test the case where the id is for a MaxConcurrentStreams
1775 match get_setting(3, 100).unwrap() {
1776 Some(Setting::MaxConcurrentStreams(streams)) => {
1777 assert_eq!(streams, 100);
1778 }
1779 _ => panic!("Unexpected Setting!"),
1780 };
1781
1782 // Test the case where the id is for an InitialWindowSize
1783 match get_setting(4, 20000).unwrap() {
1784 Some(Setting::InitialWindowSize(size)) => {
1785 assert_eq!(size, 20000);
1786 }
1787 _ => panic!("Unexpected Setting!"),
1788 };
1789
1790 // Test the case where the id is for a MaxFrameSize
1791 match get_setting(5, 16384).unwrap() {
1792 Some(Setting::MaxFrameSize(size)) => {
1793 assert_eq!(size, 16384);
1794 }
1795 _ => panic!("Unexpected Setting!"),
1796 };
1797
1798 // Test the case where the id is for a MaxHeaderListSize
1799 match get_setting(6, 8192).unwrap() {
1800 Some(Setting::MaxHeaderListSize(size)) => {
1801 assert_eq!(size, 8192);
1802 }
1803 _ => panic!("Unexpected Setting!"),
1804 };
1805
1806 // Test the case where the id is not recognized
1807 match get_setting(7, 1000).unwrap() {
1808 None => {}
1809 _ => panic!("Unexpected Setting!"),
1810 };
1811
1812 // Test the case where the id is for an EnablePush, but the value is invalid
1813 let result = get_setting(2, 2);
1814 assert!(matches!(
1815 result,
1816 Err(H2Error::ConnectionError(ErrorCode::ProtocolError))
1817 ));
1818
1819 // Test the case where the id is for an InitialWindowSize, but the value is too
1820 // large
1821 let result = get_setting(4, 2usize.pow(31) as u32);
1822 assert!(matches!(
1823 result,
1824 Err(H2Error::ConnectionError(ErrorCode::FlowControlError))
1825 ));
1826 }
1827 }
1828