1

I'm trying to do a POST request using reqwest. I need to send attachments in my request. I am looking for the equivalent of

curl -F attachment=@file.txt

In older versions (see here) it was as simple as

let file = fs::File::open("much_beauty.png")?;
let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
    .headers(construct_headers())
    .body(file)
    .send()?;

But for newer versions (see here) looks like the functionality has been removed. I get the error:

21 |         .body(file)
   |          ^^^^ the trait `From<File>` is not implemented for `Body`
   |
   = help: the following implementations were found:
             <Body as From<&'static [u8]>>
             <Body as From<&'static str>>
             <Body as From<Response>>
             <Body as From<String>>
           and 2 others
   = note: required because of the requirements on the impl of `Into<Body>` for `File`

Despite the official documentation claiming

The basic one is by using the body() method of a RequestBuilder. This lets you set the exact raw bytes of what the body should be. It accepts various types, including String, Vec<u8>, and File.

pretzelhammer
  • 13,874
  • 15
  • 47
  • 98
  • 1
    I have recently [filed an issue](https://github.com/seanmonstar/reqwest/issues/1149) regarding the this part of documentation. – justinas Feb 14 '21 at 13:01

1 Answers1

2

The new API may not implement From<File> for Body anymore but does implement From<Vec<u8>> for Body and we can easily convert a File into a Vec<u8>.

In fact, there's already a handy function in the standard library called std::fs::read which will read an entire file and store it in a Vec<u8>. Here's the updated working example:

let byte_buf: Vec<u8> = std::fs::read("much_beauty.png")?;
let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
    .headers(construct_headers())
    .body(byte_buf)
    .send()?;
pretzelhammer
  • 13,874
  • 15
  • 47
  • 98