From 382027647b8a74055007211cd583485816f7bef3 Mon Sep 17 00:00:00 2001 From: Avril Date: Wed, 8 Sep 2021 16:58:28 +0100 Subject: [PATCH] NOTHING EVER WFUCKIGN WORKS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fortune for datse's current commit: Small blessing − 小吉 --- src/server/web/ban.rs | 25 +++++++++++------------ src/server/web/mod.rs | 44 ++++++++++++++++++++++++++++++----------- src/server/web/state.rs | 39 ++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 26 deletions(-) create mode 100644 src/server/web/state.rs diff --git a/src/server/web/ban.rs b/src/server/web/ban.rs index 1435910..7cc3c38 100644 --- a/src/server/web/ban.rs +++ b/src/server/web/ban.rs @@ -85,25 +85,22 @@ impl Banlist /// /// # Lifetime /// The filter holds a weak reference to this list. If the list is dropped, then the filter will panic. - //TODO: How do we make this just return `impl Filter`? We need it to take the client_info as param... - pub fn filter(&self) -> impl Fn(ClientInfo) -> futures::future::BoxFuture<'static, Result> + Clone + 'static + pub fn filter(&self, client_info: ClientInfo) -> impl Future> + 'static { let refer = Arc::downgrade(&self.0); - move |client_info: ClientInfo| { + async move { let refer = refer.upgrade().unwrap(); - async move { - let bans = refer.read().await; - //XXX: FUCK there has to be a better way to check this right? - for fuck in bans.iter() - { - if fuck == &client_info { - return Err(warp::reject::custom(ClientBannedError)); - } + + let bans = refer.read().await; + //XXX: FUCK there has to be a better way to check this right? + for fuck in bans.iter() + { + if fuck == &client_info { + return Err(warp::reject::custom(ClientBannedError)); } - Ok(client_info) } - //XXX: This doesn't seem good - }.boxed() + Ok(client_info) + } } } diff --git a/src/server/web/mod.rs b/src/server/web/mod.rs index d49d9e8..6f88dc6 100644 --- a/src/server/web/mod.rs +++ b/src/server/web/mod.rs @@ -27,19 +27,41 @@ mod ban; mod source; mod forwarded_list; -fn routing<'a>() -> impl warp::Filter + Clone + 'a +mod state; +use state::State; + +async fn auth(state: State) -> Result +{ + Ok("".to_owned()) +} + +async fn push(state: State) -> Result<&'static str, warp::Rejection> +{ + Ok("") +} + +async fn get(state: State) -> Result { + Ok(warp::reply()) +} + +fn routing<'a>(state: State) -> impl warp::Filter + Clone + 'a +{ + let state = warp::any().map(move || state.clone()); + let auth = warp::path("auth").and({ //let req = warp::path("req") - warp::post() + warp::post().and(state.clone()).and_then(|state: State| auth(state)) }); let push = warp::path("push").and({ - warp::post() + warp::post().and(state.clone()).and_then(|state: State| self::push(state)) + }); let get = warp::path("get").and({ - warp::get() + warp::post().and(state.clone()).and_then(|state: State| self::get(state)) + }); auth.or(push).or(get) @@ -47,26 +69,24 @@ fn routing<'a>() -> impl warp::Filter + Clone + pub async fn serve(cfg: Config) -> eyre::Result<()> { - let bans: ban::Banlist = cfg.static_bans.iter().collect(); - - //TODO: Create state + //Create state + let state = State::new(cfg); // Filter: Extract the client IP from the remote address of the connection of the X-Forwarded-For header if it is trusted in `cfg`. let client_ip = warp::addr::remote() .and(warp::header("X-Forwarded-For")) - .map(source::extract(cfg.trust_x_forwarded_for)) + .map(source::extract(state.cfg().trust_x_forwarded_for)) // Extract the IP .and_then(|req: Result| async move { req.map_err(warp::reject::custom) }) // Enforce banlist - .and_then(bans.filter()); + .and_then({ let state = state.clone(); move |c| { state.clone().banlist().filter(c) } }); //.and_then(|req: source::ClientInfo| async move { Result::<_, std::convert::Infallible>::Ok(req) }); let filter = warp::path("api") - //how the FUCK do we insert shit into this???????????????????????? - .and(routing()); + .and(routing(state.clone())); - warp::serve(client_ip).bind_with_graceful_shutdown(([127,0,0,1], 8001), tokio::signal::ctrl_c()).await; + warp::serve(filter).bind_with_graceful_shutdown(([127,0,0,1], 8001), tokio::signal::ctrl_c()).await; Ok(()) } diff --git a/src/server/web/state.rs b/src/server/web/state.rs new file mode 100644 index 0000000..e20ff93 --- /dev/null +++ b/src/server/web/state.rs @@ -0,0 +1,39 @@ +//! Program state management +use super::*; + + +/// Inner (immutable) state. +#[derive(Debug)] +struct StateInner +{ + cfg: Config, + banlist: ban::Banlist, +} + +/// Whole program state +#[derive(Debug, Clone)] +pub struct State(Arc); + +impl State +{ + pub fn new(cfg: Config) -> Self + { + let banlist: ban::Banlist = cfg.static_bans.iter().collect(); + Self(Arc::new(StateInner { + banlist, + cfg, + })) + } + + /// The static config the program was started on. + #[inline] pub fn cfg(&self) -> &Config + { + &self.0.cfg + } + + #[inline] pub fn banlist(&self) -> &ban::Banlist + { + &self.0.banlist + } +} +