From 97978719b366ee2c85a0eef9534a92f9225db370 Mon Sep 17 00:00:00 2001 From: sigoden Date: Thu, 2 Jun 2022 09:44:40 +0800 Subject: [PATCH] feat: list all ifaces when listening 0.0.0.0 --- Cargo.lock | 55 ++++++++++++++++++++++++++++++++++++++++++++------- Cargo.toml | 1 + src/server.rs | 38 +++++++++++++++++++++++++++++++---- 3 files changed, 83 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a02d0f..a53dd1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,7 +109,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -180,6 +180,12 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "c_linked_list" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" + [[package]] name = "cache-padded" version = "1.2.0" @@ -211,7 +217,7 @@ dependencies = [ "num-integer", "num-traits", "time 0.1.44", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -244,7 +250,7 @@ checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" dependencies = [ "atty", "lazy_static", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -303,6 +309,7 @@ dependencies = [ "base64", "clap", "futures", + "get_if_addrs", "headers", "hyper", "log", @@ -452,6 +459,12 @@ dependencies = [ "slab", ] +[[package]] +name = "gcc" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" + [[package]] name = "generic-array" version = "0.14.5" @@ -462,6 +475,28 @@ dependencies = [ "version_check", ] +[[package]] +name = "get_if_addrs" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7" +dependencies = [ + "c_linked_list", + "get_if_addrs-sys", + "libc", + "winapi 0.2.8", +] + +[[package]] +name = "get_if_addrs-sys" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48" +dependencies = [ + "gcc", + "libc", +] + [[package]] name = "hashbrown" version = "0.11.2" @@ -824,7 +859,7 @@ dependencies = [ "colored", "log", "time 0.3.9", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -840,7 +875,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" dependencies = [ "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -888,7 +923,7 @@ checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -924,7 +959,7 @@ dependencies = [ "pin-project-lite", "socket2", "tokio-macros", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1051,6 +1086,12 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 0d0d85e..1cb8474 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ async_zip = "0.0.7" async-walkdir = "0.2.0" headers = "0.3.7" mime_guess = "2.0.4" +get_if_addrs = "0.5.3" [profile.release] lto = true diff --git a/src/server.rs b/src/server.rs index 17f20c3..51bd95f 100644 --- a/src/server.rs +++ b/src/server.rs @@ -6,6 +6,7 @@ use async_zip::write::{EntryOptions, ZipFileWriter}; use async_zip::Compression; use futures::stream::StreamExt; use futures::TryStreamExt; +use get_if_addrs::get_if_addrs; use headers::{ AcceptRanges, AccessControlAllowHeaders, AccessControlAllowOrigin, ContentLength, ContentRange, ContentType, ETag, HeaderMap, HeaderMapExt, IfModifiedSince, IfNoneMatch, IfRange, @@ -21,6 +22,7 @@ use percent_encoding::percent_decode; use serde::Serialize; use std::convert::Infallible; use std::fs::Metadata; +use std::net::IpAddr; use std::path::{Path, PathBuf}; use std::sync::Arc; use std::time::SystemTime; @@ -47,7 +49,9 @@ macro_rules! status { } pub async fn serve(args: Args) -> BoxResult<()> { - let address = args.address()?; + let socket_addr = args.address()?; + let address = args.address.clone(); + let port = args.port; let inner = Arc::new(InnerService::new(args)); let make_svc = make_service_fn(move |_| { let inner = inner.clone(); @@ -59,9 +63,8 @@ pub async fn serve(args: Args) -> BoxResult<()> { } }); - let server = hyper::Server::try_bind(&address)?.serve(make_svc); - let address = server.local_addr(); - eprintln!("Files served on http://{}", address); + let server = hyper::Server::try_bind(&socket_addr)?.serve(make_svc); + print_listening(&address, port); server.await?; Ok(()) @@ -674,3 +677,30 @@ fn to_content_range(range: &Range, complete_length: u64) -> Option _ => None, }) } + +fn print_listening(address: &str, port: u16) { + let addrs = retrive_listening_addrs(address); + if addrs.len() == 1 { + eprintln!("Listening on http://{}:{}", addrs[0], port); + } else { + eprintln!("Listening on:"); + for addr in addrs { + eprintln!(" http://{}:{}", addr, port); + } + } +} + +fn retrive_listening_addrs(address: &str) -> Vec { + if address == "0.0.0.0" { + if let Ok(interfaces) = get_if_addrs() { + let mut ifaces: Vec = interfaces + .into_iter() + .map(|v| v.ip()) + .filter(|v| v.is_ipv4()) + .collect(); + ifaces.sort(); + return ifaces.into_iter().map(|v| v.to_string()).collect(); + } + } + vec![address.to_owned()] +}