♻️ 使用 Actix RS 重构 #8
@ -4,6 +4,7 @@ mod sideload;
|
||||
pub mod warden;
|
||||
|
||||
use actix_web::{App, HttpServer, web};
|
||||
use actix_web::middleware::Logger;
|
||||
use actix_web_httpauth::extractors::AuthenticationError;
|
||||
use actix_web_httpauth::headers::www_authenticate::basic::Basic;
|
||||
use actix_web_httpauth::middleware::HttpAuthentication;
|
||||
@ -44,6 +45,7 @@ async fn main() -> Result<(), std::io::Error> {
|
||||
// Proxies
|
||||
let proxies_server = HttpServer::new(|| {
|
||||
App::new()
|
||||
.wrap(Logger::default())
|
||||
.app_data(web::Data::new(Client::default()))
|
||||
.route("/", web::to(route::handle))
|
||||
}).bind(
|
||||
|
@ -9,12 +9,22 @@ pub struct RoadTrace {
|
||||
pub region: String,
|
||||
pub location: String,
|
||||
pub destination: String,
|
||||
pub ip_address: String,
|
||||
pub user_agent: String,
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
impl RoadTrace {
|
||||
pub fn from_structs(reg: Region, loc: Location, end: Destination) -> RoadTrace {
|
||||
pub fn from_structs(
|
||||
ip: String,
|
||||
ua: String,
|
||||
reg: Region,
|
||||
loc: Location,
|
||||
end: Destination,
|
||||
) -> RoadTrace {
|
||||
RoadTrace {
|
||||
ip_address: ip,
|
||||
user_agent: ua,
|
||||
region: reg.id,
|
||||
location: loc.id,
|
||||
destination: end.id,
|
||||
@ -23,17 +33,16 @@ impl RoadTrace {
|
||||
}
|
||||
|
||||
pub fn from_structs_with_error(
|
||||
ip: String,
|
||||
ua: String,
|
||||
reg: Region,
|
||||
loc: Location,
|
||||
end: Destination,
|
||||
err: String,
|
||||
) -> RoadTrace {
|
||||
RoadTrace {
|
||||
region: reg.id,
|
||||
location: loc.id,
|
||||
destination: end.id,
|
||||
error: Some(err),
|
||||
}
|
||||
let mut trace = Self::from_structs(ip, ua, reg, loc, end);
|
||||
trace.error = Some(err);
|
||||
return trace;
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,7 +55,7 @@ pub struct RoadMetrics {
|
||||
pub recent_errors: VecDeque<RoadTrace>,
|
||||
}
|
||||
|
||||
const MAX_TRACE_COUNT: usize = 10;
|
||||
const MAX_TRACE_COUNT: usize = 32;
|
||||
|
||||
impl RoadMetrics {
|
||||
pub fn new() -> RoadMetrics {
|
||||
@ -66,26 +75,35 @@ impl RoadMetrics {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_success_request(&mut self, reg: Region, loc: Location, end: Destination) {
|
||||
pub fn add_success_request(
|
||||
&mut self,
|
||||
ip: String,
|
||||
ua: String,
|
||||
reg: Region,
|
||||
loc: Location,
|
||||
end: Destination,
|
||||
) {
|
||||
self.requests_count += 1;
|
||||
self.recent_successes
|
||||
.push_back(RoadTrace::from_structs(reg, loc, end));
|
||||
.push_back(RoadTrace::from_structs(ip, ua, reg, loc, end));
|
||||
if self.recent_successes.len() > MAX_TRACE_COUNT {
|
||||
self.recent_successes.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_faliure_request(
|
||||
pub fn add_failure_request(
|
||||
&mut self,
|
||||
ip: String,
|
||||
ua: String,
|
||||
reg: Region,
|
||||
loc: Location,
|
||||
end: Destination,
|
||||
err: String, // For some reason error is rarely clonable, so we use preformatted message
|
||||
err: String, // For some reason error is rarely cloneable, so we use preformatted message
|
||||
) {
|
||||
self.requests_count += 1;
|
||||
self.failures_count += 1;
|
||||
self.recent_errors
|
||||
.push_back(RoadTrace::from_structs_with_error(reg, loc, end, err));
|
||||
.push_back(RoadTrace::from_structs_with_error(ip, ua, reg, loc, end, err));
|
||||
if self.recent_errors.len() > MAX_TRACE_COUNT {
|
||||
self.recent_errors.pop_front();
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use actix_web::{HttpRequest, HttpResponse, web};
|
||||
use actix_web::http::header;
|
||||
use awc::Client;
|
||||
use rand::seq::SliceRandom;
|
||||
|
||||
@ -59,11 +60,20 @@ pub async fn handle(req: HttpRequest, client: web::Data<Client>) -> HttpResponse
|
||||
let loc = location.clone();
|
||||
let end = destination.clone();
|
||||
|
||||
return match forward(&end, req, client).await {
|
||||
let ip = match req.peer_addr() {
|
||||
None => "unknown".to_string(),
|
||||
Some(val) => val.ip().to_string()
|
||||
};
|
||||
let ua = match req.headers().get(header::USER_AGENT) {
|
||||
None => "unknown".to_string(),
|
||||
Some(val) => val.to_str().unwrap().to_string(),
|
||||
};
|
||||
|
||||
match forward(&end, req, client).await {
|
||||
Ok(resp) => {
|
||||
tokio::spawn(async move {
|
||||
let writable_app = &mut ROAD.lock().await;
|
||||
writable_app.metrics.add_success_request(reg, loc, end);
|
||||
writable_app.metrics.add_success_request(ip, ua, reg, loc, end);
|
||||
});
|
||||
resp
|
||||
}
|
||||
@ -72,7 +82,7 @@ pub async fn handle(req: HttpRequest, client: web::Data<Client>) -> HttpResponse
|
||||
let writable_app = &mut ROAD.lock().await;
|
||||
writable_app
|
||||
.metrics
|
||||
.add_faliure_request(reg, loc, end, "TODO".to_owned());
|
||||
.add_failure_request(ip, ua, reg, loc, end, "TODO".to_owned());
|
||||
});
|
||||
resp
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user