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:
Yuchen Wu
2020-12-23 14:08:50 -08:00
committed by Sean McArthur
parent bcaaaf6dd9
commit 11229702a0

View File

@@ -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));