diff --git a/src/main.rs b/src/main.rs index d2b51dd..f8799fe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,8 @@ use std::io::ErrorKind; use std::net::TcpListener; use std::os::unix::net::UnixListener; use std::{env, io}; +use std::fs; +use std::os::unix::fs::PermissionsExt; #[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"); @@ -80,7 +82,18 @@ async fn main() -> std::io::Result<()> { server = if utils::get_env_bool("UDS") { let socket_path = env::var("BIND_UNIX").unwrap_or_else(|_| "./socket/actix.sock".to_string()); - server.bind_uds(socket_path)? + // Create the socket directory if it doesn't exist + if let Some(pos) = socket_path.rfind('/') { + let dir = &socket_path[..pos]; + fs::create_dir_all(dir).expect("Failed to create socket directory"); + } + let listener = server.bind_uds(socket_path.clone())?; + // Set permissions to 777 + let permissions = fs::metadata(&socket_path)?.permissions(); + let mut mode = permissions.mode(); + mode |= 0o777; // Set to 777 + fs::set_permissions(&socket_path, fs::Permissions::from_mode(mode))?; + listener } else { let bind = env::var("BIND").unwrap_or_else(|_| "0.0.0.0:8080".to_string()); server.bind(bind)? @@ -91,10 +104,10 @@ async fn main() -> std::io::Result<()> { } static RE_DOMAIN: Lazy = - Lazy::new(|| Regex::new(r"^(?:[a-z\d.-]*\.)?([a-z\d-]*\.[a-z\d-]*)$").unwrap()); +Lazy::new(|| Regex::new(r"^(?:[a-z\d.-]*\.)?([a-z\d-]*\.[a-z\d-]*)$").unwrap()); static RE_MANIFEST: Lazy = Lazy::new(|| Regex::new("(?m)URI=\"([^\"]+)\"").unwrap()); static RE_DASH_MANIFEST: Lazy = - Lazy::new(|| Regex::new("BaseURL>(https://[^<]+)(https://[^<]+) = Lazy::new(|| { let builder = Client::builder() @@ -124,7 +137,7 @@ static CLIENT: Lazy = Lazy::new(|| { builder } .build() - .unwrap() + .unwrap() }); const ANDROID_USER_AGENT: &str = "com.google.android.youtube/1537338816 (Linux; U; Android 13; en_US; ; Build/TQ2A.230505.002; Cronet/113.0.5672.24)"; @@ -155,20 +168,20 @@ fn is_header_allowed(header: &str) -> bool { !matches!( header, "host" - | "content-length" - | "set-cookie" - | "alt-svc" - | "accept-ch" - | "report-to" - | "strict-transport-security" - | "user-agent" - | "range" - | "transfer-encoding" - | "x-real-ip" - | "origin" - | "referer" - // the 'x-title' header contains non-ascii characters which is not allowed on some HTTP clients - | "x-title" + | "content-length" + | "set-cookie" + | "alt-svc" + | "accept-ch" + | "report-to" + | "strict-transport-security" + | "user-agent" + | "range" + | "transfer-encoding" + | "x-real-ip" + | "origin" + | "referer" + // the 'x-title' header contains non-ascii characters which is not allowed on some HTTP clients + | "x-title" ) } @@ -227,7 +240,7 @@ async fn index(req: HttpRequest) -> Result> { // Find the slice before "/range/" if let Some(position) = path .windows(range_marker.len()) - .position(|window| window == range_marker) + .position(|window| window == range_marker) { // Update the hasher with the part of the path before "/range/" // We add +1 to include the "/" in the hash @@ -244,7 +257,7 @@ async fn index(req: HttpRequest) -> Result> { hash[..8].to_owned() }) .await - .unwrap(); + .unwrap(); if hash != qhash { return Err("Invalid qhash provided".into()); @@ -370,38 +383,38 @@ async fn index(req: HttpRequest) -> Result> { #[cfg(feature = "avif")] if !disallow_image_transcoding && (content_type == "image/webp" || content_type == "image/jpeg" && avif) - { - let resp_bytes = resp.bytes().await.unwrap(); - let (body, content_type) = spawn_blocking(|| { - use ravif::{Encoder, Img}; - use rgb::FromSlice; + { + let resp_bytes = resp.bytes().await.unwrap(); + let (body, content_type) = spawn_blocking(|| { + use ravif::{Encoder, Img}; + use rgb::FromSlice; - let image = image::load_from_memory(&resp_bytes).unwrap(); + let image = image::load_from_memory(&resp_bytes).unwrap(); - let width = image.width() as usize; - let height = image.height() as usize; + let width = image.width() as usize; + let height = image.height() as usize; - let buf = image.into_rgb8(); - let buf = buf.as_raw().as_rgb(); + let buf = image.into_rgb8(); + let buf = buf.as_raw().as_rgb(); - let buffer = Img::new(buf, width, height); + let buffer = Img::new(buf, width, height); - let res = Encoder::new() - .with_quality(80f32) - .with_speed(7) - .encode_rgb(buffer); + let res = Encoder::new() + .with_quality(80f32) + .with_speed(7) + .encode_rgb(buffer); - if let Ok(res) = res { - (res.avif_file.to_vec(), "image/avif") - } else { - (resp_bytes.into(), "image/jpeg") - } - }) - .await - .unwrap(); - response.content_type(content_type); - return Ok(response.body(body)); - } + if let Ok(res) = res { + (res.avif_file.to_vec(), "image/avif") + } else { + (resp_bytes.into(), "image/jpeg") + } + }) + .await + .unwrap(); + response.content_type(content_type); + return Ok(response.body(body)); + } #[cfg(feature = "webp")] if !disallow_image_transcoding && content_type == "image/jpeg" { @@ -440,7 +453,7 @@ async fn index(req: HttpRequest) -> Result> { } }) .await - .unwrap(); + .unwrap(); response.content_type(content_type); return Ok(response.body(body)); } @@ -465,7 +478,7 @@ async fn index(req: HttpRequest) -> Result> { } utils::localize_url(line, host.as_str()) }) - .collect::>() + .collect::>() .join("\n"); return Ok(response.body(modified));