diff --git a/Cargo.toml b/Cargo.toml index dd135ff..58ab9ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,8 +10,14 @@ repository = "https://github.com/nathanbabcock/ffmpeg-sidecar" readme = "README.md" license = "MIT" +[features] +default = ["download_ffmpeg"] +download_ffmpeg = ["reqwest"] + [lib] crate-type = ["lib"] [dependencies] anyhow = "1.0.79" +reqwest = { version = "0.12.8", optional = true, features = ["blocking"]} + diff --git a/src/download.rs b/src/download.rs index cb69476..f35061c 100644 --- a/src/download.rs +++ b/src/download.rs @@ -1,6 +1,6 @@ use std::{ - fs::{create_dir_all, read_dir, remove_dir_all, remove_file, rename}, - io::Read, + fs::{create_dir_all, read_dir, remove_dir_all, remove_file, rename, File}, + io::{copy, Read}, path::{Path, PathBuf}, process::{Command, ExitStatus, Stdio}, }; @@ -54,6 +54,7 @@ pub fn ffmpeg_download_url() -> anyhow::Result<&'static str> { /// /// If FFmpeg is already installed, the method exits early without downloading /// anything. +#[cfg(feature = "download_ffmpeg")] pub fn auto_download() -> anyhow::Result<()> { if ffmpeg_is_installed() { return Ok(()); @@ -111,6 +112,7 @@ pub fn parse_linux_version(version: &str) -> Option { } /// Invoke cURL on the command line to download a file, returning it as a string. +#[deprecated] pub fn curl(url: &str) -> anyhow::Result { let mut child = Command::new("curl") .create_no_window() @@ -127,6 +129,7 @@ pub fn curl(url: &str) -> anyhow::Result { } /// Invoke cURL on the command line to download a file, writing to a file. +#[deprecated] pub fn curl_to_file(url: &str, destination: &str) -> anyhow::Result { Command::new("curl") .create_no_window() @@ -138,13 +141,26 @@ pub fn curl_to_file(url: &str, destination: &str) -> anyhow::Result /// Makes an HTTP request to obtain the latest version available online, /// automatically choosing the correct URL for the current platform. +#[cfg(feature = "download_ffmpeg")] pub fn check_latest_version() -> anyhow::Result { // Mac M1 doesn't have a manifest URL, so match the version provided in `ffmpeg_download_url` if cfg!(all(target_os = "macos", target_arch = "aarch64")) { return Ok("7.0".to_string()); } - let string = curl(ffmpeg_manifest_url()?)?; + let manifest_url = ffmpeg_manifest_url()?; + let response = reqwest::blocking::get(manifest_url) + .context("Failed to make a request for the latest version")?; + + if !response.status().is_success() { + anyhow::bail!( + "Failed to get the latest version, status: {}", + response.status() + ); + } + + let string = response.text().context("Failed to read response text")?; + if cfg!(target_os = "windows") { Ok(string) } else if cfg!(target_os = "macos") { @@ -158,6 +174,7 @@ pub fn check_latest_version() -> anyhow::Result { /// Invoke `curl` to download an archive (ZIP on windows, TAR on linux and mac) /// from the latest published release online. +#[cfg(feature = "download_ffmpeg")] pub fn download_ffmpeg_package(url: &str, download_dir: &Path) -> anyhow::Result { let filename = Path::new(url) .file_name() @@ -165,14 +182,25 @@ pub fn download_ffmpeg_package(url: &str, download_dir: &Path) -> anyhow::Result let archive_path = download_dir.join(filename); - let archive_filename = archive_path.to_str().context("invalid download path")?; - - let exit_status = curl_to_file(url, archive_filename)?; + let response = + reqwest::blocking::get(url).context("Failed to make a request to download ffmpeg")?; - if !exit_status.success() { - anyhow::bail!("Failed to download ffmpeg"); + if !response.status().is_success() { + anyhow::bail!("Failed to download ffmpeg, status: {}", response.status()); } + let mut file = + File::create(&archive_path).context("Failed to create file for ffmpeg download")?; + + copy( + &mut response + .bytes() + .context("Failed to read response bytes")? + .as_ref(), + &mut file, + ) + .context("Failed to write ffmpeg download to file")?; + Ok(archive_path) }