-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5e3b71b
commit be08b7d
Showing
11 changed files
with
272 additions
and
206 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
use core::{any::type_name, fmt}; | ||
|
||
use std::error; | ||
|
||
use super::{error_from_service, forward_blank_bad_request}; | ||
|
||
/// error type for typed instance can't be found from [`Extensions`] | ||
/// | ||
/// [`Extensions`]: crate::http::Extensions | ||
#[derive(Debug)] | ||
pub struct ExtensionNotFound(&'static str); | ||
|
||
impl ExtensionNotFound { | ||
pub(crate) fn from_type<T>() -> Self { | ||
Self(type_name::<T>()) | ||
} | ||
} | ||
|
||
impl fmt::Display for ExtensionNotFound { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
write!(f, "{} type can't be found from Extensions", self.0) | ||
} | ||
} | ||
|
||
impl error::Error for ExtensionNotFound {} | ||
|
||
error_from_service!(ExtensionNotFound); | ||
forward_blank_bad_request!(ExtensionNotFound); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use core::fmt; | ||
|
||
use std::error; | ||
|
||
use crate::http::HeaderName; | ||
|
||
use super::{error_from_service, forward_blank_bad_request}; | ||
|
||
/// error type when named header is not found from request. | ||
#[derive(Debug)] | ||
pub struct HeaderNotFound(pub HeaderName); | ||
|
||
impl fmt::Display for HeaderNotFound { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
write!(f, "HeaderName: {} is not found", self.0.as_str()) | ||
} | ||
} | ||
|
||
impl error::Error for HeaderNotFound {} | ||
|
||
error_from_service!(HeaderNotFound); | ||
forward_blank_bad_request!(HeaderNotFound); | ||
|
||
/// error type when named header is not associated with valid header value. | ||
#[derive(Debug)] | ||
pub struct InvalidHeaderValue(pub HeaderName); | ||
|
||
impl fmt::Display for InvalidHeaderValue { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
write!(f, "HeaderName: {} associated with invalid HeaderValue", self.0.as_str()) | ||
} | ||
} | ||
|
||
impl error::Error for InvalidHeaderValue {} | ||
|
||
error_from_service!(InvalidHeaderValue); | ||
forward_blank_bad_request!(InvalidHeaderValue); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
pub use xitca_http::util::service::{ | ||
route::MethodNotAllowed, | ||
router::{MatchError, RouterError}, | ||
}; | ||
|
||
use core::convert::Infallible; | ||
|
||
use crate::{ | ||
body::ResponseBody, | ||
http::{header::ALLOW, StatusCode, WebResponse}, | ||
service::Service, | ||
WebContext, | ||
}; | ||
|
||
use super::{blank_error_service, error_from_service, Error}; | ||
|
||
error_from_service!(MatchError); | ||
blank_error_service!(MatchError, StatusCode::NOT_FOUND); | ||
|
||
error_from_service!(MethodNotAllowed); | ||
|
||
impl<'r, C, B> Service<WebContext<'r, C, B>> for MethodNotAllowed { | ||
type Response = WebResponse; | ||
type Error = Infallible; | ||
|
||
async fn call(&self, ctx: WebContext<'r, C, B>) -> Result<Self::Response, Self::Error> { | ||
let mut res = ctx.into_response(ResponseBody::empty()); | ||
|
||
let allowed = self.allowed_methods(); | ||
|
||
let len = allowed.iter().fold(0, |a, m| a + m.as_str().len() + 1); | ||
|
||
let mut methods = String::with_capacity(len); | ||
|
||
for method in allowed { | ||
methods.push_str(method.as_str()); | ||
methods.push(','); | ||
} | ||
methods.pop(); | ||
|
||
res.headers_mut().insert(ALLOW, methods.parse().unwrap()); | ||
*res.status_mut() = StatusCode::METHOD_NOT_ALLOWED; | ||
|
||
Ok(res) | ||
} | ||
} | ||
|
||
impl<E, C> From<RouterError<E>> for Error<C> | ||
where | ||
E: Into<Self>, | ||
{ | ||
fn from(e: RouterError<E>) -> Self { | ||
match e { | ||
RouterError::Match(e) => e.into(), | ||
RouterError::NotAllowed(e) => e.into(), | ||
RouterError::Service(e) => e.into(), | ||
} | ||
} | ||
} |
Oops, something went wrong.