pub struct MultipartStream { /* private fields */ }Expand description
An incremental multipart/form-data parser.
Consumes the request body, so it must be the last handler argument. Fields
arrive one at a time from next_field, and each field’s
content is read with Field::chunk or collected with Field::bytes.
use churust_core::{Churust, MultipartStream, TestClient};
let app = Churust::server()
.routing(|r| {
r.post("/upload", |mut form: MultipartStream| async move {
let mut total = 0usize;
while let Some(mut field) = form.next_field().await? {
// A real handler would write each chunk to disk here.
while let Some(chunk) = field.chunk().await? {
total += chunk.len();
}
}
Ok::<_, churust_core::Error>(format!("{total} bytes"))
});
})
.build();
let body = "--X\r\nContent-Disposition: form-data; name=\"doc\"; filename=\"a.txt\"\r\n\r\nhello\r\n--X--\r\n";
let res = TestClient::new(app)
.post("/upload")
.header("content-type", "multipart/form-data; boundary=X")
.body(body)
.send()
.await;
assert_eq!(res.text(), "5 bytes");Implementations§
Source§impl MultipartStream
impl MultipartStream
Sourcepub fn max_field_bytes(self, bytes: usize) -> Self
pub fn max_field_bytes(self, bytes: usize) -> Self
Cap what Field::bytes will collect (default 8 MiB).
Only affects collecting. Field::chunk is unbounded on purpose: a
handler streaming to disk is choosing its own ceiling, and the framework
has no way to know what it is.
Sourcepub async fn next_field(&mut self) -> Result<Option<Field<'_>>>
pub async fn next_field(&mut self) -> Result<Option<Field<'_>>>
The next field, or None at the end of the body.
A field that was not read to the end is discarded first, so a handler may skip a part it does not want without leaving the parser mid-stream.
§Errors
If the body is malformed, ends early, exceeds the part count, or the underlying body stream fails, which includes the per-route body cap being crossed.