1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-11-25 19:11:10 +00:00

refactor server binding

This commit is contained in:
Rob Ede 2023-03-11 22:17:52 +00:00
parent 4c4024c949
commit 3fc01c4887
No known key found for this signature in database
GPG key ID: 97C636207D3EF933
2 changed files with 39 additions and 34 deletions

View file

@ -338,7 +338,7 @@ where
/// # ; Ok(()) } /// # ; Ok(()) }
/// ``` /// ```
pub fn bind<A: net::ToSocketAddrs>(mut self, addrs: A) -> io::Result<Self> { pub fn bind<A: net::ToSocketAddrs>(mut self, addrs: A) -> io::Result<Self> {
let sockets = self.bind2(addrs)?; let sockets = bind_addrs(addrs, self.backlog)?;
for lst in sockets { for lst in sockets {
self = self.listen(lst)?; self = self.listen(lst)?;
@ -347,33 +347,6 @@ where
Ok(self) Ok(self)
} }
fn bind2<A: net::ToSocketAddrs>(&self, addrs: A) -> io::Result<Vec<net::TcpListener>> {
let mut err = None;
let mut success = false;
let mut sockets = Vec::new();
for addr in addrs.to_socket_addrs()? {
match create_tcp_listener(addr, self.backlog) {
Ok(lst) => {
success = true;
sockets.push(lst);
}
Err(e) => err = Some(e),
}
}
if success {
Ok(sockets)
} else if let Some(e) = err.take() {
Err(e)
} else {
Err(io::Error::new(
io::ErrorKind::Other,
"Can not bind to address.",
))
}
}
/// Resolves socket address(es) and binds server to created listener(s) for TLS connections /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
/// using Rustls. /// using Rustls.
/// ///
@ -386,7 +359,7 @@ where
addrs: A, addrs: A,
config: RustlsServerConfig, config: RustlsServerConfig,
) -> io::Result<Self> { ) -> io::Result<Self> {
let sockets = self.bind2(addrs)?; let sockets = bind_addrs(addrs, self.backlog)?;
for lst in sockets { for lst in sockets {
self = self.listen_rustls_inner(lst, config.clone())?; self = self.listen_rustls_inner(lst, config.clone())?;
} }
@ -404,7 +377,7 @@ where
where where
A: net::ToSocketAddrs, A: net::ToSocketAddrs,
{ {
let sockets = self.bind2(addrs)?; let sockets = bind_addrs(addrs, self.backlog)?;
let acceptor = openssl_acceptor(builder)?; let acceptor = openssl_acceptor(builder)?;
for lst in sockets { for lst in sockets {
@ -719,6 +692,38 @@ where
} }
} }
/// Bind TCP listeners to socket addresses resolved from `addrs` with options.
fn bind_addrs(
addrs: impl net::ToSocketAddrs,
backlog: u32,
) -> io::Result<Vec<net::TcpListener>> {
let mut err = None;
let mut success = false;
let mut sockets = Vec::new();
for addr in addrs.to_socket_addrs()? {
match create_tcp_listener(addr, backlog) {
Ok(lst) => {
success = true;
sockets.push(lst);
}
Err(e) => err = Some(e),
}
}
if success {
Ok(sockets)
} else if let Some(err) = err.take() {
Err(err)
} else {
Err(io::Error::new(
io::ErrorKind::Other,
"Can not bind to address.",
))
}
}
/// Creates a TCP listener from socket address and options.
fn create_tcp_listener(addr: net::SocketAddr, backlog: u32) -> io::Result<net::TcpListener> { fn create_tcp_listener(addr: net::SocketAddr, backlog: u32) -> io::Result<net::TcpListener> {
use socket2::{Domain, Protocol, Socket, Type}; use socket2::{Domain, Protocol, Socket, Type};
let domain = Domain::for_address(addr); let domain = Domain::for_address(addr);
@ -731,7 +736,7 @@ fn create_tcp_listener(addr: net::SocketAddr, backlog: u32) -> io::Result<net::T
Ok(net::TcpListener::from(socket)) Ok(net::TcpListener::from(socket))
} }
/// Configure `SslAcceptorBuilder` with custom server flags. /// Configures OpenSSL acceptor `builder` with ALPN protocols.
#[cfg(feature = "openssl")] #[cfg(feature = "openssl")]
fn openssl_acceptor(mut builder: SslAcceptorBuilder) -> io::Result<SslAcceptor> { fn openssl_acceptor(mut builder: SslAcceptorBuilder) -> io::Result<SslAcceptor> {
builder.set_alpn_select_callback(|_, protocols| { builder.set_alpn_select_callback(|_, protocols| {

View file

@ -304,7 +304,7 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn test_either_extract_first_try() { async fn test_either_extract_first_try() {
let (req, mut pl) = TestRequest::default() let (req, mut pl) = TestRequest::default()
.set_form(&TestForm { .set_form(TestForm {
hello: "world".to_owned(), hello: "world".to_owned(),
}) })
.to_http_parts(); .to_http_parts();
@ -320,7 +320,7 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn test_either_extract_fallback() { async fn test_either_extract_fallback() {
let (req, mut pl) = TestRequest::default() let (req, mut pl) = TestRequest::default()
.set_json(&TestForm { .set_json(TestForm {
hello: "world".to_owned(), hello: "world".to_owned(),
}) })
.to_http_parts(); .to_http_parts();
@ -351,7 +351,7 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn test_either_extract_recursive_fallback_inner() { async fn test_either_extract_recursive_fallback_inner() {
let (req, mut pl) = TestRequest::default() let (req, mut pl) = TestRequest::default()
.set_json(&TestForm { .set_json(TestForm {
hello: "world".to_owned(), hello: "world".to_owned(),
}) })
.to_http_parts(); .to_http_parts();