1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-27 09:42:57 +01:00

normalize actix-files error messages

This commit is contained in:
Rob Ede 2023-03-13 14:22:50 +00:00
parent 0e7380659f
commit bfdc29ebb8
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
2 changed files with 58 additions and 32 deletions

View File

@ -4,46 +4,44 @@ use derive_more::Display;
/// Errors which can occur when serving static files. /// Errors which can occur when serving static files.
#[derive(Debug, PartialEq, Eq, Display)] #[derive(Debug, PartialEq, Eq, Display)]
pub enum FilesError { pub enum FilesError {
/// Path is not a directory /// Path is not a directory.
#[allow(dead_code)] #[allow(dead_code)]
#[display(fmt = "Path is not a directory. Unable to serve static files")] #[display(fmt = "path is not a directory. Unable to serve static files")]
IsNotDirectory, IsNotDirectory,
/// Cannot render directory /// Cannot render directory.
#[display(fmt = "Unable to render directory without index file")] #[display(fmt = "unable to render directory without index file")]
IsDirectory, IsDirectory,
} }
/// Return `NotFound` for `FilesError`
impl ResponseError for FilesError { impl ResponseError for FilesError {
/// Returns `404 Not Found`.
fn status_code(&self) -> StatusCode { fn status_code(&self) -> StatusCode {
StatusCode::NOT_FOUND StatusCode::NOT_FOUND
} }
} }
#[allow(clippy::enum_variant_names)]
#[derive(Debug, PartialEq, Eq, Display)] #[derive(Debug, PartialEq, Eq, Display)]
#[non_exhaustive] #[non_exhaustive]
pub enum UriSegmentError { pub enum UriSegmentError {
/// The segment started with the wrapped invalid character. /// Segment started with the wrapped invalid character.
#[display(fmt = "The segment started with the wrapped invalid character")] #[display(fmt = "segment started with invalid character: ('{_0}')")]
BadStart(char), BadStart(char),
/// The segment contained the wrapped invalid character. /// Segment contained the wrapped invalid character.
#[display(fmt = "The segment contained the wrapped invalid character")] #[display(fmt = "segment contained invalid character ('{_0}')")]
BadChar(char), BadChar(char),
/// The segment ended with the wrapped invalid character. /// Segment ended with the wrapped invalid character.
#[display(fmt = "The segment ended with the wrapped invalid character")] #[display(fmt = "segment ended with invalid character: ('{_0}')")]
BadEnd(char), BadEnd(char),
// /// Path is not a valid UTF-8 string after percent-decoding.
/// The path is not a valid UTF-8 string after doing percent decoding. // #[display(fmt = "path is not a valid UTF-8 string after percent-decoding")]
#[display(fmt = "The path is not a valid UTF-8 string after percent-decoding")] // NotValidUtf8,
NotValidUtf8,
} }
/// Return `BadRequest` for `UriSegmentError`
impl ResponseError for UriSegmentError { impl ResponseError for UriSegmentError {
/// Returns `400 Bad Request`.
fn status_code(&self) -> StatusCode { fn status_code(&self) -> StatusCode {
StatusCode::BAD_REQUEST StatusCode::BAD_REQUEST
} }

View File

@ -1,4 +1,36 @@
use derive_more::{Display, Error}; use std::fmt;
use derive_more::Error;
/// Copy of `http_range::HttpRangeParseError`.
#[derive(Debug, Clone)]
enum HttpRangeParseError {
InvalidRange,
NoOverlap,
}
impl From<http_range::HttpRangeParseError> for HttpRangeParseError {
fn from(err: http_range::HttpRangeParseError) -> Self {
match err {
http_range::HttpRangeParseError::InvalidRange => Self::InvalidRange,
http_range::HttpRangeParseError::NoOverlap => Self::NoOverlap,
}
}
}
#[derive(Debug, Clone, Error)]
#[non_exhaustive]
pub struct ParseRangeErr(#[error(not(source))] HttpRangeParseError);
impl fmt::Display for ParseRangeErr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("invalid Range header: ")?;
f.write_str(match self.0 {
HttpRangeParseError::InvalidRange => "invalid syntax",
HttpRangeParseError::NoOverlap => "range starts after end of content",
})
}
}
/// HTTP Range header representation. /// HTTP Range header representation.
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -10,26 +42,22 @@ pub struct HttpRange {
pub length: u64, pub length: u64,
} }
#[derive(Debug, Clone, Display, Error)]
#[display(fmt = "Parse HTTP Range failed")]
pub struct ParseRangeErr(#[error(not(source))] ());
impl HttpRange { impl HttpRange {
/// Parses Range HTTP header string as per RFC 2616. /// Parses Range HTTP header string as per RFC 2616.
/// ///
/// `header` is HTTP Range header (e.g. `bytes=bytes=0-9`). /// `header` is HTTP Range header (e.g. `bytes=bytes=0-9`).
/// `size` is full size of response (file). /// `size` is full size of response (file).
pub fn parse(header: &str, size: u64) -> Result<Vec<HttpRange>, ParseRangeErr> { pub fn parse(header: &str, size: u64) -> Result<Vec<HttpRange>, ParseRangeErr> {
match http_range::HttpRange::parse(header, size) { let ranges = http_range::HttpRange::parse(header, size)
Ok(ranges) => Ok(ranges .map_err(|err| ParseRangeErr(err.into()))?;
.iter()
.map(|range| HttpRange { Ok(ranges
start: range.start, .iter()
length: range.length, .map(|range| HttpRange {
}) start: range.start,
.collect()), length: range.length,
Err(_) => Err(ParseRangeErr(())), })
} .collect())
} }
} }