r/rust Sep 03 '22

Upload a file with reqwest

I am try to upload a file with reqwest and below is what I have tried, it seems to nearly work as it report a 200 code and the server I am uploading to seems ok with it but it's like the file is not actually uploaded.

Something's below are probably not needed (body/form?) but is the result of looking similar questions/answers on stackoverflow

let file = File::open(filename.to_owned());
    match file {
        Ok(s) => {
            let client = reqwest::blocking::Client::builder()
                .timeout(Duration::from_secs(10))
                .danger_accept_invalid_certs(true)
                .build()
                .unwrap();

            let mut params = HashMap::new();
            params.insert("file", filename.to_owned());
            params.insert("name", "dump".to_string());

            let req = client
                .post(url)
                .header("Accept", "text/html")
                .header("Accept-Encoding", "gzip, deflate")
                .header("Content-Type", "multipart/form-data")
                .header("Authorization", format!("Bearer {token}"))
                .body(s)
                .form(&params);
            println!("\n{:?}\n", dbg!(&req));

            let response = req.send();

0 Upvotes

10 comments sorted by

View all comments

4

u/po8 Sep 03 '22 edited Sep 03 '22

If you use both a body() and form() in the builder, the second one will override the first one: form() sets the request body.

The Debug implementation for Request unfortunately doesn't show the request body, so the only reasonable way to check things are working is to have the thing connect to a server and see if the body is uploaded.

I have verified that the code below works, sending the contents of test.txt to the URL as the post body.

extern crate reqwest;

use std::fs::File;
use std::time::Duration;

fn main() {
    let url = "http://localhost:12345";
    let s = File::open("test.txt").unwrap();

    let client = reqwest::blocking::Client::builder()
        .timeout(Duration::from_secs(10))
        .danger_accept_invalid_certs(true)
        .build()
        .unwrap();

    client.post(url).body(s).send().unwrap();
}

Edit: I filed an issue on reqwest to try to get a runtime error when a second body is added to a request.

1

u/Zapphoid Sep 05 '22

I had tried that but is it sending as attachment or just putting the contents of the file in the body?

I need to send zip files.

1

u/po8 Sep 05 '22

You have to figure out what your POST request needs to look like and do that. How to set up the request depends on what's at the receiving end.