-
Notifications
You must be signed in to change notification settings - Fork 321
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
multipart support #852
Comments
Hi, thanks for asking! Unfortunately we still don't support multipart because we need to author a multipart parser, as we found that there were no implementations in the ecosystem which could provide the guarantees we needed from a parser. You can track the progress of the issue here: http-rs/http-types#126 |
Just in case someone needs this, here is an option. Use multer, which is a multipart parser:
Copy this buffered stream implementaion: use async_std::io::{self, Read};
use async_std::stream::Stream;
use async_std::task::{Context, Poll};
use std::pin::Pin;
#[derive(Debug)]
pub struct BufferedBytesStream<T> {
inner: T,
}
impl<T: Read + Unpin> Stream for BufferedBytesStream<T> {
type Item = async_std::io::Result<Vec<u8>>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
let mut buf = [0u8; 2048];
let rd = Pin::new(&mut self.inner);
match futures_core::ready!(rd.poll_read(cx, &mut buf)) {
Ok(0) => Poll::Ready(None),
Ok(n) => Poll::Ready(Some(Ok(buf[..n].to_vec()))),
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => Poll::Pending,
Err(e) => Poll::Ready(Some(Err(e))),
}
}
} Parse the request headers out of the tide use use multer::Multipart;
let multipart_boudry = "".to_string()
if let Some(mime) = req.content_type() {
let content_type = mime.essence().to_string();
if content_type == "multipart/form-data" {
if let Some(boundry) = mime.param("boundary") {
multipart_boundry = boundry.to_string()
}
}
}
// use buffered stream on the request
let body_stream = BufferedBytesStream { inner: req };
let mut multipart = Multipart::new(body_stream, multipart_boundry.clone());
// download a file fromt the field "file" in the multipart request.
let download_file = "/some_path/";
while let Some(mut field) = multipart.next_field().await? {
if field.name() != Some("file") {
continue;
}
let mut output = File::create(&download_file).await?;
while let Some(chunk) = field.chunk().await? {
output.write_all(&chunk).await?;
}
output.flush().await?;
} |
I wonder if a BufferedByteStream could be added to asnyc-std like I initially used a wrapped The streams |
In the meantime, would it make sense to update It's really easy to accidentally get a form in multipart format if sending data from JS, because |
I just ran into this while porting my Flask app to Tide. I agree that the docs should really have some indication of this restriction as it would have saved me a lot of debugging. |
Hi, I see example link (Multipart Form) here https://crates.io/crates/tide/0.1.1 are broken.
Is there any workaround?
There was a fix, #47
But it seems to be reverted.
Thanks!
The text was updated successfully, but these errors were encountered: