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