mirror of
https://codeberg.org/icewind/single-file-server.git
synced 2026-06-03 10:04:10 +02:00
listenfd support
This commit is contained in:
parent
9fbe3bf7fc
commit
0f3ac7ebd1
6 changed files with 130 additions and 10 deletions
96
Cargo.lock
generated
96
Cargo.lock
generated
|
|
@ -148,6 +148,12 @@ dependencies = [
|
|||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.10.1"
|
||||
|
|
@ -381,6 +387,16 @@ version = "1.0.15"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
|
|
@ -393,6 +409,17 @@ version = "0.2.174"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||
|
||||
[[package]]
|
||||
name = "listenfd"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b87bc54a4629b4294d0b3ef041b64c40c611097a677d9dc07b2c67739fe39dba"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"uuid",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.27"
|
||||
|
|
@ -621,6 +648,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"axum",
|
||||
"clap",
|
||||
"listenfd",
|
||||
"main_error",
|
||||
"serde",
|
||||
"thiserror",
|
||||
|
|
@ -864,6 +892,16 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.1"
|
||||
|
|
@ -876,6 +914,64 @@ version = "0.11.1+wasi-snapshot-preview1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"rustversion",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
|
|
|||
|
|
@ -12,4 +12,5 @@ tracing-subscriber = "0.3.19"
|
|||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
toml = "0.8.23"
|
||||
thiserror = "2.0.12"
|
||||
clap = { version = "4.5.40", features = ["derive"] }
|
||||
clap = { version = "4.5.40", features = ["derive"] }
|
||||
listenfd = "1.0.2"
|
||||
|
|
@ -11,7 +11,7 @@ A basic web server for
|
|||
# address = "0.0.0.0" # defaults to "127.0.0.1"
|
||||
# port = 1234 # defaults to 7366
|
||||
# you can set it to listen over a unix socket instead.
|
||||
socket = "/var/run/single-file.sock"
|
||||
socket = "/run/single-file.sock"
|
||||
|
||||
[single-file]
|
||||
# path to single-file-cli
|
||||
|
|
@ -22,6 +22,10 @@ executable = "/path/to/single-file" # defaults to "single-file"
|
|||
executable = "/path/to/chome" # defaults to "chromium"
|
||||
```
|
||||
|
||||
In additional to the `listen` configuration, the server will automatically
|
||||
detect if it get's activated trough systemd socket activation and takes the
|
||||
provided socket.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use toml::from_str;
|
|||
pub struct Config {
|
||||
#[serde(default)]
|
||||
pub listen: ListenConfig,
|
||||
#[serde(default)]
|
||||
#[serde(default, rename = "single-file")]
|
||||
pub single_file: SingleFileConfig,
|
||||
#[serde(default)]
|
||||
pub browser: BrowserConfig,
|
||||
|
|
|
|||
11
src/fetch.rs
11
src/fetch.rs
|
|
@ -4,7 +4,7 @@ use axum::http::StatusCode;
|
|||
use axum::response::{IntoResponse, Response};
|
||||
use thiserror::Error;
|
||||
use tokio::task::{JoinError, spawn_blocking};
|
||||
use tracing::info;
|
||||
use tracing::{debug, info, warn};
|
||||
|
||||
pub async fn fetch_single_file(config: &Config, url: &str) -> Result<String, FetchError> {
|
||||
info!(url, "fetching url");
|
||||
|
|
@ -20,9 +20,16 @@ pub async fn fetch_single_file(config: &Config, url: &str) -> Result<String, Fet
|
|||
|
||||
command.arg(url).arg("--dump-content");
|
||||
|
||||
debug!(?command, "running single-file command");
|
||||
|
||||
let output = spawn_blocking(move || command.output().map_err(FetchError::Command)).await??;
|
||||
|
||||
Ok(String::from_utf8_lossy(&output.stdout).to_string())
|
||||
if !output.stderr.is_empty() {
|
||||
warn!(output = %String::from_utf8_lossy(&output.stderr), "command returned stderr");
|
||||
}
|
||||
let result = String::from_utf8_lossy(&output.stdout).to_string();
|
||||
debug!(length = result.len(), status = ?output.status.code().unwrap_or_default(), "single-file done");
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
|
|
|
|||
22
src/main.rs
22
src/main.rs
|
|
@ -9,10 +9,12 @@ use axum::{debug_handler, Router};
|
|||
use axum::extract::{Path, State};
|
||||
use axum::routing::get;
|
||||
use clap::Parser;
|
||||
use listenfd::ListenFd;
|
||||
use main_error::MainResult;
|
||||
use thiserror::Error;
|
||||
use tokio::net::UnixListener;
|
||||
use tokio::signal::ctrl_c;
|
||||
use tracing::error;
|
||||
use crate::config::{Config, ListenConfig};
|
||||
use crate::fetch::{fetch_single_file, FetchError};
|
||||
|
||||
|
|
@ -46,8 +48,18 @@ async fn main() -> MainResult {
|
|||
ctrl_c().await.ok();
|
||||
};
|
||||
|
||||
match &config.listen {
|
||||
ListenConfig::Unix { socket: path } => {
|
||||
let mut systemd_listener = ListenFd::from_env();
|
||||
|
||||
match (systemd_listener.take_unix_listener(0), &config.listen) {
|
||||
(Ok(Some(listener)), _) => {
|
||||
println!("listening on fd 0");
|
||||
let listener = UnixListener::from_std(listener).unwrap();
|
||||
axum::serve(listener, app)
|
||||
.with_graceful_shutdown(cancel)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
(_, ListenConfig::Unix { socket: path }) => {
|
||||
if let Some(parent) = path.parent() {
|
||||
if !parent.exists() {
|
||||
create_dir_all(parent)
|
||||
|
|
@ -60,7 +72,7 @@ async fn main() -> MainResult {
|
|||
|
||||
let uds = UnixListener::bind(path)
|
||||
.map_err(|error| SetupError::BindUnix { error, path: path.clone() })?;
|
||||
let _ = set_permissions(path, PermissionsExt::from_mode(0o660));
|
||||
let _ = set_permissions(path, PermissionsExt::from_mode(0o666));
|
||||
|
||||
|
||||
println!("listening on {}", path.display());
|
||||
|
|
@ -70,7 +82,7 @@ async fn main() -> MainResult {
|
|||
.await
|
||||
.unwrap();
|
||||
}
|
||||
ListenConfig::Tcp {address, port} => {
|
||||
(_, ListenConfig::Tcp {address, port}) => {
|
||||
let address = SocketAddr::new(*address, *port);
|
||||
let listener = tokio::net::TcpListener::bind(address).await
|
||||
.map_err(|error| SetupError::BindTcp { error, address })?;
|
||||
|
|
@ -112,6 +124,6 @@ enum SetupError {
|
|||
|
||||
#[debug_handler]
|
||||
async fn fetch(State(state): State<App>, Path(url): Path<String>) -> Result<String, FetchError> {
|
||||
fetch_single_file(state.config, &url).await
|
||||
fetch_single_file(state.config, &url).await.inspect_err(|error| error!(%error, url, "Error while fetching url"))
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue