use rustc_hash::FxHashMap;
#[derive(Debug, Clone)]
pub enum RouteAction {
Continue(ContinueOverrides),
Fulfill(FulfillResponse),
Abort(String),
}
#[derive(Debug, Clone, Default)]
pub struct ContinueOverrides {
pub url: Option<String>,
pub method: Option<String>,
pub headers: Option<Vec<(String, String)>>,
pub post_data: Option<Vec<u8>>,
}
#[derive(Debug, Clone)]
pub struct FulfillResponse {
pub status: i32,
pub headers: Vec<(String, String)>,
pub body: Vec<u8>,
pub content_type: Option<String>,
}
impl Default for FulfillResponse {
fn default() -> Self {
Self {
status: 200,
headers: vec![],
body: vec![],
content_type: None,
}
}
}
#[derive(Debug, Clone)]
pub struct InterceptedRequest {
pub request_id: String,
pub url: String,
pub method: String,
pub headers: FxHashMap<String, String>,
pub post_data: Option<String>,
pub resource_type: String,
}
pub struct Route {
request: InterceptedRequest,
action_tx: Option<tokio::sync::oneshot::Sender<RouteAction>>,
}
impl Route {
#[must_use]
pub fn new(request: InterceptedRequest, action_tx: tokio::sync::oneshot::Sender<RouteAction>) -> Self {
Self {
request,
action_tx: Some(action_tx),
}
}
#[must_use]
pub fn request(&self) -> &InterceptedRequest {
&self.request
}
pub fn fulfill(mut self, response: FulfillResponse) {
if let Some(tx) = self.action_tx.take() {
let _ = tx.send(RouteAction::Fulfill(response));
}
}
pub fn continue_route(mut self, overrides: ContinueOverrides) {
if let Some(tx) = self.action_tx.take() {
let _ = tx.send(RouteAction::Continue(overrides));
}
}
pub fn abort(mut self, reason: &str) {
if let Some(tx) = self.action_tx.take() {
let _ = tx.send(RouteAction::Abort(reason.to_string()));
}
}
}
impl Drop for Route {
fn drop(&mut self) {
if let Some(tx) = self.action_tx.take() {
let _ = tx.send(RouteAction::Continue(ContinueOverrides::default()));
}
}
}
pub type RouteHandler = std::sync::Arc<dyn Fn(Route) + Send + Sync>;
pub struct RegisteredRoute {
pub matcher: crate::url_matcher::UrlMatcher,
pub handler: RouteHandler,
}
#[must_use]
pub fn status_text(code: i32) -> &'static str {
match code {
201 => "Created",
204 => "No Content",
301 => "Moved Permanently",
302 => "Found",
304 => "Not Modified",
400 => "Bad Request",
401 => "Unauthorized",
403 => "Forbidden",
404 => "Not Found",
405 => "Method Not Allowed",
500 => "Internal Server Error",
502 => "Bad Gateway",
503 => "Service Unavailable",
_ => "OK",
}
}