chore: add reject_filters
This commit is contained in:
parent
c5bfc9df7f
commit
ef85f32cb6
10
reject_filters/.gitignore
vendored
Normal file
10
reject_filters/.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/target
|
||||
target
|
||||
Cargo.lock
|
||||
.cache
|
||||
.temp
|
||||
.env
|
||||
*.log
|
||||
.DS_Store
|
||||
logs
|
||||
tmp
|
14
reject_filters/Cargo.toml
Normal file
14
reject_filters/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "reject_filters"
|
||||
version = "0.1.0"
|
||||
authors = ["JesusPerez <jpl@jesusperez.pro>"]
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_derive = "1.0.125"
|
||||
warp = { version = "0.3", features = ["default","websocket","tls","compression"] }
|
||||
app_env = { version = "0.1.0", path = "../../defs/app_env" }
|
5
reject_filters/README.md
Normal file
5
reject_filters/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# App reject filters library
|
||||
|
||||
Filters as configure routes and webservices for [warp](https://github.com/seanmonstar/warp)
|
||||
|
||||
As default fallback for **warp routes**
|
5
reject_filters/TODO.md
Normal file
5
reject_filters/TODO.md
Normal file
@ -0,0 +1,5 @@
|
||||
# App reject filters library
|
||||
|
||||
- [ ] Conditional **boxed** with cargo build for production
|
||||
|
||||
[Warp and compile times](https://rust-classes.com/chapter_6_3.html)
|
201
reject_filters/src/lib.rs
Normal file
201
reject_filters/src/lib.rs
Normal file
@ -0,0 +1,201 @@
|
||||
|
||||
|
||||
use serde_derive::{Serialize};
|
||||
//use std::convert::Infallible;
|
||||
use std::error::Error;
|
||||
|
||||
use warp::{
|
||||
http::{StatusCode},
|
||||
// http::{method::Method, HeaderMap, HeaderValue},
|
||||
// http::{HeaderMap, HeaderValue},
|
||||
// filters::header::headers_cloned,
|
||||
// filters::method::method,
|
||||
// filters::BoxedFilter,
|
||||
Filter,
|
||||
Rejection, Reply,
|
||||
};
|
||||
|
||||
use app_env::AppStore;
|
||||
|
||||
/// An API error serializable to JSON.
|
||||
#[derive(Serialize)]
|
||||
struct ErrorMessage {
|
||||
code: u16,
|
||||
message: String,
|
||||
}
|
||||
|
||||
/*
|
||||
#[must_use]
|
||||
#[allow(clippy::missing_errors_doc)]
|
||||
pub fn static_filter(
|
||||
static_path: &String
|
||||
) -> BoxedFilter<(impl warp::Reply,)> {
|
||||
warp::fs::dir(&static_path).with(warp::compression::gzip())
|
||||
.boxed()
|
||||
}
|
||||
*/
|
||||
/*
|
||||
#[allow(clippy::missing_errors_doc)]
|
||||
pub fn rejection(
|
||||
err: Rejection,
|
||||
db: AppStore,
|
||||
) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
|
||||
headers_cloned()
|
||||
.and(method())
|
||||
.and(handle_rejection)
|
||||
.and(with_db(db))
|
||||
.and_then(handle_rejection_filter)
|
||||
}
|
||||
*/
|
||||
// This function receives a `Rejection` and tries to return a custom
|
||||
// value, otherwise simply passes the rejection along.
|
||||
#[allow(clippy::missing_errors_doc)]
|
||||
pub async fn handle_rejection_filter(
|
||||
reply: impl warp::Reply,
|
||||
// full_path: warp::path::FullPath,
|
||||
// header: HeaderMap<HeaderValue>,
|
||||
db: AppStore,
|
||||
) -> Result<impl Reply, Rejection> {
|
||||
// dbg!(&db);
|
||||
// dbg!(&header);
|
||||
// dbg!(&full_path);
|
||||
let response = reply.into_response();
|
||||
let status_code = &response.status();
|
||||
//if let Some(message) = response.headers().get("x-message") {
|
||||
let message = match &response.headers().get("x-message") {
|
||||
Some(msg) => format!("{:?}",&msg),
|
||||
//warp::http::HeaderValue::from("NOT_FOUND") => println!("No encontrado"),
|
||||
None => String::from("Unknown"),
|
||||
};
|
||||
let result =format!("StatusCode: {} -> Message: {}", &status_code, &message);
|
||||
|
||||
let app = db.app_data.read();
|
||||
let fallback = |_: &str| {
|
||||
Ok(warp::http::Response::builder()
|
||||
.body(result.to_string())
|
||||
.into_response())
|
||||
// Ok(warp::reply::with_header(
|
||||
// warp::http::Response::new(result),
|
||||
// "Access-Control-Allow-Origin",
|
||||
// "http://localhost:3333"))
|
||||
};
|
||||
let tera = app.tera.to_owned();
|
||||
let mut context = app.ctx.to_owned();
|
||||
context.insert("status_code", &status_code.to_string());
|
||||
let template = match status_code.as_str() {
|
||||
"404" => "error404.html",
|
||||
_ => "error.html",
|
||||
};
|
||||
match tera.render(&template, &context) {
|
||||
Ok(page) =>
|
||||
Ok(warp::http::Response::builder()
|
||||
.body(page.to_string())
|
||||
.into_response()),
|
||||
// Ok(warp::reply::with_header(
|
||||
// warp::http::Response::new(page),
|
||||
// "Access-Control-Allow-Origin",
|
||||
// "http://localhost:3333")),
|
||||
Err(_) => fallback("Page not found"),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::missing_errors_doc)]
|
||||
pub async fn handle_rejection(
|
||||
err: Rejection,
|
||||
// header: HeaderMap<HeaderValue>,
|
||||
db: AppStore,
|
||||
// full_path: warp::path::FullPath,
|
||||
) -> Result<impl warp::Reply, Rejection> {
|
||||
// ) -> Result<impl Reply, Infallible> {
|
||||
// dbg!(&header);
|
||||
// dbg!(&err);
|
||||
// dbg!(&full_path);
|
||||
let code;
|
||||
let message;
|
||||
|
||||
|
||||
if err.is_not_found() {
|
||||
code = StatusCode::NOT_FOUND;
|
||||
message = "NOT_FOUND";
|
||||
} else if let Some(e) = err.find::<warp::filters::body::BodyDeserializeError>() {
|
||||
// This error happens if the body could not be deserialized correctly
|
||||
// We can use the cause to analyze the error and customize the error message
|
||||
message = match e.source() {
|
||||
Some(cause) => {
|
||||
if cause.to_string().contains("denom") {
|
||||
"FIELD_ERROR: denom"
|
||||
} else {
|
||||
"BAD_REQUEST"
|
||||
}
|
||||
}
|
||||
None => "BAD_REQUEST",
|
||||
};
|
||||
code = StatusCode::BAD_REQUEST;
|
||||
} else if let Some(_) = err.find::<warp::reject::MethodNotAllowed>() {
|
||||
// We can handle a specific error, here METHOD_NOT_ALLOWED,
|
||||
// and render it however we want
|
||||
code = StatusCode::METHOD_NOT_ALLOWED;
|
||||
message = "METHOD_NOT_ALLOWED";
|
||||
} else {
|
||||
// We should have expected this... Just log and say its a 500
|
||||
eprintln!("unhandled rejection: {:?}", err);
|
||||
code = StatusCode::INTERNAL_SERVER_ERROR;
|
||||
message = "UNHANDLED_REJECTION";
|
||||
}
|
||||
|
||||
// let json = warp::reply::json(&ErrorMessage {
|
||||
// code: code.as_u16(),
|
||||
// message: message.into(),
|
||||
// });
|
||||
|
||||
let result =format!("StatusCode: {} -> Message: {}", &code, &message);
|
||||
|
||||
let app = db.app_data.read();
|
||||
// let fallback = |e: &str| {
|
||||
// warp::reply::with_header(
|
||||
// warp::http::Response::new(result),
|
||||
// "Access-Control-Allow-Origin",
|
||||
// "http://localhost:3333")
|
||||
// };
|
||||
let tera = app.tera.to_owned();
|
||||
let mut context = app.ctx.to_owned();
|
||||
context.insert("status_code", &code.to_string());
|
||||
let template = match code.as_str() {
|
||||
"404" => "error404.html",
|
||||
_ => "error.html",
|
||||
};
|
||||
let reply = match tera.render(&template, &context) {
|
||||
Ok(page) =>
|
||||
warp::http::Response::builder()
|
||||
.status(code)
|
||||
.header("X-Message", message)
|
||||
.body(page)
|
||||
.into_response(),
|
||||
/*
|
||||
Ok(warp::reply::with_header(
|
||||
warp::http::Response::new(page),
|
||||
"Access-Control-Allow-Origin",
|
||||
"http://localhost:3333")),
|
||||
*/
|
||||
Err(_) =>
|
||||
warp::http::Response::builder()
|
||||
.status(code)
|
||||
.header("X-Message", message)
|
||||
.body(result)
|
||||
.into_response(),
|
||||
};
|
||||
Ok(warp::reply::with_status(reply,code))
|
||||
/*
|
||||
let res = warp::http::Response::builder()
|
||||
.status(code)
|
||||
.header("X-Message", message)
|
||||
.body(message.to_owned())
|
||||
.into_response();
|
||||
Ok(warp::reply::with_status(res, code))
|
||||
*/
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_app_db(db: AppStore) -> impl Filter<Extract = (AppStore,), Error = std::convert::Infallible> + Clone {
|
||||
warp::any().map(move || db.clone())
|
||||
}
|
Loading…
Reference in New Issue
Block a user