Skip to main content

Module upload

Module upload 

Source
Expand description

Streaming request bodies

By default a request body is read completely into memory (bounded by App::max_body_size) before the handler runs. That is right for JSON, wrong for a 2 GB upload. Routes registered with App::stream_body skip the buffering: the handler pulls the body piece by piece with Request::body_stream and can write it to disk while it arrives, with a limit that is enforced as the bytes come in.

use ullun::prelude::*;

App::new()
    // up to 5 GiB for this prefix; memory use stays at a few chunks
    .stream_body("/upload", Some(5 << 30))
    .put("/upload/{name}", |mut req: Request| async move {
        let name = req.params.get("name")?.to_string();
        let mut body = req.body_stream()?;
        let bytes = body.save_to(format!("/var/data/{name}.part")).await?;
        Ok(Response::json(serde_json::json!({ "stored": bytes })))
    })
    .run("127.0.0.1:3000")
    .await
    .unwrap();

Anything that needs the whole body (Request::json, form, multipart) sees an empty body on a streaming route; choose per prefix. Validate names and paths yourself: the stream only moves bytes.

Structsยง

BodyStream
A request body that is read in pieces, see the module documentation