1 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4 // option. This file may not be copied, modified, or distributed
5 // except according to those terms.
6 
7 use crate::hsettings_frame::HSettings;
8 use neqo_common::{
9     hex, qdebug, qtrace, Decoder, Encoder, IncrementalDecoder, IncrementalDecoderResult,
10 };
11 use neqo_transport::Connection;
12 
13 use std::mem;
14 
15 use crate::{Error, Res};
16 
17 pub type HFrameType = u64;
18 
19 pub const H3_FRAME_TYPE_DATA: HFrameType = 0x0;
20 pub const H3_FRAME_TYPE_HEADERS: HFrameType = 0x1;
21 const H3_FRAME_TYPE_CANCEL_PUSH: HFrameType = 0x3;
22 const H3_FRAME_TYPE_SETTINGS: HFrameType = 0x4;
23 const H3_FRAME_TYPE_PUSH_PROMISE: HFrameType = 0x5;
24 const H3_FRAME_TYPE_GOAWAY: HFrameType = 0x7;
25 const H3_FRAME_TYPE_MAX_PUSH_ID: HFrameType = 0xd;
26 const H3_FRAME_TYPE_DUPLICATE_PUSH: HFrameType = 0xe;
27 
28 #[derive(Copy, Clone, PartialEq)]
29 pub enum HStreamType {
30     Control,
31     Request,
32     Push,
33 }
34 
35 // data for DATA frame is not read into HFrame::Data.
36 #[derive(PartialEq, Debug)]
37 pub enum HFrame {
38     Data {
39         len: u64, // length of the data
40     },
41     Headers {
42         header_block: Vec<u8>,
43     },
44     CancelPush {
45         push_id: u64,
46     },
47     Settings {
48         settings: HSettings,
49     },
50     PushPromise {
51         push_id: u64,
52         header_block: Vec<u8>,
53     },
54     Goaway {
55         stream_id: u64,
56     },
57     MaxPushId {
58         push_id: u64,
59     },
60     DuplicatePush {
61         push_id: u64,
62     },
63 }
64 
65 impl HFrame {
get_type(&self) -> HFrameType66     fn get_type(&self) -> HFrameType {
67         match self {
68             Self::Data { .. } => H3_FRAME_TYPE_DATA,
69             Self::Headers { .. } => H3_FRAME_TYPE_HEADERS,
70             Self::CancelPush { .. } => H3_FRAME_TYPE_CANCEL_PUSH,
71             Self::Settings { .. } => H3_FRAME_TYPE_SETTINGS,
72             Self::PushPromise { .. } => H3_FRAME_TYPE_PUSH_PROMISE,
73             Self::Goaway { .. } => H3_FRAME_TYPE_GOAWAY,
74             Self::MaxPushId { .. } => H3_FRAME_TYPE_MAX_PUSH_ID,
75             Self::DuplicatePush { .. } => H3_FRAME_TYPE_DUPLICATE_PUSH,
76         }
77     }
78 
encode(&self, enc: &mut Encoder)79     pub fn encode(&self, enc: &mut Encoder) {
80         enc.encode_varint(self.get_type());
81 
82         match self {
83             Self::Data { len } => {
84                 // DATA frame only encode the length here.
85                 enc.encode_varint(*len);
86             }
87             Self::Headers { header_block } => {
88                 enc.encode_vvec(header_block);
89             }
90             Self::CancelPush { push_id } => {
91                 enc.encode_vvec_with(|enc_inner| {
92                     enc_inner.encode_varint(*push_id);
93                 });
94             }
95             Self::Settings { settings } => {
96                 settings.encode_frame_contents(enc);
97             }
98             Self::PushPromise {
99                 push_id,
100                 header_block,
101             } => {
102                 enc.encode_varint((header_block.len() + (Encoder::varint_len(*push_id))) as u64);
103                 enc.encode_varint(*push_id);
104                 enc.encode(header_block);
105             }
106             Self::Goaway { stream_id } => {
107                 enc.encode_vvec_with(|enc_inner| {
108                     enc_inner.encode_varint(*stream_id);
109                 });
110             }
111             Self::MaxPushId { push_id } => {
112                 enc.encode_vvec_with(|enc_inner| {
113                     enc_inner.encode_varint(*push_id);
114                 });
115             }
116             Self::DuplicatePush { push_id } => {
117                 enc.encode_vvec_with(|enc_inner| {
118                     enc_inner.encode_varint(*push_id);
119                 });
120             }
121         }
122     }
123 
is_allowed(&self, s: HStreamType) -> bool124     pub fn is_allowed(&self, s: HStreamType) -> bool {
125         match self {
126             Self::Data { .. } => !(s == HStreamType::Control),
127             Self::Headers { .. } => !(s == HStreamType::Control),
128             Self::CancelPush { .. } => (s == HStreamType::Control),
129             Self::Settings { .. } => (s == HStreamType::Control),
130             Self::PushPromise { .. } => (s == HStreamType::Request),
131             Self::Goaway { .. } => (s == HStreamType::Control),
132             Self::MaxPushId { .. } => (s == HStreamType::Control),
133             Self::DuplicatePush { .. } => (s == HStreamType::Request),
134         }
135     }
136 }
137 
138 #[derive(Copy, Clone, PartialEq, Debug)]
139 enum HFrameReaderState {
140     BeforeFrame,
141     GetType,
142     GetLength,
143     GetData,
144     UnknownFrameDischargeData,
145     Done,
146 }
147 
148 #[derive(Debug)]
149 pub struct HFrameReader {
150     state: HFrameReaderState,
151     decoder: IncrementalDecoder,
152     hframe_type: u64,
153     hframe_len: u64,
154     payload: Vec<u8>,
155 }
156 
157 impl Default for HFrameReader {
default() -> Self158     fn default() -> Self {
159         Self::new()
160     }
161 }
162 
163 impl HFrameReader {
new() -> Self164     pub fn new() -> Self {
165         Self {
166             state: HFrameReaderState::BeforeFrame,
167             hframe_type: 0,
168             hframe_len: 0,
169             decoder: IncrementalDecoder::decode_varint(),
170             payload: Vec::new(),
171         }
172     }
173 
reset(&mut self)174     pub fn reset(&mut self) {
175         self.state = HFrameReaderState::BeforeFrame;
176         self.decoder = IncrementalDecoder::decode_varint();
177     }
178 
179     // returns true if quic stream was closed.
receive(&mut self, conn: &mut Connection, stream_id: u64) -> Res<bool>180     pub fn receive(&mut self, conn: &mut Connection, stream_id: u64) -> Res<bool> {
181         loop {
182             let to_read = std::cmp::min(self.decoder.min_remaining(), 4096);
183             let mut buf = vec![0; to_read];
184             let fin;
185             let mut input = match conn.stream_recv(stream_id, &mut buf[..]) {
186                 Ok((0, true)) => {
187                     qtrace!([conn], "HFrameReader::receive: stream has been closed");
188                     break match self.state {
189                         HFrameReaderState::BeforeFrame => Ok(true),
190                         _ => Err(Error::HttpFrameError),
191                     };
192                 }
193                 Ok((0, false)) => break Ok(false),
194                 Ok((amount, f)) => {
195                     qtrace!(
196                         [conn],
197                         "HFrameReader::receive: reading {} byte, fin={}",
198                         amount,
199                         f
200                     );
201                     fin = f;
202                     Decoder::from(&buf[..amount])
203                 }
204                 Err(e) => {
205                     qdebug!(
206                         [conn],
207                         "HFrameReader::receive: error reading data from stream {}: {:?}",
208                         stream_id,
209                         e
210                     );
211                     break Err(e.into());
212                 }
213             };
214 
215             let progress = self.decoder.consume(&mut input);
216             match self.state {
217                 HFrameReaderState::BeforeFrame | HFrameReaderState::GetType => match progress {
218                     IncrementalDecoderResult::Uint(v) => {
219                         qtrace!([conn], "HFrameReader::receive: read frame type {}", v);
220                         self.hframe_type = v;
221                         self.decoder = IncrementalDecoder::decode_varint();
222                         self.state = HFrameReaderState::GetLength;
223                     }
224                     IncrementalDecoderResult::InProgress => {
225                         self.state = HFrameReaderState::GetType;
226                     }
227                     _ => panic!("We must be in one of the states above"),
228                 },
229 
230                 HFrameReaderState::GetLength => {
231                     match progress {
232                         IncrementalDecoderResult::Uint(len) => {
233                             qtrace!(
234                                 [conn],
235                                 "HFrameReader::receive: frame type {} length {}",
236                                 self.hframe_type,
237                                 len
238                             );
239                             self.hframe_len = len;
240                             self.state = match self.hframe_type {
241                                 // DATA payload are left on the quic stream and picked up separately
242                                 H3_FRAME_TYPE_DATA => HFrameReaderState::Done,
243 
244                                 // for other frames get all data before decoding.
245                                 H3_FRAME_TYPE_CANCEL_PUSH
246                                 | H3_FRAME_TYPE_SETTINGS
247                                 | H3_FRAME_TYPE_GOAWAY
248                                 | H3_FRAME_TYPE_MAX_PUSH_ID
249                                 | H3_FRAME_TYPE_DUPLICATE_PUSH
250                                 | H3_FRAME_TYPE_PUSH_PROMISE
251                                 | H3_FRAME_TYPE_HEADERS => {
252                                     if len == 0 {
253                                         HFrameReaderState::Done
254                                     } else {
255                                         self.decoder = IncrementalDecoder::decode(len as usize);
256                                         HFrameReaderState::GetData
257                                     }
258                                 }
259                                 _ => {
260                                     if len == 0 {
261                                         self.decoder = IncrementalDecoder::decode_varint();
262                                         HFrameReaderState::BeforeFrame
263                                     } else {
264                                         self.decoder = IncrementalDecoder::ignore(len as usize);
265                                         HFrameReaderState::UnknownFrameDischargeData
266                                     }
267                                 }
268                             };
269                         }
270                         IncrementalDecoderResult::InProgress => {}
271                         _ => panic!("We must be in one of the states above"),
272                     }
273                 }
274                 HFrameReaderState::GetData => {
275                     match progress {
276                         IncrementalDecoderResult::Buffer(data) => {
277                             qtrace!(
278                                 [conn],
279                                 "received frame {}: {}",
280                                 self.hframe_type,
281                                 hex(&data[..])
282                             );
283                             self.payload = data;
284                             self.state = HFrameReaderState::Done;
285                         }
286                         IncrementalDecoderResult::InProgress => {}
287                         _ => panic!("We must be in one of the states above"),
288                     };
289                 }
290                 HFrameReaderState::UnknownFrameDischargeData => {
291                     match progress {
292                         IncrementalDecoderResult::Ignored => {
293                             self.reset();
294                         }
295                         IncrementalDecoderResult::InProgress => {}
296                         _ => panic!("We must be in one of the states above"),
297                     };
298                 }
299                 HFrameReaderState::Done => {
300                     break Ok(fin);
301                 }
302             };
303 
304             if self.state == HFrameReaderState::Done {
305                 break Ok(fin);
306             }
307 
308             if fin {
309                 if self.state == HFrameReaderState::BeforeFrame {
310                     break Ok(fin);
311                 } else {
312                     break Err(Error::HttpFrameError);
313                 }
314             }
315         }
316     }
317 
done(&self) -> bool318     pub fn done(&self) -> bool {
319         self.state == HFrameReaderState::Done
320     }
321 
get_frame(&mut self) -> Res<HFrame>322     pub fn get_frame(&mut self) -> Res<HFrame> {
323         if self.state != HFrameReaderState::Done {
324             return Err(Error::NotEnoughData);
325         }
326 
327         let payload = mem::replace(&mut self.payload, Vec::new());
328         let mut dec = Decoder::from(&payload[..]);
329         let f = match self.hframe_type {
330             H3_FRAME_TYPE_DATA => HFrame::Data {
331                 len: self.hframe_len,
332             },
333             H3_FRAME_TYPE_HEADERS => HFrame::Headers {
334                 header_block: dec.decode_remainder().to_vec(),
335             },
336             H3_FRAME_TYPE_CANCEL_PUSH => HFrame::CancelPush {
337                 push_id: match dec.decode_varint() {
338                     Some(v) => v,
339                     _ => return Err(Error::NotEnoughData),
340                 },
341             },
342             H3_FRAME_TYPE_SETTINGS => {
343                 let mut settings = HSettings::default();
344                 settings.decode_frame_contents(&mut dec)?;
345                 HFrame::Settings { settings }
346             }
347             H3_FRAME_TYPE_PUSH_PROMISE => {
348                 let push_id = match dec.decode_varint() {
349                     Some(v) => v,
350                     _ => return Err(Error::NotEnoughData),
351                 };
352                 HFrame::PushPromise {
353                     push_id,
354                     header_block: dec.decode_remainder().to_vec(),
355                 }
356             }
357             H3_FRAME_TYPE_GOAWAY => HFrame::Goaway {
358                 stream_id: match dec.decode_varint() {
359                     Some(v) => v,
360                     _ => return Err(Error::NotEnoughData),
361                 },
362             },
363             H3_FRAME_TYPE_MAX_PUSH_ID => HFrame::MaxPushId {
364                 push_id: match dec.decode_varint() {
365                     Some(v) => v,
366                     _ => return Err(Error::NotEnoughData),
367                 },
368             },
369             H3_FRAME_TYPE_DUPLICATE_PUSH => HFrame::DuplicatePush {
370                 push_id: match dec.decode_varint() {
371                     Some(v) => v,
372                     _ => return Err(Error::NotEnoughData),
373                 },
374             },
375             _ => panic!("We should not be in state Done with unknown frame type!"),
376         };
377         self.reset();
378         Ok(f)
379     }
380 }
381 
382 #[cfg(test)]
383 mod tests {
384     use super::*;
385     use crate::hsettings_frame::{HSetting, HSettingType};
386     use neqo_crypto::AuthenticationStatus;
387     use neqo_transport::StreamType;
388     use num_traits::Num;
389     use test_fixture::*;
390 
391     #[allow(clippy::many_single_char_names)]
enc_dec(f: &HFrame, st: &str, remaining: usize)392     fn enc_dec(f: &HFrame, st: &str, remaining: usize) {
393         let mut d = Encoder::default();
394 
395         f.encode(&mut d);
396 
397         // For data, headers and push_promise we do not read all bytes from the buffer
398         let d2 = Encoder::from_hex(st);
399         assert_eq!(&d[..], &d2[..d.len()]);
400 
401         let mut conn_c = default_client();
402         let mut conn_s = default_server();
403         let out = conn_c.process(None, now());
404         let out = conn_s.process(out.dgram(), now());
405         let out = conn_c.process(out.dgram(), now());
406         conn_s.process(out.dgram(), now());
407         conn_c.authenticated(AuthenticationStatus::Ok, now());
408         let out = conn_c.process(None, now());
409         conn_s.process(out.dgram(), now());
410 
411         // create a stream
412         let stream_id = conn_s.stream_create(StreamType::BiDi).unwrap();
413 
414         let mut fr: HFrameReader = HFrameReader::new();
415 
416         // conver string into u8 vector
417         let mut buf: Vec<u8> = Vec::new();
418         if st.len() % 2 != 0 {
419             panic!("Needs to be even length");
420         }
421         for i in 0..st.len() / 2 {
422             let x = st.get(i * 2..i * 2 + 2);
423             let v = <u8 as Num>::from_str_radix(x.unwrap(), 16).unwrap();
424             buf.push(v);
425         }
426         conn_s.stream_send(stream_id, &buf).unwrap();
427         let out = conn_s.process(None, now());
428         conn_c.process(out.dgram(), now());
429 
430         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
431 
432         // Check remaining data.
433         let mut buf = [0u8; 100];
434         let (amount, _) = conn_c.stream_recv(stream_id, &mut buf).unwrap();
435         assert_eq!(amount, remaining);
436 
437         assert!(fr.done());
438         if let Ok(f2) = fr.get_frame() {
439             assert_eq!(*f, f2);
440         } else {
441             panic!("wrong frame type");
442         }
443     }
444 
445     #[test]
test_data_frame()446     fn test_data_frame() {
447         let f = HFrame::Data { len: 3 };
448         enc_dec(&f, "0003010203", 3);
449     }
450 
451     #[test]
test_headers_frame()452     fn test_headers_frame() {
453         let f = HFrame::Headers {
454             header_block: vec![0x01, 0x02, 0x03],
455         };
456         enc_dec(&f, "0103010203", 0);
457     }
458 
459     #[test]
test_cancel_push_frame4()460     fn test_cancel_push_frame4() {
461         let f = HFrame::CancelPush { push_id: 5 };
462         enc_dec(&f, "030105", 0);
463     }
464 
465     #[test]
test_settings_frame4()466     fn test_settings_frame4() {
467         let f = HFrame::Settings {
468             settings: HSettings::new(&[HSetting::new(HSettingType::MaxHeaderListSize, 4)]),
469         };
470         enc_dec(&f, "04020604", 0);
471     }
472 
473     #[test]
test_push_promise_frame4()474     fn test_push_promise_frame4() {
475         let f = HFrame::PushPromise {
476             push_id: 4,
477             header_block: vec![0x61, 0x62, 0x63, 0x64],
478         };
479         enc_dec(&f, "05050461626364", 0);
480     }
481 
482     #[test]
test_goaway_frame4()483     fn test_goaway_frame4() {
484         let f = HFrame::Goaway { stream_id: 5 };
485         enc_dec(&f, "070105", 0);
486     }
487 
488     #[test]
test_max_push_id_frame4()489     fn test_max_push_id_frame4() {
490         let f = HFrame::MaxPushId { push_id: 5 };
491         enc_dec(&f, "0d0105", 0);
492     }
493 
494     #[test]
test_duplicate_push_frame4()495     fn test_duplicate_push_frame4() {
496         let f = HFrame::DuplicatePush { push_id: 5 };
497         enc_dec(&f, "0e0105", 0);
498     }
499 
500     // We have 2 code paths in frame_reader:
501     // 1) All frames except DATA (here we test SETTING and SETTINGS with larger varints and PUSH_PROMISE)
502     // 1) DATA
503 
504     // Test SETTINGS
505     #[test]
test_frame_reading_with_stream_settings1()506     fn test_frame_reading_with_stream_settings1() {
507         let (mut conn_c, mut conn_s) = connect();
508 
509         // create a stream
510         let stream_id = conn_s.stream_create(StreamType::BiDi).unwrap();
511 
512         let mut fr: HFrameReader = HFrameReader::new();
513 
514         // Send and read settings frame 040406040804
515         conn_s.stream_send(stream_id, &[0x4]).unwrap();
516         let out = conn_s.process(None, now());
517         conn_c.process(out.dgram(), now());
518         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
519 
520         conn_s.stream_send(stream_id, &[0x4]).unwrap();
521         let out = conn_s.process(None, now());
522         conn_c.process(out.dgram(), now());
523         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
524 
525         conn_s.stream_send(stream_id, &[0x6]).unwrap();
526         let out = conn_s.process(None, now());
527         conn_c.process(out.dgram(), now());
528         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
529 
530         conn_s.stream_send(stream_id, &[0x4]).unwrap();
531         let out = conn_s.process(None, now());
532         conn_c.process(out.dgram(), now());
533         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
534 
535         conn_s.stream_send(stream_id, &[0x8]).unwrap();
536         let out = conn_s.process(None, now());
537         conn_c.process(out.dgram(), now());
538         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
539 
540         conn_s.stream_send(stream_id, &[0x4]).unwrap();
541         let out = conn_s.process(None, now());
542         conn_c.process(out.dgram(), now());
543         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
544 
545         assert!(fr.done());
546         let f = fr.get_frame();
547         if let HFrame::Settings { settings } = f.unwrap() {
548             assert!(settings.len() == 1);
549             //            for i in settings.iter() {
550             assert!(settings[0] == HSetting::new(HSettingType::MaxHeaderListSize, 4));
551         } else {
552             panic!("wrong frame type");
553         }
554     }
555 
556     // Test SETTINGS with larger varints
557     #[test]
test_frame_reading_with_stream_settings2()558     fn test_frame_reading_with_stream_settings2() {
559         let (mut conn_c, mut conn_s) = connect();
560 
561         // create a stream
562         let stream_id = conn_s.stream_create(StreamType::BiDi).unwrap();
563 
564         let mut fr: HFrameReader = HFrameReader::new();
565 
566         // Read settings frame 400406064004084100
567         conn_s.stream_send(stream_id, &[0x40]).unwrap();
568         let out = conn_s.process(None, now());
569         conn_c.process(out.dgram(), now());
570         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
571 
572         conn_s.stream_send(stream_id, &[0x4]).unwrap();
573         let out = conn_s.process(None, now());
574         conn_c.process(out.dgram(), now());
575         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
576 
577         conn_s.stream_send(stream_id, &[0x6]).unwrap();
578         let out = conn_s.process(None, now());
579         conn_c.process(out.dgram(), now());
580         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
581 
582         conn_s.stream_send(stream_id, &[0x6]).unwrap();
583         let out = conn_s.process(None, now());
584         conn_c.process(out.dgram(), now());
585         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
586 
587         conn_s.stream_send(stream_id, &[0x40]).unwrap();
588         let out = conn_s.process(None, now());
589         conn_c.process(out.dgram(), now());
590         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
591 
592         conn_s.stream_send(stream_id, &[0x4]).unwrap();
593         let out = conn_s.process(None, now());
594         conn_c.process(out.dgram(), now());
595         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
596 
597         conn_s.stream_send(stream_id, &[0x8]).unwrap();
598         let out = conn_s.process(None, now());
599         conn_c.process(out.dgram(), now());
600         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
601 
602         conn_s.stream_send(stream_id, &[0x41]).unwrap();
603         let out = conn_s.process(None, now());
604         conn_c.process(out.dgram(), now());
605         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
606 
607         conn_s.stream_send(stream_id, &[0x0]).unwrap();
608         let out = conn_s.process(None, now());
609         conn_c.process(out.dgram(), now());
610         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
611 
612         assert!(fr.done());
613         let f = fr.get_frame();
614         assert!(f.is_ok());
615         if let HFrame::Settings { settings } = f.unwrap() {
616             assert!(settings.len() == 1);
617             assert!(settings[0] == HSetting::new(HSettingType::MaxHeaderListSize, 4));
618         } else {
619             panic!("wrong frame type");
620         }
621     }
622 
623     // Test PUSH_PROMISE
624     #[test]
test_frame_reading_with_stream_push_promise()625     fn test_frame_reading_with_stream_push_promise() {
626         let (mut conn_c, mut conn_s) = connect();
627 
628         // create a stream
629         let stream_id = conn_s.stream_create(StreamType::BiDi).unwrap();
630 
631         let mut fr: HFrameReader = HFrameReader::new();
632 
633         // Read pushpromise frame 05054101010203
634         conn_s.stream_send(stream_id, &[0x5]).unwrap();
635         let out = conn_s.process(None, now());
636         conn_c.process(out.dgram(), now());
637         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
638 
639         conn_s.stream_send(stream_id, &[0x5]).unwrap();
640         let out = conn_s.process(None, now());
641         conn_c.process(out.dgram(), now());
642         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
643 
644         conn_s.stream_send(stream_id, &[0x41]).unwrap();
645         let out = conn_s.process(None, now());
646         conn_c.process(out.dgram(), now());
647         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
648 
649         conn_s
650             .stream_send(stream_id, &[0x1, 0x1, 0x2, 0x3])
651             .unwrap();
652         let out = conn_s.process(None, now());
653         conn_c.process(out.dgram(), now());
654         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
655 
656         // headers are still on the stream.
657         // assert that we do not have any more date on the stream
658         let mut buf = [0u8; 100];
659         let (amount, _) = conn_c.stream_recv(stream_id, &mut buf).unwrap();
660         assert_eq!(amount, 0);
661 
662         assert!(fr.done());
663         let f = fr.get_frame();
664         assert!(f.is_ok());
665         if let HFrame::PushPromise {
666             push_id,
667             header_block,
668         } = f.unwrap()
669         {
670             assert_eq!(push_id, 257);
671             assert_eq!(header_block, &[0x1, 0x2, 0x3]);
672         } else {
673             panic!("wrong frame type");
674         }
675     }
676 
677     // Test DATA
678     #[test]
test_frame_reading_with_stream_data()679     fn test_frame_reading_with_stream_data() {
680         let (mut conn_c, mut conn_s) = connect();
681 
682         // create a stream
683         let stream_id = conn_s.stream_create(StreamType::BiDi).unwrap();
684 
685         let mut fr: HFrameReader = HFrameReader::new();
686 
687         // Read data frame 0003010203
688         conn_s
689             .stream_send(stream_id, &[0x0, 0x3, 0x1, 0x2, 0x3])
690             .unwrap();
691         let out = conn_s.process(None, now());
692         conn_c.process(out.dgram(), now());
693         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
694 
695         // payloead is still on the stream.
696         // assert that we have 3 bytes in the stream
697         let mut buf = [0u8; 100];
698         let (amount, _) = conn_c.stream_recv(stream_id, &mut buf).unwrap();
699         assert_eq!(amount, 3);
700 
701         assert!(fr.done());
702         let f = fr.get_frame();
703         assert!(f.is_ok());
704         if let HFrame::Data { len } = f.unwrap() {
705             assert!(len == 3);
706         } else {
707             panic!("wrong frame type");
708         }
709     }
710 
711     // Test an unknown frame
712     #[test]
test_unknown_frame()713     fn test_unknown_frame() {
714         let (mut conn_c, mut conn_s) = connect();
715 
716         // create a stream
717         let stream_id = conn_s.stream_create(StreamType::BiDi).unwrap();
718 
719         let mut fr: HFrameReader = HFrameReader::new();
720 
721         // Construct an unknown frame.
722         const UNKNOWN_FRAME_LEN: usize = 832;
723         let mut enc = Encoder::with_capacity(UNKNOWN_FRAME_LEN + 4);
724         enc.encode_varint(1028u64); // Arbitrary type.
725         enc.encode_varint(UNKNOWN_FRAME_LEN as u64);
726         let mut buf: Vec<_> = enc.into();
727         buf.resize(UNKNOWN_FRAME_LEN + buf.len(), 0);
728         conn_s.stream_send(stream_id, &buf).unwrap();
729         let out = conn_s.process(None, now());
730         conn_c.process(out.dgram(), now());
731         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
732 
733         // now receive a CANCEL_PUSH fram to see that frame reader is ok.
734         conn_s.stream_send(stream_id, &[0x03, 0x01, 0x05]).unwrap();
735         let out = conn_s.process(None, now());
736         conn_c.process(out.dgram(), now());
737         assert_eq!(Ok(false), fr.receive(&mut conn_c, stream_id));
738 
739         assert!(fr.done());
740         let f = fr.get_frame();
741         assert!(f.is_ok());
742         if let HFrame::CancelPush { push_id } = f.unwrap() {
743             assert!(push_id == 5);
744         } else {
745             panic!("wrong frame type");
746         }
747     }
748 
749     enum FrameReadingTestSend {
750         OnlyData,
751         DataWithFin,
752         DataThenFin,
753     }
754 
755     enum FrameReadingTestExpect {
756         Error,
757         Incomplete,
758         FrameComplete,
759         FrameAndStreamComplete,
760         StreamDoneWithoutFrame,
761     }
762 
test_reading_frame( buf: &[u8], test_to_send: FrameReadingTestSend, expected_result: FrameReadingTestExpect, )763     fn test_reading_frame(
764         buf: &[u8],
765         test_to_send: FrameReadingTestSend,
766         expected_result: FrameReadingTestExpect,
767     ) {
768         let (mut conn_c, mut conn_s) = connect();
769 
770         // create a stream
771         let stream_id = conn_s.stream_create(StreamType::BiDi).unwrap();
772 
773         conn_s.stream_send(stream_id, &buf).unwrap();
774         if let FrameReadingTestSend::DataWithFin = test_to_send {
775             conn_s.stream_close_send(stream_id).unwrap();
776         }
777 
778         let out = conn_s.process(None, now());
779         conn_c.process(out.dgram(), now());
780 
781         if let FrameReadingTestSend::DataThenFin = test_to_send {
782             conn_s.stream_close_send(stream_id).unwrap();
783             let out = conn_s.process(None, now());
784             conn_c.process(out.dgram(), now());
785         }
786 
787         let mut fr = HFrameReader::new();
788         let rv = fr.receive(&mut conn_c, stream_id);
789 
790         match expected_result {
791             FrameReadingTestExpect::Error => assert_eq!(Err(Error::HttpFrameError), rv),
792             FrameReadingTestExpect::Incomplete => {
793                 assert_eq!(Ok(false), rv);
794                 assert_eq!(false, fr.done());
795             }
796             FrameReadingTestExpect::FrameComplete => {
797                 assert_eq!(Ok(false), rv);
798                 assert_eq!(true, fr.done());
799             }
800             FrameReadingTestExpect::FrameAndStreamComplete => {
801                 assert_eq!(Ok(true), rv);
802                 assert_eq!(true, fr.done());
803             }
804             FrameReadingTestExpect::StreamDoneWithoutFrame => {
805                 assert_eq!(Ok(true), rv);
806                 assert_eq!(false, fr.done());
807             }
808         };
809     }
810 
811     #[test]
test_complete_and_incomplete_unknown_frame()812     fn test_complete_and_incomplete_unknown_frame() {
813         // Construct an unknown frame.
814         const UNKNOWN_FRAME_LEN: usize = 832;
815         let mut enc = Encoder::with_capacity(UNKNOWN_FRAME_LEN + 4);
816         enc.encode_varint(1028u64); // Arbitrary type.
817         enc.encode_varint(UNKNOWN_FRAME_LEN as u64);
818         let mut buf: Vec<_> = enc.into();
819         buf.resize(UNKNOWN_FRAME_LEN + buf.len(), 0);
820 
821         let len = std::cmp::min(buf.len() - 1, 10);
822         for i in 1..len {
823             test_reading_frame(
824                 &buf[..i],
825                 FrameReadingTestSend::OnlyData,
826                 FrameReadingTestExpect::Incomplete,
827             );
828             test_reading_frame(
829                 &buf[..i],
830                 FrameReadingTestSend::DataWithFin,
831                 FrameReadingTestExpect::Error,
832             );
833             test_reading_frame(
834                 &buf[..i],
835                 FrameReadingTestSend::DataThenFin,
836                 FrameReadingTestExpect::Error,
837             );
838         }
839         test_reading_frame(
840             &buf,
841             FrameReadingTestSend::OnlyData,
842             FrameReadingTestExpect::Incomplete,
843         );
844         test_reading_frame(
845             &buf,
846             FrameReadingTestSend::DataWithFin,
847             FrameReadingTestExpect::StreamDoneWithoutFrame,
848         );
849         test_reading_frame(
850             &buf,
851             FrameReadingTestSend::DataThenFin,
852             FrameReadingTestExpect::StreamDoneWithoutFrame,
853         );
854     }
855 
856     // if we read more than done_state bytes HFrameReader will be in done state.
test_complete_and_incomplete_frame(buf: &[u8], done_state: usize)857     fn test_complete_and_incomplete_frame(buf: &[u8], done_state: usize) {
858         use std::cmp::Ordering;
859         // Let's consume partial frames. It is enough to test partal frames
860         // up to 10 byte. 10 byte is greater than frame type and frame
861         // length and bit of data.
862         let len = std::cmp::min(buf.len() - 1, 10);
863         for i in 1..len {
864             test_reading_frame(
865                 &buf[..i],
866                 FrameReadingTestSend::OnlyData,
867                 if i >= done_state {
868                     FrameReadingTestExpect::FrameComplete
869                 } else {
870                     FrameReadingTestExpect::Incomplete
871                 },
872             );
873             test_reading_frame(
874                 &buf[..i],
875                 FrameReadingTestSend::DataWithFin,
876                 match i.cmp(&done_state) {
877                     Ordering::Greater => FrameReadingTestExpect::FrameComplete,
878                     Ordering::Equal => FrameReadingTestExpect::FrameAndStreamComplete,
879                     Ordering::Less => FrameReadingTestExpect::Error,
880                 },
881             );
882             test_reading_frame(
883                 &buf[..i],
884                 FrameReadingTestSend::DataThenFin,
885                 match i.cmp(&done_state) {
886                     Ordering::Greater => FrameReadingTestExpect::FrameComplete,
887                     Ordering::Equal => FrameReadingTestExpect::FrameAndStreamComplete,
888                     Ordering::Less => FrameReadingTestExpect::Error,
889                 },
890             );
891         }
892         test_reading_frame(
893             buf,
894             FrameReadingTestSend::OnlyData,
895             FrameReadingTestExpect::FrameComplete,
896         );
897         test_reading_frame(
898             buf,
899             FrameReadingTestSend::DataWithFin,
900             if buf.len() == done_state {
901                 FrameReadingTestExpect::FrameAndStreamComplete
902             } else {
903                 FrameReadingTestExpect::FrameComplete
904             },
905         );
906         test_reading_frame(
907             buf,
908             FrameReadingTestSend::DataThenFin,
909             if buf.len() == done_state {
910                 FrameReadingTestExpect::FrameAndStreamComplete
911             } else {
912                 FrameReadingTestExpect::FrameComplete
913             },
914         );
915     }
916 
917     #[test]
test_complete_and_incomplete_frames()918     fn test_complete_and_incomplete_frames() {
919         const FRAME_LEN: usize = 10;
920         const HEADER_BLOCK: &[u8] = &[0x01, 0x02, 0x03, 0x04];
921 
922         // H3_FRAME_TYPE_DATA len=0
923         let f = HFrame::Data { len: 0 };
924         let mut enc = Encoder::with_capacity(2);
925         f.encode(&mut enc);
926         let buf: Vec<_> = enc.into();
927         test_complete_and_incomplete_frame(&buf, 2);
928 
929         // H3_FRAME_TYPE_DATA len=FRAME_LEN
930         let f = HFrame::Data {
931             len: FRAME_LEN as u64,
932         };
933         let mut enc = Encoder::with_capacity(2);
934         f.encode(&mut enc);
935         let mut buf: Vec<_> = enc.into();
936         buf.resize(FRAME_LEN + buf.len(), 0);
937         test_complete_and_incomplete_frame(&buf, 2);
938 
939         // H3_FRAME_TYPE_HEADERS empty header block
940         let f = HFrame::Headers {
941             header_block: Vec::new(),
942         };
943         let mut enc = Encoder::default();
944         f.encode(&mut enc);
945         let buf: Vec<_> = enc.into();
946         test_complete_and_incomplete_frame(&buf, 2);
947 
948         // H3_FRAME_TYPE_HEADERS
949         let f = HFrame::Headers {
950             header_block: HEADER_BLOCK.to_vec(),
951         };
952         let mut enc = Encoder::default();
953         f.encode(&mut enc);
954         let buf: Vec<_> = enc.into();
955         test_complete_and_incomplete_frame(&buf, buf.len());
956 
957         // H3_FRAME_TYPE_CANCEL_PUSH
958         let f = HFrame::CancelPush { push_id: 5 };
959         let mut enc = Encoder::default();
960         f.encode(&mut enc);
961         let buf: Vec<_> = enc.into();
962         test_complete_and_incomplete_frame(&buf, buf.len());
963 
964         // H3_FRAME_TYPE_SETTINGS
965         let f = HFrame::Settings {
966             settings: HSettings::new(&[HSetting::new(HSettingType::MaxHeaderListSize, 4)]),
967         };
968         let mut enc = Encoder::default();
969         f.encode(&mut enc);
970         let buf: Vec<_> = enc.into();
971         test_complete_and_incomplete_frame(&buf, buf.len());
972 
973         // H3_FRAME_TYPE_PUSH_PROMISE
974         let f = HFrame::PushPromise {
975             push_id: 4,
976             header_block: HEADER_BLOCK.to_vec(),
977         };
978         let mut enc = Encoder::default();
979         f.encode(&mut enc);
980         let buf: Vec<_> = enc.into();
981         test_complete_and_incomplete_frame(&buf, buf.len());
982 
983         // H3_FRAME_TYPE_GOAWAY
984         let f = HFrame::Goaway { stream_id: 5 };
985         let mut enc = Encoder::default();
986         f.encode(&mut enc);
987         let buf: Vec<_> = enc.into();
988         test_complete_and_incomplete_frame(&buf, buf.len());
989 
990         // H3_FRAME_TYPE_MAX_PUSH_ID
991         let f = HFrame::MaxPushId { push_id: 5 };
992         let mut enc = Encoder::default();
993         f.encode(&mut enc);
994         let buf: Vec<_> = enc.into();
995         test_complete_and_incomplete_frame(&buf, buf.len());
996 
997         // H3_FRAME_TYPE_DUPLICATE_PUSH
998         let f = HFrame::DuplicatePush { push_id: 5 };
999         let mut enc = Encoder::default();
1000         f.encode(&mut enc);
1001         let buf: Vec<_> = enc.into();
1002         test_complete_and_incomplete_frame(&buf, buf.len());
1003     }
1004 
1005     // Test closing a stream before any frame is sent should not cause an error.
1006     #[test]
test_frame_reading_when_stream_is_closed_before_sending_data()1007     fn test_frame_reading_when_stream_is_closed_before_sending_data() {
1008         let (mut conn_c, mut conn_s) = connect();
1009 
1010         // create a stream
1011         let stream_id = conn_s.stream_create(StreamType::BiDi).unwrap();
1012         conn_s.stream_send(stream_id, &[0x00]).unwrap();
1013         let out = conn_s.process(None, now());
1014         conn_c.process(out.dgram(), now());
1015 
1016         let mut fr: HFrameReader = HFrameReader::new();
1017         assert_eq!(Ok(()), conn_c.stream_close_send(stream_id));
1018         let out = conn_c.process(None, now());
1019         conn_s.process(out.dgram(), now());
1020         assert_eq!(Ok(true), fr.receive(&mut conn_s, stream_id));
1021     }
1022 }
1023