Allow more minimal cargo features, tidy code, allow setting unix domain socket filename

This commit is contained in:
chaos 2023-09-27 21:40:47 +01:00
parent 884df6a08e
commit f3754b46cf
No known key found for this signature in database
3 changed files with 274 additions and 31 deletions

238
Cargo.lock generated
View file

@ -487,6 +487,22 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "core-foundation"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.9" version = "0.2.9"
@ -604,6 +620,27 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd"
dependencies = [
"errno-dragonfly",
"libc",
"windows-sys",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]] [[package]]
name = "exr" name = "exr"
version = "1.71.0" version = "1.71.0"
@ -620,6 +657,12 @@ dependencies = [
"zune-inflate", "zune-inflate",
] ]
[[package]]
name = "fastrand"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
[[package]] [[package]]
name = "fdeflate" name = "fdeflate"
version = "0.3.0" version = "0.3.0"
@ -654,6 +697,21 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]] [[package]]
name = "form_urlencoded" name = "form_urlencoded"
version = "1.2.0" version = "1.2.0"
@ -891,6 +949,19 @@ dependencies = [
"tokio-rustls", "tokio-rustls",
] ]
[[package]]
name = "hyper-tls"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [
"bytes",
"hyper",
"native-tls",
"tokio",
"tokio-native-tls",
]
[[package]] [[package]]
name = "idna" name = "idna"
version = "0.4.0" version = "0.4.0"
@ -938,9 +1009,9 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.0.0" version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" checksum = "ad227c3af19d4914570ad36d30409928b75967c298feb9ea1969db3a610bb14e"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown 0.14.0", "hashbrown 0.14.0",
@ -1011,6 +1082,12 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "lebe" name = "lebe"
version = "0.5.2" version = "0.5.2"
@ -1053,6 +1130,12 @@ dependencies = [
"glob", "glob",
] ]
[[package]]
name = "linux-raw-sys"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128"
[[package]] [[package]]
name = "local-channel" name = "local-channel"
version = "0.1.4" version = "0.1.4"
@ -1172,6 +1255,24 @@ dependencies = [
"rayon", "rayon",
] ]
[[package]]
name = "native-tls"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
dependencies = [
"lazy_static",
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[package]] [[package]]
name = "new_debug_unreachable" name = "new_debug_unreachable"
version = "1.0.4" version = "1.0.4"
@ -1283,6 +1384,50 @@ version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "openssl"
version = "0.10.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c"
dependencies = [
"bitflags 2.4.0",
"cfg-if",
"foreign-types",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.37",
]
[[package]]
name = "openssl-probe"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-sys"
version = "0.9.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.12.1" version = "0.12.1"
@ -1572,10 +1717,12 @@ dependencies = [
"http-body", "http-body",
"hyper", "hyper",
"hyper-rustls", "hyper-rustls",
"hyper-tls",
"ipnet", "ipnet",
"js-sys", "js-sys",
"log", "log",
"mime", "mime",
"native-tls",
"once_cell", "once_cell",
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
@ -1585,6 +1732,7 @@ dependencies = [
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
"tokio", "tokio",
"tokio-native-tls",
"tokio-rustls", "tokio-rustls",
"tokio-socks", "tokio-socks",
"tokio-util", "tokio-util",
@ -1659,6 +1807,19 @@ dependencies = [
"semver", "semver",
] ]
[[package]]
name = "rustix"
version = "0.38.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f"
dependencies = [
"bitflags 2.4.0",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]] [[package]]
name = "rustls" name = "rustls"
version = "0.21.7" version = "0.21.7"
@ -1696,6 +1857,15 @@ version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]]
name = "schannel"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88"
dependencies = [
"windows-sys",
]
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.2.0" version = "1.2.0"
@ -1712,6 +1882,29 @@ dependencies = [
"untrusted", "untrusted",
] ]
[[package]]
name = "security-framework"
version = "2.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]] [[package]]
name = "semver" name = "semver"
version = "1.0.19" version = "1.0.19"
@ -1900,19 +2093,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a"
[[package]] [[package]]
name = "thiserror" name = "tempfile"
version = "1.0.48" version = "3.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef"
dependencies = [
"cfg-if",
"fastrand",
"redox_syscall",
"rustix",
"windows-sys",
]
[[package]]
name = "thiserror"
version = "1.0.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.48" version = "1.0.49"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2003,6 +2209,16 @@ dependencies = [
"syn 2.0.37", "syn 2.0.37",
] ]
[[package]]
name = "tokio-native-tls"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
dependencies = [
"native-tls",
"tokio",
]
[[package]] [[package]]
name = "tokio-rustls" name = "tokio-rustls"
version = "0.24.1" version = "0.24.1"
@ -2075,7 +2291,7 @@ version = "0.19.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
dependencies = [ dependencies = [
"indexmap 2.0.0", "indexmap 2.0.1",
"serde", "serde",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
@ -2172,6 +2388,12 @@ dependencies = [
"rust_hawktracer", "rust_hawktracer",
] ]
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]] [[package]]
name = "version-compare" name = "version-compare"
version = "0.1.1" version = "0.1.1"

View file

@ -6,22 +6,34 @@ version = "0.1.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
# Web Requests & Async Runtime
tokio = { version = "1.32.0", features = ["full"] }
actix-web = "4.4.0" actix-web = "4.4.0"
image = "0.24.7" reqwest = { version = "0.11.20", features = ["stream", "brotli", "gzip", "socks"], default-features = false }
libwebp-sys = { version = "0.9.4", optional = true }
mimalloc = "0.1.39"
once_cell = "1.18.0"
qstring = "0.7.2" qstring = "0.7.2"
# Alternate Allocator
mimalloc = { version = "0.1.39", optional = true }
# Transcoding Images to WebP/AVIF to save bandwidth
image = { version = "0.24.7", optional = true }
libwebp-sys = { version = "0.9.4", optional = true }
ravif = { version = "0.11.3", optional = true } ravif = { version = "0.11.3", optional = true }
rgb = { version = "0.8.36", optional = true } rgb = { version = "0.8.36", optional = true }
once_cell = "1.18.0"
regex = "1.9.5" regex = "1.9.5"
reqwest = { version = "0.11.20", features = ["rustls-tls", "stream", "brotli", "gzip", "socks"], default-features = false }
tokio = { version = "1.32.0", features = ["full"] }
[features] [features]
default = ["webp"] default = ["webp", "mimalloc", "reqwest-rustls"]
avif = ["dep:ravif", "dep:rgb"]
webp = ["dep:libwebp-sys"] reqwest-rustls = ["reqwest/rustls-tls"]
reqwest-native-tls = ["reqwest/default-tls"]
avif = ["dep:ravif", "dep:rgb", "dep:image"]
webp = ["dep:libwebp-sys", "dep:image"]
mimalloc = ["dep:mimalloc"]
[profile.release] [profile.release]
lto = true lto = true

View file

@ -1,17 +1,21 @@
use actix_web::http::Method; use actix_web::http::Method;
use actix_web::{web, App, HttpRequest, HttpResponse, HttpResponseBuilder, HttpServer}; use actix_web::{web, App, HttpRequest, HttpResponse, HttpResponseBuilder, HttpServer};
use mimalloc::MiMalloc;
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::env; use std::env;
use std::error::Error; use std::error::Error;
use tokio::sync::oneshot;
use tokio::task::spawn_blocking;
#[cfg(not(any(feature = "reqwest-native-tls", feature = "reqwest-rustls")))]
compile_error!("feature \"reqwest-native-tls\" or \"reqwest-rustls\" must be set for proxy to have TLS support");
#[cfg(any(feature = "webp", feature = "avif"))]
use tokio::{sync::oneshot, task::spawn_blocking};
#[cfg(feature = "mimalloc")]
#[global_allocator] #[global_allocator]
static GLOBAL: MiMalloc = MiMalloc; static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
#[actix_web::main] #[actix_web::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
@ -22,8 +26,8 @@ async fn main() -> std::io::Result<()> {
App::new().default_service(web::to(index)) App::new().default_service(web::to(index))
}); });
// get port from env // get port from env
if env::var("UDS").is_ok() { if let Ok(unix_socket) = env::var("BIND_UNIX") {
server.bind_uds("./socket/actix.sock")? server.bind_uds(unix_socket)?
} 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)?
@ -48,17 +52,17 @@ static CLIENT: Lazy<Client> = Lazy::new(|| {
None None
}; };
let builder = if proxy.is_some() {
let builder = if let Some(proxy) = proxy {
// proxy basic auth // proxy basic auth
if let Ok(proxy_auth_user) = env::var("PROXY_USER") { if let Ok(proxy_auth_user) = env::var("PROXY_USER") {
let proxy_auth_pass = env::var("PROXY_PASS").unwrap_or_default(); let proxy_auth_pass = env::var("PROXY_PASS").unwrap_or_default();
builder.proxy( builder.proxy(
proxy proxy
.unwrap()
.basic_auth(&proxy_auth_user, &proxy_auth_pass), .basic_auth(&proxy_auth_user, &proxy_auth_pass),
) )
} else { } else {
builder.proxy(proxy.unwrap()) builder.proxy(proxy)
} }
} else { } else {
builder builder
@ -133,6 +137,9 @@ async fn index(req: HttpRequest) -> Result<HttpResponse, Box<dyn Error>> {
return Err("No host provided".into()); return Err("No host provided".into());
} }
#[cfg(any(feature = "webp", feature = "avif"))]
let disallow_image_transcoding = env::var("DISALLOW_IMAGE_TRANSCODING").is_ok();
let rewrite = query.get("rewrite") != Some("false"); let rewrite = query.get("rewrite") != Some("false");
#[cfg(feature = "avif")] #[cfg(feature = "avif")]
@ -213,7 +220,9 @@ async fn index(req: HttpRequest) -> Result<HttpResponse, Box<dyn Error>> {
if rewrite { if rewrite {
if let Some(content_type) = resp.headers().get("content-type") { if let Some(content_type) = resp.headers().get("content-type") {
#[cfg(feature = "avif")] #[cfg(feature = "avif")]
if content_type == "image/webp" || content_type == "image/jpeg" && avif { if disallow_image_transcoding
&& (content_type == "image/webp" || content_type == "image/jpeg" && avif)
{
let resp_bytes = resp.bytes().await.unwrap(); let resp_bytes = resp.bytes().await.unwrap();
let (tx, rx) = oneshot::channel::<(Vec<u8>, &'static str)>(); let (tx, rx) = oneshot::channel::<(Vec<u8>, &'static str)>();
spawn_blocking(|| { spawn_blocking(|| {
@ -235,11 +244,11 @@ async fn index(req: HttpRequest) -> Result<HttpResponse, Box<dyn Error>> {
.with_speed(7) .with_speed(7)
.encode_rgb(buffer); .encode_rgb(buffer);
return if let Ok(res) = res { if let Ok(res) = res {
tx.send((res.avif_file.to_vec(), "image/avif")).unwrap(); tx.send((res.avif_file.to_vec(), "image/avif")).unwrap();
} else { } else {
tx.send((resp_bytes.into(), "image/jpeg")).unwrap(); tx.send((resp_bytes.into(), "image/jpeg")).unwrap();
}; }
}); });
let (body, content_type) = rx.await.unwrap(); let (body, content_type) = rx.await.unwrap();
response.content_type(content_type); response.content_type(content_type);
@ -247,7 +256,7 @@ async fn index(req: HttpRequest) -> Result<HttpResponse, Box<dyn Error>> {
} }
#[cfg(feature = "webp")] #[cfg(feature = "webp")]
if content_type == "image/jpeg" { if !disallow_image_transcoding && content_type == "image/jpeg" {
let resp_bytes = resp.bytes().await.unwrap(); let resp_bytes = resp.bytes().await.unwrap();
let (tx, rx) = oneshot::channel::<(Vec<u8>, &'static str)>(); let (tx, rx) = oneshot::channel::<(Vec<u8>, &'static str)>();
spawn_blocking(|| { spawn_blocking(|| {