eggress-protocol-http 1.0.3

HTTP/1.1 CONNECT protocol for eggress proxy
Documentation
/// Error types for HTTP proxy protocol operations.
#[derive(Debug, thiserror::Error)]
pub enum HttpError {
    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),

    #[error("malformed request: {0}")]
    MalformedRequest(String),

    #[error("malformed response: {0}")]
    MalformedResponse(String),

    #[error("unsupported HTTP version: {0}")]
    UnsupportedVersion(String),

    #[error("missing required header: {0}")]
    MissingHeader(String),

    #[error("invalid header value: {0}")]
    InvalidHeaderValue(String),

    #[error("header too large")]
    HeaderTooLarge,

    #[error("too many header lines")]
    TooManyHeaders,

    #[error("target address parse error: {0}")]
    TargetParseError(String),

    #[error("authentication required (407 Proxy Authentication Required)")]
    AuthRequired,

    #[error("authentication failed (403 Forbidden)")]
    AuthFailed,

    #[error("connection refused by upstream")]
    ConnectionRefused,

    #[error("gateway timeout (504)")]
    GatewayTimeout,

    #[error("bad gateway (502)")]
    BadGateway,

    #[error("unexpected status code: {0}")]
    UnexpectedStatus(u16),

    #[error("upstream error: {0}")]
    Upstream(String),

    #[error("invalid Content-Length header")]
    InvalidContentLength,

    #[error("conflicting Content-Length values")]
    ConflictingContentLength,

    #[error("Transfer-Encoding with Content-Length is not allowed")]
    TransferEncodingWithContentLength,

    #[error("unsupported transfer encoding: {0}")]
    UnsupportedTransferEncoding(String),

    #[error("chunked transfer encoding must be the final coding")]
    ChunkedNotFinal,

    #[error("invalid credentials: control characters not allowed")]
    InvalidCredentials,

    #[error("HTTP expectation is not supported")]
    ExpectationFailed,

    #[error("HTTP protocol upgrade is not supported")]
    UpgradeUnsupported,

    #[error("too many informational responses")]
    TooManyInformationalResponses,
}

impl HttpError {
    /// Returns the appropriate HTTP status code for this error.
    pub fn status_code(&self) -> u16 {
        match self {
            HttpError::MalformedRequest(_) => 400,
            HttpError::AuthRequired => 407,
            HttpError::AuthFailed => 403,
            HttpError::ConnectionRefused => 502,
            HttpError::BadGateway => 502,
            HttpError::GatewayTimeout => 504,
            HttpError::HeaderTooLarge => 431,
            HttpError::TooManyHeaders => 431,
            HttpError::InvalidContentLength => 400,
            HttpError::ConflictingContentLength => 400,
            HttpError::TransferEncodingWithContentLength => 400,
            HttpError::UnsupportedTransferEncoding(_) => 400,
            HttpError::ChunkedNotFinal => 400,
            HttpError::InvalidCredentials => 400,
            HttpError::ExpectationFailed => 417,
            HttpError::UpgradeUnsupported => 501,
            HttpError::TooManyInformationalResponses => 502,
            _ => 500,
        }
    }
}