-
-
Notifications
You must be signed in to change notification settings - Fork 709
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Form error in 0.3.4 but not in 0.3.3 #1034
Comments
There's a proposal to move to |
@ChristophHess running the other PR on this code: use futures_util::StreamExt;
use warp::Filter;
use warp::multipart::FormData;
#[tokio::main]
async fn main() {
let route = warp::path!("some_path")
.and(warp::multipart::form().max_length(1_000_000))
.and_then(|mut b: FormData| async move {
let r = b.next().await.unwrap().unwrap();
Ok::<_, warp::Rejection>(format!("{:?}", r))
});
warp::serve(route).run(([127, 0, 0, 1], 3030)).await;
} I get this:
Does that cover your usecase ? |
I got the same error as in the first post
and got an error
this way of reading solved the issue
now I read the form like this
Thank you |
@azecm when running the same on multer's branch i see that it fails with Instead of: use futures_util::{StreamExt, TryStreamExt};
use warp::Filter;
use warp::multipart::FormData;
#[tokio::main]
async fn main() {
let route = warp::multipart::form()
.and_then(|mut b: FormData| async move {
let field_names: Vec<_> = b.try_collect().await.unwrap();
Ok::<_, warp::Rejection>(format!("{:?}", field_names))
});
warp::serve(route).run(([0,0,0,0], 3030)).await;
} one would do use futures_util::{StreamExt, TryStreamExt};
use warp::Filter;
use warp::multipart::FormData;
#[tokio::main]
async fn main() {
let route = warp::multipart::form()
.and_then(|mut b: FormData| async move {
let field_names: Vec<_> = b.and_then(|field| async move {
Ok(field.name().to_string())
}).try_collect().await.unwrap();
Ok::<_, warp::Rejection>(format!("{:?}", field_names))
});
warp::serve(route).run(([0,0,0,0], 3030)).await;
} But, only if that gets merged into warp. |
text fields i was able to read part.data().await now I get only the initial part |
figured out it's even better now great for large files
|
@seanmonstar @jaysonsantos Terribly sorry for the delayed reply. I just tested the "use-multer-for-multipart" branch with my build system and it worked perfectly. Thank you both very much. |
So the UPDATE: I ended up wrapping the result with Ok() and nesting a result inside the returned Vec, then iterating through them later after the let results: Vec<Result<(), anyhow::Error>> = form.and_then(|part| async move {
Ok(process_form_parts(part).await)
})
.try_collect()
.await
.map_err(|e| {
error!("failed to collect multipart form data: {}", e);
warp::reject::reject()
})?;
for result in results {
if let Err(e) = result {
return Ok(Box::new(warp::reply::with_status(e.to_string(), StatusCode::BAD_REQUEST)))
}
}
Ok(Box::new(warp::reply::with_status("files uploaded".to_string(), StatusCode::OK))) |
Also revise the upload endpoint to be in lign with the new multipart request handler in warp. For more details see seanmonstar/warp#1034.
I'm in the same situation and am stuck, if someone could assist with some guidance that would be much appreciated. I was running warp This was the original code: let result: Result<Vec<Part>, ()> = data.try_collect().await.map_err(|e| {
eprintln!("form error: {}", e);
}); I have tried changing to the following code but I am still getting the let result: Result<Vec<Part>, ()> = data
.and_then(|part| async move {
println!("part: {:?}"part);
Ok(part)
})
.try_collect()
.await
.map_err(|e| {
eprintln!("form error: {}", e);
}); |
@nocker01 that is because multer does not allow multiple instances of multipart data to exist as it tries to avoid copying data over, as you want to do something with the data, it is better if you get the info you need from that and then collect (by discarding the original part), the example here shows that #1034 (comment) |
Thank you @jaysonsantos , I did try your suggestion from above like this: let result: Result<Vec<Part>, ()> = data
.and_then(|part| async move {
println!("part: {:?}", part);
Ok(part.name().to_string())
})
.try_collect()
.await
.map_err(|e| {
eprintln!("form error: {}", e);
}); but that does not compile, I get the following compilation error:
because I am trying to end up with a I will keep trying to see what I can do. |
@nocker01 I think that happens because you are still asking for a |
Thank you. I've got it working again now. This was my original implementation when using warp use futures::TryStreamExt;
use warp::multipart::{FormData, Part};
let result: Result<Vec<Part>, ()> = form_data.try_collect().await.map_err(|_| {});
if let Ok(parts) = result {
for p in parts {
let p_name = p.name().to_string();
let p_filename = p.filename().unwrap_or_default().to_string();
let value = p
.stream()
.try_fold(Vec::new(), |mut vec, data| {
vec.put(data);
async move { Ok(vec) }
})
.await;
// Handle each of the Parts...
}
} And this is my implementation using warp use futures::{StreamExt, TryStreamExt};
use warp::multipart::FormData;
// Extract the parts from the stream of multipart/form-data
let mut data = form_data
.fold(post_data, |mut post_data, part| {
async move {
if let Ok(p) = part {
let p_name = p.name().to_string();
let p_filename = p.filename().unwrap_or_default().to_string();
let value = p
.stream()
.try_fold(Vec::new(), |mut vec, data| {
vec.put(data);
async move { Ok(vec) }
})
.await;
// Handle each of the Parts...
post_data
}
})
.await; |
Version
warp:
0.3.4
rustc:
1.68.2
Platform
Linux fedora 6.2.8-200.fsync.fc37.x86_64
Also on Docker -> Debian
Description
When running the latest version with the multipart update, I am getting an Error when making a request at an endpoint like such:
this results in:
form error: Tried to poll data from the not last Part
request body already taken in previous filter
When I simply downgrade to
0.3.3
this bug disappears.The text was updated successfully, but these errors were encountered: