pub struct UploadStream<A> { /* private fields */ }Expand description
What a streaming upload’s handler receives: the arguments, then the files one at a time, each in chunks as they arrive.
RouterExt::upload_stream hands one to its handler, which keeps no file
in memory unless it collects the chunks itself. The arguments are read
before the handler runs, because the runtime sends them as the first part
of the body. The limit of the Upload holds while the handler reads:
past it, the read fails with a RequestError
whose status is 413 Payload Too Large, which the handler can return as
its error.
§Examples
A handler that counts the bytes of each file without holding one in memory. Writing each chunk to a file works the same way.
use axum::Router;
use hypersig::{Patches, RequestError, RouterExt, Signals, Upload, UploadStream};
use serde::{Deserialize, Serialize};
#[derive(Signals, Serialize, Deserialize)]
struct Library {
received: u64,
}
const VIDEO: Upload<Library> = Upload::post("/video").max_bytes(512 * 1024 * 1024);
async fn receive((): (), mut upload: UploadStream<()>) -> Result<Patches<Library>, RequestError> {
let mut received = 0;
while let Some(mut file) = upload.next_file().await? {
while let Some(chunk) = file.chunk().await? {
received += chunk.len() as u64;
}
}
Ok(Library::received().patch(received).into())
}
let _app: Router = Router::new().upload_stream(VIDEO, receive);Implementations§
Source§impl<A> UploadStream<A>
impl<A> UploadStream<A>
Sourcepub async fn next_file(
&mut self,
) -> Result<Option<StreamedFile<'_>>, RequestError>
pub async fn next_file( &mut self, ) -> Result<Option<StreamedFile<'_>>, RequestError>
The next file, in the order the visitor picked them, or None after
the last one.
The part of the previous file that was not read is skipped, and so is
a part other than a file, as RouterExt::upload
skips it.
§Errors
Returns a RequestError when the body is
malformed or longer than the upload’s limit.