Reputation: 117
I am trying to build a simple web server to upload and save images using Rust. Here is my code:
use std::convert::Infallible;
use std::path::PathBuf;
use warp::multipart::FormData;
use warp::{http::StatusCode, Filter};
use futures::stream::TryStreamExt;
#[tokio::main]
async fn main() {
let upload_route = warp::path("upload")
.and(warp::post())
.and(warp::multipart::form().max_length(3 * 1024 * 1024))
.and_then(upload_handler);
let hello_route = warp::path!("hello")
.and(warp::get())
.and(warp::fs::file("./static/index.html"));
let routes = upload_route.or(hello_route);
println!("Server started at http://localhost:8080");
warp::serve(routes).run(([127, 0, 0, 1], 8080)).await;
}
async fn upload_handler(mut form: FormData) -> Result<impl warp::Reply, Infallible> {
while let Ok(Some(part)) = form.try_next().await {
let filename = match part.filename() {
Some(filename) => filename.to_string(),
None => return Ok(StatusCode::BAD_REQUEST),
};
println!("Receiving file: {}", filename);
let mut data = Vec::new();
let mut stream = part.stream();
while let Ok(Some(chunk)) = stream.try_next().await {
data.extend_from_slice(&chunk);
}
let save_path = PathBuf::from(format!("./uploads/{}", filename));
if let Err(_) = tokio::fs::write(save_path, data).await {
return Ok(StatusCode::INTERNAL_SERVER_ERROR);
}
}
Ok(StatusCode::CREATED)
}
My problem is in line data.extend_from_slice(&chunk);
:
expected `&[_]`, found `&impl Buf`
I am not exactly sure what [_]
means and why data.extend_from_slice
does not accept the chunk
bytes.
Upvotes: 0
Views: 437
Reputation: 12812
You can use reader
to create an implementer of Read
, and then call read_to_end
.
while let Ok(Some(mut chunk)) = stream.try_next().await {
chunk.reader().read_to_end(&mut data).unwrap();
}
The issue with chunk
is that it doesn't have to return the entire buffer.
Note that this can return shorter slice
If you want to use chunk
, you have to loop until remaining
is zero.
while let Ok(Some(mut chunk)) = stream.try_next().await {
while chunk.remaining() > 0 {
let slice: &[u8] = chunk.chunk();
data.extend_from_slice(slice);
chunk.advance(slice.len());
}
}
Upvotes: 1
Reputation: 117
I was able to address this type error using the Buf chunk
method like so
while let Ok(Some(mut chunk)) = stream.try_next().await {
let slice: &[u8] = chunk.chunk();
data.extend_from_slice(slice);
chunk.advance(slice.len());
}
Upvotes: 0