'Corrupted .gif download file using rust but without rust using curl command it works

Hi I tried to download a .gif file using curl command in Linux fedora 36 using
curl https://static.wikia.nocookie.net/minecraft_gamepedia/images/d/d1/Magma_Block_JE2_BE2.gif/revision/latest?cb=20200915183320 --output magma.gif
and it works

but then I try to do the same thing in rust with this function and curl library

pub fn download_file(url: &str, path: String) -> Result<(), Box<dyn std::error::Error>> {
    let mut curl = Easy::new();
    curl.http_content_decoding(true)?;
    curl.get(true)?;
    curl.verbose(true)?;
    curl.connect_timeout(Duration::from_secs(3))?;
    curl.dns_cache_timeout(Duration::from_secs(3))?;
    curl.url(url)?;
    curl.write_function(move |data| {
        if fs::write(&path, data).is_err() {
            eprint!(
                "{}: Failed to write to file -> check permission",
                "error".red().bold()
            );
            process::exit(-1);
        }
        Ok(data.len())
    })?;
    curl.perform()?;
    Ok(())
}

and for the parameters I use https://static.wikia.nocookie.net/minecraft_gamepedia/images/d/d1/Magma_Block_JE2_BE2.gif/revision/latest?cb=20200915183320 and magma.gif but doesn't work it downloads something but it's size is way lower than what is should be and it's corrupted and I can't open it

full source: https://github.com/NiiightmareXD/minecraft_block_downloader
working file: https://i.stack.imgur.com/zpClR.gif
corrupted file: https://www.mediafire.com/file/amlj2vrd4thtkb8/magma.gif/file
working verbose: https://www.mediafire.com/file/hsb4k8jmam5bmoh/working_verbose.txt/file
corrupted verbose: https://www.mediafire.com/file/ouu0h88f2dcgiu9/corrupted_verbose.txt/file
Thanks for reading



Solution 1:[1]

the problem was that the write function overwrite the previous data to file so it gets corrupted so the new code is this and it works

pub fn download_file(url: &str, path: String) -> Result<(), Box<dyn std::error::Error>> {
    let mut curl = Easy::new();
    curl.url(url)?;
    File::create(&path)?;
    let mut file = File::options().write(true).append(true).open(&path)?;
    curl.write_function(move |data| {
        if let Err(e) = file.write_all(data) {
            eprint!("{}: {}", "error".red().bold(), &e);
            process::exit(-1);
        }
        Ok(data.len())
    })?;
    curl.perform()?;
    Ok(())
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1