use std::collections::HashMap;
use std::time::Duration;
use tokio::time::sleep;
use log::info;
use warp::{Filter, Rejection, Reply};
use warp::http::{Response, StatusCode};
use warp::hyper::Body;
use crate::models::{Endpoint, InvalidGraphQLRequest, MethodNotAllowed, NotFound, RateLimited, Unauthorized};
use crate::middlewares::rate_limit::RateLimitTracker;
pub async fn add_possible_delay(endpoint: &Endpoint) {
if let Some(delay) = endpoint.delay {
info!("⏳ Applying delay of {} ms", delay);
sleep(Duration::from_millis(delay)).await;
}
}
pub fn with_rate_limiter(rate_limiter: RateLimitTracker) ->
impl Filter<Extract = (RateLimitTracker,), Error = std::convert::Infallible> + Clone {
warp::any().map(move || rate_limiter.clone())
}
pub fn reconstruct_full_url(path: &str, query_params: &Option<HashMap<String, String>>) -> String {
if let Some(params) = query_params {
if !params.is_empty() {
let query_string = serde_urlencoded::to_string(params).unwrap_or_default();
return format!("{}?{}", path, query_string);
}
}
path.to_string()
}
pub async fn handle_rejection(err: Rejection) -> Result<impl Reply, Rejection> {
if err.find::<Unauthorized>().is_some() {
let response: Response<Body> = Response::builder()
.status(StatusCode::UNAUTHORIZED)
.body(Body::from("Unauthorized\n"))
.unwrap();
return Ok(response);
} else if err.find::<RateLimited>().is_some() {
let response: Response<Body> = Response::builder()
.status(StatusCode::TOO_MANY_REQUESTS)
.body(Body::from("Rate limit exceeded\n"))
.unwrap();
return Ok(response);
} else if err.find::<NotFound>().is_some() {
let response: Response<Body> = Response::builder()
.status(StatusCode::NOT_FOUND)
.body(Body::from("Resource not found\n"))
.unwrap();
return Ok(response);
} else if err.find::<MethodNotAllowed>().is_some() {
let response: Response<Body> = Response::builder()
.status(StatusCode::METHOD_NOT_ALLOWED)
.body(Body::from("Method not allowed\n"))
.unwrap();
return Ok(response);
} else if err.find::<InvalidGraphQLRequest>().is_some() {
let response: Response<Body> = Response::builder()
.status(StatusCode::NOT_FOUND)
.body(Body::from("Invalid gRPC request\n"))
.unwrap();
return Ok(response);
}
Err(err)
}