Compile crashes

Fortune for datse's current commit: Half blessing − 半吉
simple
Avril 3 years ago
parent d8a5727d0c
commit e69bb356fb
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -1,5 +1,6 @@
#![cfg_attr(nightly, feature(never_type))]
#![feature(entry_insert)]
#![feature(type_alias_impl_trait)]
#![allow(dead_code)]
#![allow(unused_imports)]

@ -0,0 +1,128 @@
//! Banning
use std::sync::{
Arc,
Weak,
};
use std::{fmt, error};
use std::collections::BTreeSet;
use std::cmp::{PartialOrd, Ordering};
use tokio::sync::RwLock;
use std::net::IpAddr;
use std::iter::FromIterator;
use super::*;
use source::ClientInfo;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum BanKind
{
IP(IpAddr),
}
impl PartialEq<ClientInfo> for BanKind
{
fn eq(&self, other: &ClientInfo) -> bool
{
match self {
Self::IP(addr) => addr == &other.ip_addr,
}
}
}
impl PartialOrd<ClientInfo> for BanKind
{
#[inline] fn partial_cmp(&self, other: &ClientInfo) -> Option<Ordering> {
match self {
Self::IP(addr) => addr.partial_cmp(&other.ip_addr),
}
}
}
impl ClientInfo
{
/// Ban this client IP
#[inline] pub fn ban_ip(&self) -> BanKind
{
BanKind::IP(self.ip_addr.clone())
}
}
#[derive(Debug, Clone)]
pub struct Banlist(Arc<RwLock<BTreeSet<BanKind>>>);
type OpaqueFuture<'a, T> = impl Future<Output = T> + 'a;
impl Banlist
{
/// Create a new, empty banlist.
///
/// To create one from a list of bans, this type implements `FromIterator`.
pub fn new() -> Self
{
Self(Arc::new(RwLock::new(BTreeSet::new())))
}
/// Add a ban to the list and wait for it to complete.
pub async fn add_ban_inline(&self, ban: BanKind) -> bool
{
self.0.write().await.insert(ban)
}
/// Add a ban to the list.
///
/// If the list is being used, this operation is deferred until it is able to complete. A future is returned to allow you to wait until the operation completes (it is a background task.)
pub fn add_ban(&self, ban: BanKind) -> impl Future<Output = bool>
{
let col = self.0.clone();
tokio::spawn(async move {
col.write().await.insert(ban)
}).map(|x| x.unwrap())
}
/// Create a warp filter that disallows hosts on the list.
///
/// # Lifetime
/// The filter holds a weak reference to this list. If the list is dropped, then the filter will panic.
pub fn filter(&self) -> impl Fn(ClientInfo) -> OpaqueFuture<'static, Result<ClientInfo, warp::reject::Rejection>> + Clone + 'static
{
let refer = Arc::downgrade(&self.0);
move |client_info: ClientInfo| {
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));
}
}
Ok(client_info)
}
}
}
}
impl FromIterator<BanKind> for Banlist
{
fn from_iter<I: IntoIterator<Item=BanKind>>(iter: I) -> Self
{
Self(Arc::new(RwLock::new(iter.into_iter().collect())))
}
}
/// Error returned from filter when the client is banned.
#[derive(Debug)]
pub struct ClientBannedError;
impl warp::reject::Reject for ClientBannedError{}
impl error::Error for ClientBannedError{}
impl fmt::Display for ClientBannedError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "you are banned")
}
}

@ -23,18 +23,44 @@ use cryptohelpers::{
use uuid::Uuid;
mod ban;
mod source;
mod forwarded_list;
pub async fn serve(cfg: Config) -> eyre::Result<()>
fn routing<'a>() -> impl warp::Filter<Error = warp::reject::Rejection> + Clone + 'a
{
let auth = warp::path("auth").and({
//let req = warp::path("req")
warp::post()
});
let push = warp::path("push").and({
warp::post()
});
let get = warp::path("get").and({
warp::get()
});
auth.or(push).or(get)
}
pub async fn serve(cfg: impl Into<Config>) -> eyre::Result<()>
{
let cfg = cfg.into();
let bans = ban::Banlist::new();
// 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))
.and_then(|req: Result<std::net::IpAddr, _>| async move { req.map_err(warp::reject::custom) });
// Extract the IP
.and_then(|req: Result<source::ClientInfo, _>| async move { req.map_err(warp::reject::custom) })
// Enforce banlist
.and_then(bans.filter());
//.and_then(|req: source::ClientInfo| async move { Result::<_, std::convert::Infallible>::Ok(req) });
let r = warp::path("api").and(routing());
Ok(())
}

@ -49,13 +49,24 @@ impl fmt::Display for NoIpError
///
/// # Returns
/// A filter to perform the extraction
#[inline] pub fn extract(trust_x: bool) -> impl Fn(Option<SocketAddr>, XForwardedFor) -> Result<IpAddr,NoIpError> + Clone
#[inline] pub fn extract(trust_x: bool) -> impl Fn(Option<SocketAddr>, XForwardedFor) -> Result<ClientInfo,NoIpError> + Clone
{
move |opt, x| {
if trust_x {
x.into_first().ok_or(NoIpError)
} else {
opt.map(|x| x.ip()).ok_or(NoIpError)
}
}.map(|ip_addr|
// Create ClientInfo
ClientInfo {
ip_addr
})
}
}
/// Information about the client
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ClientInfo
{
pub ip_addr: IpAddr
}

Loading…
Cancel
Save