Handle malformed HEADERS
This commit is contained in:
		| @@ -1,5 +1,4 @@ | ||||
| use {frame, ConnectionError}; | ||||
| use error::User::InactiveStreamId; | ||||
| use proto::*; | ||||
| use super::*; | ||||
|  | ||||
| @@ -101,27 +100,10 @@ impl<B> Send<B> where B: Buf { | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     /// This is called by the user to send a reset and should not be called | ||||
|     /// by internal state transitions. Use `reset_stream` for that. | ||||
|     pub fn send_reset(&mut self, | ||||
|                       reason: Reason, | ||||
|                       stream: &mut store::Ptr<B>, | ||||
|                       task: &mut Option<Task>) | ||||
|         -> Result<(), ConnectionError> | ||||
|     { | ||||
|         if stream.state.is_closed() { | ||||
|             debug!("send_reset; invalid stream ID"); | ||||
|             return Err(InactiveStreamId.into()) | ||||
|         } | ||||
|  | ||||
|         self.reset_stream(reason, stream, task); | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     fn reset_stream(&mut self, | ||||
|                     reason: Reason, | ||||
|                     stream: &mut store::Ptr<B>, | ||||
|                     task: &mut Option<Task>) | ||||
|     { | ||||
|         if stream.state.is_reset() { | ||||
|             // Don't double reset | ||||
| @@ -240,7 +222,7 @@ impl<B> Send<B> where B: Buf { | ||||
|     { | ||||
|         if let Err(e) = self.prioritize.recv_stream_window_update(sz, stream) { | ||||
|             debug!("recv_stream_window_update !!; err={:?}", e); | ||||
|             self.reset_stream(FlowControlError.into(), stream, task); | ||||
|             self.send_reset(FlowControlError.into(), stream, task); | ||||
|         } | ||||
|  | ||||
|         Ok(()) | ||||
|   | ||||
| @@ -312,6 +312,33 @@ impl<B> Streams<B> | ||||
|             key: key, | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     pub fn send_reset<P: Peer>(&mut self, id: StreamId, reason: Reason) { | ||||
|         let mut me = self.inner.lock().unwrap(); | ||||
|         let me = &mut *me; | ||||
|  | ||||
|         let key = match me.store.find_entry(id) { | ||||
|             Entry::Occupied(e) => e.key(), | ||||
|             Entry::Vacant(e) => { | ||||
|                 match me.actions.recv.open::<P>(id) { | ||||
|                     Ok(Some(stream_id)) => { | ||||
|                         let stream = Stream::new( | ||||
|                             stream_id, 0, 0); | ||||
|  | ||||
|                         e.insert(stream) | ||||
|                     } | ||||
|                     _ => return, | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|  | ||||
|         let stream = me.store.resolve(key); | ||||
|  | ||||
|         me.actions.transition::<P, _, _>(stream, move |actions, stream| { | ||||
|             actions.send.send_reset(reason, stream, &mut actions.task) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
|  | ||||
| // ===== impl StreamRef ===== | ||||
| @@ -367,7 +394,7 @@ impl<B> StreamRef<B> | ||||
|         me.actions.recv.take_request(&mut stream) | ||||
|     } | ||||
|  | ||||
|     pub fn send_reset<P: Peer>(&mut self, reason: Reason) -> Result<(), ConnectionError> { | ||||
|     pub fn send_reset<P: Peer>(&mut self, reason: Reason) { | ||||
|         let mut me = self.inner.lock().unwrap(); | ||||
|         let me = &mut *me; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user