Return an error instead of panicking when stuck in a CONTINUATION loop
It is not rare a large header can trigger such a CONTINUATION loop. While the stream cannot recover from this issue, returning an error instead of panicking makes the impact radius under better control.
This commit is contained in:
		| @@ -148,6 +148,12 @@ where | |||||||
|             match self.encoder.unset_frame() { |             match self.encoder.unset_frame() { | ||||||
|                 ControlFlow::Continue => (), |                 ControlFlow::Continue => (), | ||||||
|                 ControlFlow::Break => break, |                 ControlFlow::Break => break, | ||||||
|  |                 ControlFlow::EndlessLoopHeaderTooBig => { | ||||||
|  |                     return Poll::Ready(Err(std::io::Error::new( | ||||||
|  |                         std::io::ErrorKind::InvalidInput, | ||||||
|  |                         UserError::HeaderTooBig, | ||||||
|  |                     ))); | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -193,6 +199,7 @@ where | |||||||
| enum ControlFlow { | enum ControlFlow { | ||||||
|     Continue, |     Continue, | ||||||
|     Break, |     Break, | ||||||
|  |     EndlessLoopHeaderTooBig, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<B> Encoder<B> | impl<B> Encoder<B> | ||||||
| @@ -222,7 +229,10 @@ where | |||||||
|                         // If *only* the CONTINUATION frame header was |                         // If *only* the CONTINUATION frame header was | ||||||
|                         // written, and *no* header fields, we're stuck |                         // written, and *no* header fields, we're stuck | ||||||
|                         // in a loop... |                         // in a loop... | ||||||
|                         panic!("CONTINUATION frame write loop; header value too big to encode"); |                         tracing::warn!( | ||||||
|  |                             "CONTINUATION frame write loop; header value too big to encode" | ||||||
|  |                         ); | ||||||
|  |                         return ControlFlow::EndlessLoopHeaderTooBig; | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                     self.next = Some(Next::Continuation(continuation)); |                     self.next = Some(Next::Continuation(continuation)); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user