use std::process::Command;
use std::sync::{Arc, atomic::AtomicBool};
use std::thread::JoinHandle;
use crate::{
DownloadResult, DownloadSink, ResponseError, StartError,
drivers::{Driver, Request},
util,
};
#[derive(Debug, Clone, Copy)]
pub(crate) struct WgetDriver;
impl Driver for WgetDriver {
fn start(
&self,
req: Request,
sink: DownloadSink,
cancel: Arc<AtomicBool>,
) -> Result<JoinHandle<Result<DownloadResult, ResponseError>>, StartError> {
let mut cmd = Command::new("wget");
cmd.arg("-O")
.arg("-")
.arg("--server-response")
.arg("--no-http-keep-alive")
.arg(req.url.to_url_string());
if !req.follow_redirects {
cmd.arg("--max-redirect=0");
} else {
cmd.arg("--max-redirect=10");
}
for (k, v) in util::add_common_headers(&req) {
cmd.arg("--header").arg(format!("{k}: {v}"));
}
util::spawn_download_cmd_thread(cmd, "wget", req, sink, cancel, download_wget)
}
}
fn download_wget(
output: std::process::Output,
_req: &Request,
) -> Result<(u16, Option<crate::ContentEncoding>), ResponseError> {
let stderr = String::from_utf8_lossy(&output.stderr);
let mut last_code: Option<u16> = None;
for line in stderr.lines() {
let line = line.trim();
if let Some(rest) = line.strip_prefix("HTTP/") {
let parts: Vec<&str> = rest.split_whitespace().collect();
if parts.len() >= 2 {
if let Ok(code) = parts[1].parse::<u16>() {
last_code = Some(code);
}
}
}
}
Ok((last_code.unwrap_or(200), None))
}