Last active
June 28, 2023 14:52
-
-
Save simmons/6c2e6eb3ade5bfcb962250603dd667cf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate multipart; | |
extern crate reqwest; | |
use multipart::client::lazy::Multipart; | |
use reqwest::mime; | |
use std::process; | |
use std::io::Read; | |
const URL: &'static str = "http://example.com/fileupload"; | |
const UPLOAD_FORM_FIELD_NAME: &'static str = "thefile"; | |
const FILENAME: &'static str = "sample.txt"; | |
/// This is example code for using the multipart crate with reqwest to | |
/// upload a file. The multipart crate is used to encode the file, and | |
/// the necessary headers/body are manually added to the reqwest | |
/// request. | |
/// | |
/// NOTE: Built-in multipart support in reqwest is pending, and this | |
/// example will be obsolete when that is available. | |
/// | |
/// NOTE: For simplicity, this example stores the entire encoded file in | |
/// memory. For anything but very small files, you'd want a streaming | |
/// approach instead. | |
fn main() { | |
// Construct a multipart description | |
let mut multipart = Multipart::new(); | |
multipart.add_file(UPLOAD_FORM_FIELD_NAME, FILENAME); | |
let mut multipart_prepared = multipart.prepare().unwrap(); | |
let mut multipart_buffer: Vec<u8> = vec![]; | |
multipart_prepared | |
.read_to_end(&mut multipart_buffer) | |
.unwrap(); | |
// Compose a request | |
let client = reqwest::Client::new().unwrap(); | |
let requestbuilder = client | |
.post(&String::from(URL)) | |
.header(reqwest::header::ContentType(mime::Mime( | |
mime::TopLevel::Multipart, | |
mime::SubLevel::FormData, | |
vec![ | |
( | |
mime::Attr::Ext(String::from("boundary")), | |
mime::Value::Ext( | |
String::from(multipart_prepared.boundary()), | |
) | |
), | |
], | |
))) | |
.body(multipart_buffer); | |
// Send request | |
let mut response = match requestbuilder.send() { | |
Ok(r) => r, | |
Err(e) => { | |
println!("error: {:?}", e); | |
process::exit(0); | |
} | |
}; | |
// Report | |
println!("status: {}", response.status()); | |
let mut response_data: Vec<u8> = vec![]; | |
response.read_to_end(&mut response_data).unwrap(); | |
println!( | |
"response:\n{}", | |
std::str::from_utf8(&response_data).unwrap() | |
); | |
} |
Hi,
Sorry, I don't have an async upload example. And even this sync code is really old. The technique it outlines may not be needed any more.
Just posting here in case someone needs an async solution (like me). The code is inspired by this conversation
// reqwest = { version = "0.11", features = ["multipart"] }
use reqwest::multipart::Part;
async fn upload_file() -> Result<(), Box<dyn std::error::Error>> {
let content: Vec<u8> = tokio::fs::read("path/to/file").await?;
let part = Part::bytes(content).file_name("file_name.extension");
let file = reqwest::multipart::Form::new().part("field_name", part);
let response = reqwest::Client::new()
.post("api/endpoint")
.multipart(file)
.send()
.await?;
println!("Status: {}", response.status());
println!("Headers:\n{:#?}", response.headers());
println!("Body:\n{}", response.text().await?);
Ok(())
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello, do you have an example with async support? Thank you very much for the good work