Last active
October 12, 2021 20:16
-
-
Save OliverBrotchie/c41689394d8b1894a804255c14d7ef8d to your computer and use it in GitHub Desktop.
Async connection handler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use actix_web::http::header::HeaderMap; | |
use chrono::{DateTime, Utc}; | |
use std::collections::HashMap; | |
use std::sync::Mutex; | |
#[derive(Debug, Clone)] | |
pub struct Fingerprint { | |
properties: Vec<(String, String)>, | |
fonts: Vec<String>, | |
headers: HeaderMap, | |
timestamp: DateTime<Utc>, | |
} | |
#[derive(Clone)] | |
pub struct ConnectionHandler<T: FnMut(String, &Fingerprint)> { | |
data: HashMap<String, Fingerprint>, | |
return_fn: T, | |
} | |
impl<T> ConnectionHandler<T> | |
where | |
T: FnMut(String, &Fingerprint), | |
{ | |
pub fn insert(&mut self, ip: String, key: String, value: String, headers: Option<&HeaderMap>) { | |
match self.data.get_mut(&ip) { | |
Some(f) => { | |
if key == "font-name" { | |
f.fonts.push(value) | |
} else { | |
f.properties.push((key, value)) | |
} | |
} | |
None => { | |
self.data.insert( | |
ip.clone(), | |
Fingerprint { | |
properties: Vec::new(), | |
fonts: Vec::new(), | |
headers: headers.unwrap().clone(), | |
timestamp: chrono::offset::Utc::now(), | |
}, | |
); | |
self.insert(ip, key, value, None); | |
// Wait x seconds before calling this! | |
(self.return_fn)(ip, self.data.get(&ip).unwrap()); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use actix_web::{get, web, App, HttpRequest, HttpResponse, HttpServer, Responder}; | |
use std::collections::HashMap; | |
use std::sync::Mutex; | |
mod handler; | |
#[get("/some/url/{key}={value}")] | |
async fn new_prop<T: FnMut(String, &handler::Fingerprint)>( | |
con_handler: web::Data<handler::ConnectionHandler<T>>, | |
request: HttpRequest, | |
web::Path((key, value)): web::Path<(String, String)>, | |
) -> impl Responder { | |
// Just an example (will not work due to threading issues) | |
con_handler.insert( | |
request | |
.connection_info() | |
.realip_remote_addr() | |
.unwrap() | |
.to_owned(), | |
key, | |
value, | |
Some(request.headers()), | |
); | |
HttpResponse::Gone() | |
} | |
#[actix_web::main] | |
async fn main() -> std::io::Result<()> { | |
const PORT: u16 = 8000; | |
println!("🚀 Server running on port: {}!", PORT); | |
// Define the connection handler | |
let h = web::Data::new(handler::ConnectionHandler { | |
data: HashMap::new(), | |
return_fn: |ip: String, fingerprint: &handler::Fingerprint| { | |
println!("IP: {}, Fingerprint: {:#?}", ip, fingerprint) | |
}, | |
}); | |
HttpServer::new(|| { | |
App::new() | |
.app_data(h.clone()) | |
.service(new_prop) | |
}) | |
.bind(format!("127.0.0.1:{}", PORT))? | |
.run() | |
.await | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment