1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//! Shared error type for HPACK/QPACK header compression.
//!
//! Both protocols decode into a near-identical error vocabulary: Huffman malformed input,
//! integer-prefix decode failure, static-table index out of range, unexpected end of input,
//! and invalid field name. Each protocol maps the enum to its own wire-level
//! connection-error code via a `From` impl.
use super::{huffman::HuffmanError, integer_prefix::IntegerPrefixError};
use crate::h3::{H3Error, H3ErrorCode};
/// Errors produced by the header-compression codecs (HPACK and QPACK).
#[derive(Debug, thiserror::Error, Clone, Copy)]
pub(crate) enum CompressionError {
#[error(transparent)]
Huffman(#[from] HuffmanError),
#[error(transparent)]
IntegerPrefix(#[from] IntegerPrefixError),
#[error("static table index {0} out of range")]
InvalidStaticIndex(usize),
#[error("unexpected end of field section")]
UnexpectedEnd,
#[error("invalid header name")]
InvalidHeaderName,
}
impl From<CompressionError> for H3Error {
/// Most `CompressionError` variants are codec failures the QPACK layer reports as
/// `QPACK_DECOMPRESSION_FAILED`. `InvalidHeaderName` is the exception: a header name
/// with uppercase chars or an unrecognized pseudo-name is a *malformed-message*
/// problem (the codec succeeded; the resulting message is invalid), which is a
/// stream-level `H3_MESSAGE_ERROR`.
fn from(error: CompressionError) -> Self {
match error {
CompressionError::InvalidHeaderName => H3ErrorCode::MessageError.into(),
CompressionError::Huffman(_)
| CompressionError::IntegerPrefix(_)
| CompressionError::InvalidStaticIndex(_)
| CompressionError::UnexpectedEnd => H3ErrorCode::QpackDecompressionFailed.into(),
}
}
}