#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ParseError {
InvalidHttpVersion,
InvalidMethod,
InvalidRequestTarget,
InvalidStatusCode,
InvalidReasonPhrase,
InvalidHeaderName,
InvalidHeaderValue,
InvalidUri,
MissingCrlf,
BareCarriageReturn,
UnexpectedEndOfInput,
InvalidWhitespace,
LineTooLong,
InvalidChunkSize,
InvalidContentLength,
HeaderTooLarge,
InvalidState,
ConflictingFraming,
ChunkedNotFinal,
WhitespaceBeforeHeaders,
ExtraDataAfterResponse,
MissingHostHeader,
BareCarriageReturnInHeader,
ObsoleteFoldInHeader,
InvalidTransferEncodingForStatus,
ChunkedInTeHeader,
TeHeaderMissingConnection,
MultipleHostHeaders,
InvalidHostHeaderValue,
UriTooLong,
TransferEncodingRequiresHttp11,
ChunkedAppliedMultipleTimes,
DecompressionFailed,
}
impl ParseError {
#[must_use]
pub const fn requires_connection_closure(self) -> bool {
matches!(
self,
Self::ConflictingFraming
| Self::ChunkedNotFinal
| Self::InvalidContentLength
| Self::UnexpectedEndOfInput
| Self::ExtraDataAfterResponse
| Self::WhitespaceBeforeHeaders
| Self::InvalidTransferEncodingForStatus
)
}
}
impl core::fmt::Display for ParseError {
fn fmt(
&self,
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
match self {
Self::InvalidHttpVersion => write!(f, "invalid HTTP version"),
Self::InvalidMethod => write!(f, "invalid method"),
Self::InvalidRequestTarget => write!(f, "invalid request target"),
Self::InvalidStatusCode => write!(f, "invalid status code"),
Self::InvalidReasonPhrase => write!(f, "invalid reason phrase"),
Self::InvalidHeaderName => write!(f, "invalid header name"),
Self::InvalidHeaderValue => write!(f, "invalid header value"),
Self::InvalidUri => write!(f, "invalid URI"),
Self::MissingCrlf => write!(f, "missing CRLF"),
Self::BareCarriageReturn => write!(f, "bare CR not allowed"),
Self::UnexpectedEndOfInput => write!(f, "unexpected end of input"),
Self::InvalidWhitespace => write!(f, "invalid whitespace"),
Self::LineTooLong => write!(f, "line too long"),
Self::InvalidChunkSize => write!(f, "invalid chunk size"),
Self::InvalidContentLength => write!(f, "invalid Content-Length value"),
Self::HeaderTooLarge => write!(f, "response header too large"),
Self::InvalidState => write!(f, "invalid parser state"),
Self::ConflictingFraming => {
write!(f, "both Transfer-Encoding and Content-Length present")
},
Self::ChunkedNotFinal => write!(f, "chunked must be the final Transfer-Encoding"),
Self::WhitespaceBeforeHeaders => {
write!(f, "whitespace found between start-line and first header")
},
Self::ExtraDataAfterResponse => {
write!(f, "extra data found after complete response")
},
Self::MissingHostHeader => write!(f, "Host header required for HTTP/1.1 requests"),
Self::BareCarriageReturnInHeader => {
write!(f, "header value contains bare CR (not allowed)")
},
Self::ObsoleteFoldInHeader => {
write!(f, "header value contains obs-fold (not allowed)")
},
Self::InvalidTransferEncodingForStatus => {
write!(f, "Transfer-Encoding not allowed for this status code")
},
Self::ChunkedInTeHeader => write!(f, "TE header must not contain 'chunked'"),
Self::TeHeaderMissingConnection => {
write!(f, "TE header requires 'TE' in Connection header")
},
Self::MultipleHostHeaders => write!(f, "multiple Host headers present"),
Self::InvalidHostHeaderValue => write!(f, "invalid Host header value format"),
Self::UriTooLong => write!(f, "request-target URI exceeds maximum allowed length"),
Self::TransferEncodingRequiresHttp11 => {
write!(f, "Transfer-Encoding requires HTTP/1.1 or higher")
},
Self::ChunkedAppliedMultipleTimes => {
write!(f, "chunked transfer coding applied multiple times")
},
Self::DecompressionFailed => write!(f, "failed to decompress response body"),
}
}
}