Skip to content

Start decoding headers once enought data is received #294

Open
@Ruben2424

Description

@Ruben2424

At the moment client and server are using

h3/h3/src/qpack/decoder.rs

Lines 216 to 260 in 9b02824

// Decode field lines received on Request or Push stream.
// https://www.rfc-editor.org/rfc/rfc9204.html#name-field-line-representations
pub fn decode_stateless<T: Buf>(buf: &mut T, max_size: u64) -> Result<Decoded, Error> {
let (required_ref, _base) = HeaderPrefix::decode(buf)?.get(0, 0)?;
if required_ref > 0 {
return Err(Error::MissingRefs(required_ref));
}
let mut mem_size = 0;
let mut fields = Vec::new();
while buf.has_remaining() {
let field = match HeaderBlockField::decode(buf.chunk()[0]) {
HeaderBlockField::IndexedWithPostBase => return Err(Error::MissingRefs(0)),
HeaderBlockField::LiteralWithPostBaseNameRef => return Err(Error::MissingRefs(0)),
HeaderBlockField::Indexed => match Indexed::decode(buf)? {
Indexed::Static(index) => StaticTable::get(index)?.clone(),
Indexed::Dynamic(_) => return Err(Error::MissingRefs(0)),
},
HeaderBlockField::LiteralWithNameRef => match LiteralWithNameRef::decode(buf)? {
LiteralWithNameRef::Dynamic { .. } => return Err(Error::MissingRefs(0)),
LiteralWithNameRef::Static { index, value } => {
StaticTable::get(index)?.with_value(value)
}
},
HeaderBlockField::Literal => {
let literal = Literal::decode(buf)?;
HeaderField::new(literal.name, literal.value)
}
_ => return Err(Error::UnknownPrefix(buf.chunk()[0])),
};
mem_size += field.mem_size() as u64;
// Cancel decoding if the header is considered too big
if mem_size > max_size {
return Err(Error::HeaderTooLong(mem_size));
}
fields.push(field);
}
Ok(Decoded {
fields,
mem_size,
dyn_ref: false,
})
}

To decode headers.
The spec says for the SETTINGS_MAX_FIELD_SECTION_SIZE Setting:

Spec 4.2.2

The size of a field list is calculated based on the uncompressed size of fields, including the length of the name and value in bytes plus an overhead of 32 bytes for each field.

Because the decoding is stateless, the hole header frame needs to be received before the header can be parsed. So if the MAX_FIELD_SECTION_SIZE setting is set for h3 it will only have a limited effect for now, because the limit only aborts the parsing but the hole header is in memory.

The parsing of the headers should start once enough data is received.
It makes probably sense to implement this functionality into the already existing Decoder struct from the qpack module. The Encoder struct and the dynamic table feature can be integrated to.

pub struct Decoder {
table: DynamicTable,
}

The duvet tags could also be filled in for qpack rfc 9204.

Metadata

Metadata

Assignees

Labels

C-featureCategory: feature. This is adding a new feature.C-refactorCategory: refactor. This would improve the clarity of internal code.E-hardEffort: hard. Likely requires a deeper understanding of how the internals work.

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions