Handle more H2 details
This commit is contained in:
		| @@ -85,6 +85,9 @@ pub fn from_framed_write<T, P, B>(framed_write: FramedWrite<T, B::Buf>) | ||||
|         .length_field_length(3) | ||||
|         .length_adjustment(9) | ||||
|         .num_skip(0) // Don't skip the header | ||||
|         // TODO: make this configurable and allow it to be changed during | ||||
|         // runtime. | ||||
|         .max_frame_length(frame::DEFAULT_MAX_FRAME_SIZE as usize) | ||||
|         .new_read(framed_write); | ||||
|  | ||||
|     let codec = FramedRead::new(framed); | ||||
|   | ||||
| @@ -21,6 +21,9 @@ pub(super) struct Recv<B> { | ||||
|     /// Connection level flow control governing received data | ||||
|     flow_control: FlowControl, | ||||
|  | ||||
|     /// The lowest stream ID that is still idle | ||||
|     next_stream_id: StreamId, | ||||
|  | ||||
|     /// Streams that have pending window updates | ||||
|     /// TODO: don't use a VecDeque | ||||
|     pending_window_updates: VecDeque<StreamId>, | ||||
| @@ -50,12 +53,19 @@ struct Indices { | ||||
| } | ||||
|  | ||||
| impl<B> Recv<B> where B: Buf { | ||||
|     pub fn new(config: &Config) -> Self { | ||||
|     pub fn new<P: Peer>(config: &Config) -> Self { | ||||
|         let next_stream_id = if P::is_server() { | ||||
|             1 | ||||
|         } else { | ||||
|             2 | ||||
|         }; | ||||
|  | ||||
|         Recv { | ||||
|             max_streams: config.max_remote_initiated, | ||||
|             num_streams: 0, | ||||
|             init_window_sz: config.init_remote_window_sz, | ||||
|             flow_control: FlowControl::new(config.init_remote_window_sz), | ||||
|             next_stream_id: next_stream_id.into(), | ||||
|             pending_window_updates: VecDeque::new(), | ||||
|             pending_accept: store::List::new(), | ||||
|             buffer: Buffer::new(), | ||||
| @@ -129,6 +139,13 @@ impl<B> Recv<B> where B: Buf { | ||||
|                 unimplemented!(); | ||||
|             } | ||||
|  | ||||
|             if frame.stream_id() >= self.next_stream_id { | ||||
|                 self.next_stream_id = frame.stream_id(); | ||||
|                 self.next_stream_id.increment(); | ||||
|             } else { | ||||
|                 return Err(ProtocolError.into()); | ||||
|             } | ||||
|  | ||||
|             // Increment the number of concurrent streams | ||||
|             self.inc_num_streams(); | ||||
|         } | ||||
| @@ -246,6 +263,14 @@ impl<B> Recv<B> where B: Buf { | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     pub fn ensure_not_idle(&self, id: StreamId) -> Result<(), ConnectionError> { | ||||
|         if id >= self.next_stream_id { | ||||
|             return Err(ProtocolError.into()); | ||||
|         } | ||||
|  | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     pub fn recv_reset(&mut self, frame: frame::Reset, stream: &mut Stream<B>) | ||||
|         -> Result<(), ConnectionError> | ||||
|     { | ||||
|   | ||||
| @@ -273,6 +273,14 @@ impl<B> Send<B> where B: Buf { | ||||
|         0 | ||||
|     } | ||||
|  | ||||
|     pub fn ensure_not_idle(&self, id: StreamId) -> Result<(), ConnectionError> { | ||||
|         if id >= self.next_stream_id { | ||||
|             return Err(ProtocolError.into()); | ||||
|         } | ||||
|  | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     pub fn dec_num_streams(&mut self) { | ||||
|         self.num_streams -= 1; | ||||
|     } | ||||
|   | ||||
| @@ -53,7 +53,7 @@ impl<B> Streams<B> | ||||
|         Streams { | ||||
|             inner: Arc::new(Mutex::new(Inner { | ||||
|                 actions: Actions { | ||||
|                     recv: Recv::new(&config), | ||||
|                     recv: Recv::new::<P>(&config), | ||||
|                     send: Send::new::<P>(&config), | ||||
|                 }, | ||||
|                 store: Store::new(), | ||||
| @@ -129,10 +129,17 @@ impl<B> Streams<B> | ||||
|  | ||||
|         let id = frame.stream_id(); | ||||
|  | ||||
|         if id.is_zero() { | ||||
|             return Err(ProtocolError.into()); | ||||
|         } | ||||
|  | ||||
|         let mut stream = match me.store.find_mut(&id) { | ||||
|             Some(stream) => stream, | ||||
|             // TODO: should this be an error? | ||||
|             None => return Ok(()), | ||||
|             None => { | ||||
|                 // TODO: Are there other error cases? | ||||
|                 me.actions.ensure_not_idle::<P>(id)?; | ||||
|                 return Ok(()); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         me.actions.transition::<P, _, _>(stream, |actions, stream| { | ||||
| @@ -165,6 +172,8 @@ impl<B> Streams<B> | ||||
|             // considers closed. It's ok... | ||||
|             if let Some(mut stream) = me.store.find_mut(&id) { | ||||
|                 try!(me.actions.send.recv_stream_window_update(frame, &mut stream)); | ||||
|             } else { | ||||
|                 me.actions.recv.ensure_not_idle(id)?; | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -413,6 +422,16 @@ impl<B> Drop for Chunk<B> | ||||
| impl<B> Actions<B> | ||||
|     where B: Buf, | ||||
| { | ||||
|     fn ensure_not_idle<P: Peer>(&mut self, id: StreamId) | ||||
|         -> Result<(), ConnectionError> | ||||
|     { | ||||
|         if self.is_local_init::<P>(id) { | ||||
|             self.send.ensure_not_idle(id) | ||||
|         } else { | ||||
|             self.recv.ensure_not_idle(id) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn dec_num_streams<P: Peer>(&mut self, id: StreamId) { | ||||
|         if self.is_local_init::<P>(id) { | ||||
|             self.send.dec_num_streams(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user