Add support for HAProxy proxy protocol for listeners

This commit is contained in:
Lambda 2024-09-15 15:55:47 +00:00
parent 99f3e2aecd
commit 3247c64cd8
7 changed files with 234 additions and 14 deletions

View file

@ -57,6 +57,7 @@ use crate::{
utils::{
self,
error::{Error, Result},
proxy_protocol::{ProxyAcceptor, ProxyAcceptorConfig},
},
ApplicationState, Services,
};
@ -138,6 +139,7 @@ struct ServerSpawner<'cfg, M> {
middlewares: M,
tls_config: Option<RustlsConfig>,
proxy_config: ProxyAcceptorConfig,
servers: JoinSet<(ListenConfig, std::io::Result<()>)>,
handles: Vec<ServerHandle>,
}
@ -172,10 +174,13 @@ where
None
};
let proxy_config = ProxyAcceptorConfig::default();
Ok(Self {
config,
middlewares,
tls_config,
proxy_config,
servers: JoinSet::new(),
handles: Vec::new(),
})
@ -195,6 +200,14 @@ where
Ok(|inner| RustlsAcceptor::new(config).acceptor(inner))
}
/// Returns a function that transforms a lower-layer acceptor into a Proxy
/// Protocol acceptor.
fn proxy_acceptor_factory<A>(&self) -> impl FnOnce(A) -> ProxyAcceptor<A> {
let config = self.proxy_config.clone();
|inner| ProxyAcceptor::new(inner, config)
}
fn spawn_server_inner<A>(
&mut self,
listen: ListenConfig,
@ -229,16 +242,30 @@ where
address,
port,
tls,
proxy_protocol,
} => {
let addr = SocketAddr::from((address, port));
let server = bind(addr);
if tls {
let server =
server.map(self.tls_acceptor_factory(&listen)?);
self.spawn_server_inner(listen, server, app);
} else {
self.spawn_server_inner(listen, server, app);
match (tls, proxy_protocol) {
(false, false) => {
self.spawn_server_inner(listen, server, app);
}
(false, true) => {
let server = server.map(self.proxy_acceptor_factory());
self.spawn_server_inner(listen, server, app);
}
(true, false) => {
let server =
server.map(self.tls_acceptor_factory(&listen)?);
self.spawn_server_inner(listen, server, app);
}
(true, true) => {
let server = server
.map(self.proxy_acceptor_factory())
.map(self.tls_acceptor_factory(&listen)?);
self.spawn_server_inner(listen, server, app);
}
}
Ok(())