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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
use crate::http::errors::*; use crate::http::{guess_accept_mime, header, Request, Response, StatusCode}; pub trait Catcher: Send + Sync + 'static { fn catch(&self, req: &Request, res: &mut Response) -> bool; } pub struct CatcherImpl(HttpError); impl CatcherImpl { pub fn new(e: HttpError) -> CatcherImpl { CatcherImpl(e) } } impl Catcher for CatcherImpl { fn catch(&self, req: &Request, res: &mut Response) -> bool { let status = res.status_code().unwrap_or(StatusCode::NOT_FOUND); if status != self.0.code { return false; } let format = guess_accept_mime(req, None); let err = if res.http_error.is_some() { res.http_error.as_ref().unwrap() } else { &self.0 }; let (format, data) = err.as_bytes(&format); res.headers_mut().insert(header::CONTENT_TYPE, format.to_string().parse().unwrap()); res.write_body_bytes(&data); true } } macro_rules! default_catchers { ($($code:expr),+) => ( let mut list: Vec<Box<dyn Catcher>> = vec![]; $( list.push(Box::new(CatcherImpl::new($crate::http::errors::http_error::from_code($code).unwrap()))); )+ list ) } pub mod defaults { use super::{Catcher, CatcherImpl}; use http::status::StatusCode; pub fn get() -> Vec<Box<dyn Catcher>> { default_catchers! { StatusCode::BAD_REQUEST, StatusCode::UNAUTHORIZED, StatusCode::PAYMENT_REQUIRED, StatusCode::FORBIDDEN, StatusCode::NOT_FOUND, StatusCode::METHOD_NOT_ALLOWED, StatusCode::NOT_ACCEPTABLE, StatusCode::PROXY_AUTHENTICATION_REQUIRED, StatusCode::REQUEST_TIMEOUT, StatusCode::CONFLICT, StatusCode::GONE, StatusCode::LENGTH_REQUIRED, StatusCode::PRECONDITION_FAILED, StatusCode::PAYLOAD_TOO_LARGE, StatusCode::URI_TOO_LONG, StatusCode::UNSUPPORTED_MEDIA_TYPE, StatusCode::RANGE_NOT_SATISFIABLE, StatusCode::EXPECTATION_FAILED, StatusCode::IM_A_TEAPOT, StatusCode::MISDIRECTED_REQUEST, StatusCode::UNPROCESSABLE_ENTITY, StatusCode::LOCKED, StatusCode::FAILED_DEPENDENCY, StatusCode::UPGRADE_REQUIRED, StatusCode::PRECONDITION_REQUIRED, StatusCode::TOO_MANY_REQUESTS, StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE, StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS, StatusCode::INTERNAL_SERVER_ERROR, StatusCode::NOT_IMPLEMENTED, StatusCode::BAD_GATEWAY, StatusCode::SERVICE_UNAVAILABLE, StatusCode::GATEWAY_TIMEOUT, StatusCode::HTTP_VERSION_NOT_SUPPORTED, StatusCode::VARIANT_ALSO_NEGOTIATES, StatusCode::INSUFFICIENT_STORAGE, StatusCode::LOOP_DETECTED, StatusCode::NOT_EXTENDED, StatusCode::NETWORK_AUTHENTICATION_REQUIRED } } }