✨ More detailed error
This commit is contained in:
parent
2478a05c89
commit
e27023c130
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1277,6 +1277,7 @@ dependencies = [
|
||||
"actix-web-httpauth",
|
||||
"awc",
|
||||
"config",
|
||||
"derive_more",
|
||||
"lazy_static",
|
||||
"mime",
|
||||
"percent-encoding",
|
||||
|
@ -31,3 +31,4 @@ toml = "0.8.8"
|
||||
tracing = "0.1.40"
|
||||
tracing-subscriber = "0.3.18"
|
||||
wildmatch = "2.3.0"
|
||||
derive_more = "0.99.17"
|
||||
|
@ -1,7 +1,9 @@
|
||||
use actix_web::http::header::HeaderMap;
|
||||
use actix_web::http::{Method, Uri};
|
||||
use actix_web::http::header::{ContentType, HeaderMap};
|
||||
use actix_web::http::{Method, StatusCode, Uri};
|
||||
use regex::Regex;
|
||||
use wildmatch::WildMatch;
|
||||
use actix_web::{error, HttpResponse};
|
||||
use derive_more::{Display};
|
||||
|
||||
use crate::warden::WardenInstance;
|
||||
|
||||
@ -16,6 +18,46 @@ pub mod metrics;
|
||||
pub mod responder;
|
||||
pub mod route;
|
||||
|
||||
#[derive(Debug, Display)]
|
||||
pub enum ProxyError {
|
||||
#[display(fmt = "Remote gateway issue")]
|
||||
BadGateway,
|
||||
|
||||
#[display(fmt = "No configured able to process this request")]
|
||||
NoGateway,
|
||||
|
||||
#[display(fmt = "Not found")]
|
||||
NotFound,
|
||||
|
||||
#[display(fmt = "Only accepts method GET")]
|
||||
MethodGetOnly,
|
||||
|
||||
#[display(fmt = "Invalid request path")]
|
||||
InvalidRequestPath,
|
||||
|
||||
#[display(fmt = "Upstream does not support protocol you used")]
|
||||
NotImplemented,
|
||||
}
|
||||
|
||||
impl error::ResponseError for ProxyError {
|
||||
fn status_code(&self) -> StatusCode {
|
||||
match *self {
|
||||
ProxyError::BadGateway => StatusCode::BAD_GATEWAY,
|
||||
ProxyError::NoGateway => StatusCode::NOT_FOUND,
|
||||
ProxyError::NotFound => StatusCode::NOT_FOUND,
|
||||
ProxyError::MethodGetOnly => StatusCode::METHOD_NOT_ALLOWED,
|
||||
ProxyError::InvalidRequestPath => StatusCode::BAD_REQUEST,
|
||||
ProxyError::NotImplemented => StatusCode::NOT_IMPLEMENTED,
|
||||
}
|
||||
}
|
||||
|
||||
fn error_response(&self) -> HttpResponse {
|
||||
HttpResponse::build(self.status_code())
|
||||
.insert_header(ContentType::html())
|
||||
.body(self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RoadInstance {
|
||||
pub regions: Vec<Region>,
|
||||
|
@ -7,12 +7,14 @@ use actix_proxy::IntoHttpResponse;
|
||||
use actix_web::{HttpRequest, HttpResponse, web};
|
||||
use actix_web::http::Method;
|
||||
use awc::Client;
|
||||
use tracing::log::warn;
|
||||
use crate::proxies::ProxyError;
|
||||
|
||||
pub async fn respond_hypertext(
|
||||
uri: String,
|
||||
req: HttpRequest,
|
||||
client: web::Data<Client>,
|
||||
) -> Result<HttpResponse, HttpResponse> {
|
||||
) -> Result<HttpResponse, ProxyError> {
|
||||
let ip = req.peer_addr().unwrap().ip().to_string();
|
||||
let proto = req.uri().scheme_str().unwrap();
|
||||
let host = req.uri().host().unwrap();
|
||||
@ -40,8 +42,8 @@ pub async fn respond_hypertext(
|
||||
}
|
||||
|
||||
Err(error) => {
|
||||
Err(HttpResponse::BadGateway()
|
||||
.body(format!("Something went wrong... {:}", error)))
|
||||
warn!("Proxy got a upstream issue... {:?}", error);
|
||||
Err(ProxyError::BadGateway)
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -59,10 +61,9 @@ pub struct StaticResponderConfig {
|
||||
pub async fn respond_static(
|
||||
cfg: StaticResponderConfig,
|
||||
req: HttpRequest,
|
||||
) -> Result<HttpResponse, HttpResponse> {
|
||||
) -> Result<HttpResponse, ProxyError> {
|
||||
if req.method() != Method::GET {
|
||||
return Err(HttpResponse::MethodNotAllowed()
|
||||
.body("This destination only support GET request."));
|
||||
return Err(ProxyError::MethodGetOnly);
|
||||
}
|
||||
|
||||
let path = req
|
||||
@ -74,7 +75,7 @@ pub async fn respond_static(
|
||||
let path = match percent_encoding::percent_decode_str(path).decode_utf8() {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
return Err(HttpResponse::NotFound().body("Not found."));
|
||||
return Err(ProxyError::NotFound);
|
||||
}
|
||||
};
|
||||
|
||||
@ -91,8 +92,7 @@ pub async fn respond_static(
|
||||
}
|
||||
|
||||
if !file_path.starts_with(cfg.uri) {
|
||||
return Err(HttpResponse::Forbidden()
|
||||
.body("Unexpected path."));
|
||||
return Err(ProxyError::InvalidRequestPath);
|
||||
}
|
||||
|
||||
if !file_path.exists() {
|
||||
@ -116,7 +116,7 @@ pub async fn respond_static(
|
||||
}
|
||||
}
|
||||
|
||||
return Err(HttpResponse::NotFound().body("Not found."));
|
||||
return Err(ProxyError::NotFound);
|
||||
}
|
||||
|
||||
return if file_path.is_file() {
|
||||
@ -129,6 +129,6 @@ pub async fn respond_static(
|
||||
}
|
||||
}
|
||||
|
||||
Err(HttpResponse::NotFound().body("Not found."))
|
||||
return Err(ProxyError::NotFound);
|
||||
};
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use actix_web::{HttpRequest, HttpResponse, web};
|
||||
use actix_web::{HttpRequest, HttpResponse, ResponseError, web};
|
||||
use actix_web::http::header;
|
||||
use awc::Client;
|
||||
use rand::seq::SliceRandom;
|
||||
@ -10,14 +10,14 @@ use crate::{
|
||||
},
|
||||
ROAD,
|
||||
};
|
||||
use crate::proxies::ProxyError;
|
||||
|
||||
pub async fn handle(req: HttpRequest, client: web::Data<Client>) -> HttpResponse {
|
||||
let readable_app = ROAD.lock().await;
|
||||
let (region, location) = match readable_app.filter(req.uri(), req.method(), req.headers()) {
|
||||
Some(val) => val,
|
||||
None => {
|
||||
return HttpResponse::NotFound()
|
||||
.body("There are no region be able to respone this request.");
|
||||
return ProxyError::NoGateway.error_response();
|
||||
}
|
||||
};
|
||||
|
||||
@ -30,29 +30,24 @@ pub async fn handle(req: HttpRequest, client: web::Data<Client>) -> HttpResponse
|
||||
end: &Destination,
|
||||
req: HttpRequest,
|
||||
client: web::Data<Client>,
|
||||
) -> Result<HttpResponse, HttpResponse> {
|
||||
) -> Result<HttpResponse, ProxyError> {
|
||||
// Handle normal web request
|
||||
match end.get_type() {
|
||||
DestinationType::Hypertext => {
|
||||
let Ok(uri) = end.get_hypertext_uri() else {
|
||||
return Err(HttpResponse::NotImplemented()
|
||||
.body("This destination was not support web requests."));
|
||||
return Err(ProxyError::NotImplemented);
|
||||
};
|
||||
|
||||
responder::respond_hypertext(uri, req, client).await
|
||||
}
|
||||
DestinationType::StaticFiles => {
|
||||
let Ok(cfg) = end.get_static_config() else {
|
||||
return Err(HttpResponse::NotImplemented()
|
||||
.body("This destination was not support static files."));
|
||||
return Err(ProxyError::NotImplemented);
|
||||
};
|
||||
|
||||
responder::respond_static(cfg, req).await
|
||||
}
|
||||
_ => {
|
||||
return Err(HttpResponse::NotImplemented()
|
||||
.body("Unsupported destination protocol."));
|
||||
}
|
||||
_ => Err(ProxyError::NotImplemented)
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,13 +73,14 @@ pub async fn handle(req: HttpRequest, client: web::Data<Client>) -> HttpResponse
|
||||
resp
|
||||
}
|
||||
Err(resp) => {
|
||||
let message = resp.to_string();
|
||||
tokio::spawn(async move {
|
||||
let writable_app = &mut ROAD.lock().await;
|
||||
writable_app
|
||||
.metrics
|
||||
.add_failure_request(ip, ua, reg, loc, end, "TODO".to_owned());
|
||||
.add_failure_request(ip, ua, reg, loc, end, message);
|
||||
});
|
||||
resp
|
||||
resp.error_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user