2020-10-30 02:03:26 +00:00
|
|
|
//! This example shows how to use `actix_web::HttpServer::on_connect` to access a lower-level socket
|
|
|
|
//! properties and pass them to a handler through request-local data.
|
|
|
|
//!
|
|
|
|
//! For an example of extracting a client TLS certificate, see:
|
2021-02-28 21:41:07 +00:00
|
|
|
//! <https://github.com/actix/examples/tree/HEAD/security/rustls-client-cert>
|
2020-10-30 02:03:26 +00:00
|
|
|
|
2021-01-07 02:41:05 +00:00
|
|
|
use std::{any::Any, io, net::SocketAddr};
|
2020-10-30 02:03:26 +00:00
|
|
|
|
2021-07-13 23:20:45 +00:00
|
|
|
use actix_http::CloneableExtensions;
|
2021-07-13 23:21:05 +00:00
|
|
|
use actix_web::{rt::net::TcpStream, web, App, HttpServer};
|
2020-10-30 02:03:26 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
struct ConnectionInfo {
|
|
|
|
bind: SocketAddr,
|
|
|
|
peer: SocketAddr,
|
|
|
|
ttl: Option<u32>,
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn route_whoami(conn_info: web::ReqData<ConnectionInfo>) -> String {
|
|
|
|
format!(
|
|
|
|
"Here is some info about your connection:\n\n{:#?}",
|
|
|
|
conn_info
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-07-13 23:20:45 +00:00
|
|
|
fn get_conn_info(connection: &dyn Any, data: &mut CloneableExtensions) {
|
2020-10-30 02:03:26 +00:00
|
|
|
if let Some(sock) = connection.downcast_ref::<TcpStream>() {
|
|
|
|
data.insert(ConnectionInfo {
|
|
|
|
bind: sock.local_addr().unwrap(),
|
|
|
|
peer: sock.peer_addr().unwrap(),
|
|
|
|
ttl: sock.ttl().ok(),
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
unreachable!("connection should only be plaintext since no TLS is set up");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[actix_web::main]
|
|
|
|
async fn main() -> io::Result<()> {
|
2021-01-07 02:41:05 +00:00
|
|
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
2020-10-30 02:03:26 +00:00
|
|
|
|
|
|
|
HttpServer::new(|| App::new().default_service(web::to(route_whoami)))
|
|
|
|
.on_connect(get_conn_info)
|
|
|
|
.bind(("127.0.0.1", 8080))?
|
|
|
|
.workers(1)
|
|
|
|
.run()
|
|
|
|
.await
|
|
|
|
}
|