feat: Get listener from fd

This commit is contained in:
Jeidnx 2024-06-17 21:22:00 +02:00 committed by Bnyro
parent c7ecef8c4b
commit 7deb4175e3
3 changed files with 97 additions and 12 deletions

40
Cargo.lock generated
View file

@ -1178,6 +1178,17 @@ version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
name = "listenfd"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0500463acd96259d219abb05dc57e5a076ef04b2db9a2112846929b5f174c96"
dependencies = [
"libc",
"uuid",
"winapi",
]
[[package]] [[package]]
name = "litemap" name = "litemap"
version = "0.7.3" version = "0.7.3"
@ -1514,6 +1525,7 @@ dependencies = [
"futures-util", "futures-util",
"image", "image",
"libwebp-sys", "libwebp-sys",
"listenfd",
"mimalloc", "mimalloc",
"once_cell", "once_cell",
"qstring", "qstring",
@ -2372,6 +2384,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "uuid"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
[[package]] [[package]]
name = "v_frame" name = "v_frame"
version = "0.3.8" version = "0.3.8"
@ -2511,6 +2529,28 @@ version = "0.25.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.48.0" version = "0.48.0"

View file

@ -26,6 +26,7 @@ regex = "1.10.4"
blake3 = { version = "1.5.1", optional = true } blake3 = { version = "1.5.1", optional = true }
bytes = "1.6.0" bytes = "1.6.0"
futures-util = "0.3.30" futures-util = "0.3.30"
listenfd = "1.0.1"
[features] [features]
default = ["webp", "mimalloc", "reqwest-rustls", "qhash"] default = ["webp", "mimalloc", "reqwest-rustls", "qhash"]

View file

@ -3,12 +3,15 @@ mod utils;
use actix_web::http::{Method, StatusCode}; use actix_web::http::{Method, StatusCode};
use actix_web::{web, App, HttpRequest, HttpResponse, HttpResponseBuilder, HttpServer}; use actix_web::{web, App, HttpRequest, HttpResponse, HttpResponseBuilder, HttpServer};
use listenfd::ListenFd;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use qstring::QString; use qstring::QString;
use regex::Regex; use regex::Regex;
use reqwest::{Body, Client, Request, Url}; use reqwest::{Body, Client, Request, Url};
use std::error::Error; use std::error::Error;
use std::io::ErrorKind; use std::io::ErrorKind;
use std::net::TcpListener;
use std::os::unix::net::UnixListener;
use std::{env, io}; use std::{env, io};
#[cfg(not(any(feature = "reqwest-native-tls", feature = "reqwest-rustls")))] #[cfg(not(any(feature = "reqwest-native-tls", feature = "reqwest-rustls")))]
@ -23,27 +26,68 @@ use ump_stream::UmpTransformStream;
#[global_allocator] #[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
fn try_get_fd_listeners() -> (Option<UnixListener>, Option<TcpListener>) {
let mut fd = ListenFd::from_env();
let unix_listener = env::var("FD_UNIX").ok().map(|fd_unix| {
let fd_pos = fd_unix.parse().expect("FD_UNIX is not a number");
println!("Trying to take Unix socket at position {}", fd_pos);
fd.take_unix_listener(fd_pos)
.expect(format!("fd {} is not a Unix socket", fd_pos).as_str())
.expect(format!("fd {} has already been used", fd_pos).as_str())
});
let tcp_listener = env::var("FD_TCP").ok().map(|fd_tcp| {
let fd_pos = fd_tcp.parse().expect("FD_TCP is not a number");
println!("Trying to take TCP listener at position {}", fd_pos);
fd.take_tcp_listener(fd_pos)
.expect(format!("fd {} is not a TCP listener", fd_pos).as_str())
.expect(format!("fd {} has already been used", fd_pos).as_str())
});
(unix_listener, tcp_listener)
}
#[actix_web::main] #[actix_web::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
println!("Running server!"); println!("Running server!");
let server = HttpServer::new(|| { let mut server = HttpServer::new(|| {
// match all requests // match all requests
App::new().default_service(web::to(index)) App::new().default_service(web::to(index))
}); });
let fd_listeners = try_get_fd_listeners();
if let Some(unix_listener) = fd_listeners.0 {
server = server
.listen_uds(unix_listener)
.expect("Error while trying to listen on Unix socket passed by fd");
println!("Listening on Unix socket passed by fd.");
}
if let Some(tcp_listener) = fd_listeners.1 {
server = server
.listen(tcp_listener)
.expect("Error while trying to listen on TCP listener passed by fd");
println!("Listening on TCP listener passed by fd.");
}
// Only bind manually if there is not already a listener
if server.addrs().is_empty() {
// get socket/port from env // get socket/port from env
// backwards compat when only UDS is set // backwards compat when only UDS is set
if utils::get_env_bool("UDS") { server = if utils::get_env_bool("UDS") {
let socket_path = let socket_path =
env::var("BIND_UNIX").unwrap_or_else(|_| "./socket/actix.sock".to_string()); env::var("BIND_UNIX").unwrap_or_else(|_| "./socket/actix.sock".to_string());
server.bind_uds(socket_path)? server.bind_uds(socket_path)?
} else { } else {
let bind = env::var("BIND").unwrap_or_else(|_| "0.0.0.0:8080".to_string()); let bind = env::var("BIND").unwrap_or_else(|_| "0.0.0.0:8080".to_string());
server.bind(bind)? server.bind(bind)?
};
} }
.run()
.await server.run().await
} }
static RE_DOMAIN: Lazy<Regex> = static RE_DOMAIN: Lazy<Regex> =