Support very large headers

This completely refactors how headers are hpack-encoded.

Instead of trying to be clever, constructing frames on the go
while hpack-encoding, we just make a blob of all the
hpack-encoded headers first, and then we split that blob
in as many frames as necessary.
This commit is contained in:
Anthony Ramine
2021-08-20 14:51:11 +02:00
committed by Sean McArthur
parent e9a13700cb
commit 61b4f8fc34
11 changed files with 164 additions and 390 deletions

View File

@@ -35,9 +35,6 @@ pub enum UserError {
/// The payload size is too big
PayloadTooBig,
/// A header size is too big
HeaderTooBig,
/// The application attempted to initiate too many streams to remote.
Rejected,
@@ -130,7 +127,6 @@ impl fmt::Display for UserError {
InactiveStreamId => "inactive stream",
UnexpectedFrameType => "unexpected frame type",
PayloadTooBig => "payload too big",
HeaderTooBig => "header too big",
Rejected => "rejected",
ReleaseCapacityTooBig => "release capacity too big",
OverflowedStreamId => "stream ID overflowed",

View File

@@ -148,12 +148,6 @@ where
match self.encoder.unset_frame() {
ControlFlow::Continue => (),
ControlFlow::Break => break,
ControlFlow::EndlessLoopHeaderTooBig => {
return Poll::Ready(Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
UserError::HeaderTooBig,
)));
}
}
}
@@ -199,7 +193,6 @@ where
enum ControlFlow {
Continue,
Break,
EndlessLoopHeaderTooBig,
}
impl<B> Encoder<B>
@@ -221,20 +214,7 @@ where
Some(Next::Continuation(frame)) => {
// Buffer the continuation frame, then try to write again
let mut buf = limited_write_buf!(self);
if let Some(continuation) = frame.encode(&mut self.hpack, &mut buf) {
// We previously had a CONTINUATION, and after encoding
// it, we got *another* one? Let's just double check
// that at least some progress is being made...
if self.buf.get_ref().len() == frame::HEADER_LEN {
// If *only* the CONTINUATION frame header was
// written, and *no* header fields, we're stuck
// in a loop...
tracing::warn!(
"CONTINUATION frame write loop; header value too big to encode"
);
return ControlFlow::EndlessLoopHeaderTooBig;
}
if let Some(continuation) = frame.encode(&mut buf) {
self.next = Some(Next::Continuation(continuation));
}
ControlFlow::Continue