Search code examples
rustzipreqwest

Rust download and save ZIP file


I'm trying to download and save a Zip file. It seems like the download is working, but the saving goes wrong. If I try to unzip the file, I get the following error:

Archive:  download.zip
error [download.zip]:  missing 3208647056 bytes in zipfile
  (attempting to process anyway)
error [download.zip]:  attempt to seek before beginning of zipfile
  (please check that you have transferred or created the zipfile in the
  appropriate BINARY mode and that you have compiled UnZip properly)

Here's the code I'm using:

cargo.toml


# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
reqwest = { version = "0.10"}
tokio = { version = "0.2", features = ["full"] }
error-chain = "0.12.2"

src/main.rs

use error_chain::error_chain;
use std::path::Path;
use std::fs::File;
use std::io::prelude::*;

error_chain! {
     foreign_links {
         Io(std::io::Error);
         HttpRequest(reqwest::Error);
     }
}

#[tokio::main]
async fn main() -> Result<()> {
    let target = "https://github.com/twbs/bootstrap/archive/v4.0.0.zip";
    let response = reqwest::get(target).await?;

    let path = Path::new("./download.zip");

    let mut file = match File::create(&path) {
        Err(why) => panic!("couldn't create {}", why),
        Ok(file) => file,
    };
    let content =  response.text().await?;
    file.write_all(content.as_bytes())?;
    Ok(())
}

Can anyone help me please?


Solution

  • The reqwest::Response::text will try to parse the body of your request and replace any invalid UTF-8 sequence with REPLACEMENT CHARACTER. For binary files, this will result in a corrupted file.

    Instead you need to use reqwest::Response::bytes which returns the content as-is.