Skip to main content

Multipart

Handling file uploads

Actix 4.9+ 8 min readAdvanced Topic

# Multipart

File uploads use the multipart/form-data content type. Handling this involves streaming the request body and parsing the distinct parts (fields and files).

#actix-multipart

Actix Web doesn't include multipart parsing in the core framework; you must use the actix-multipart crate.

code_blockstoml
[dependencies]
actix-web = "4"
actix-multipart = "0.6"
futures-util = "0.3"

#Processing a Stream

Multipart data is asynchronous and stream-based. You iterate over a Multipart stream, getting Field objects.

code_blocksrust
use actix_multipart::Multipart;
use actix_web::{post, HttpResponse, Error};
use futures_util::stream::StreamExt as _;

#[post("/upload")]
async fn upload(mut payload: Multipart) -> Result<HttpResponse, Error> {
    while let Some(item) = payload.next().await {
        let mut field = item?;
        println!("Field Name: {}", field.name());
        
        // Read chunks
        while let Some(chunk) = field.next().await {
            let data = chunk?;
            // Save data to file...
        }
    }
    Ok(HttpResponse::Ok().into())
}

Was this page helpful?

Reference Implementation

The following code snippet demonstrates the authoritative pattern for this documentation.

src/main.rs
1use actix_multipart::Multipart;
2use actix_web::{post, App, HttpServer, HttpResponse, Error};
3use futures_util::stream::StreamExt as _;
4
5#[post("/upload")]
6async fn upload(mut payload: Multipart) -> Result<HttpResponse, Error> {
7 while let Some(item) = payload.next().await {
8 let field = item?;
9 println!("Received field: {}", field.name());
10 }
11 Ok(HttpResponse::Ok().body("Upload processed"))
12}
13
14#[actix_web::main]
15async fn main() -> std::io::Result<()> {
16 HttpServer::new(|| App::new().service(upload))
17 .bind(("127.0.0.1", 8080))?
18 .run()
19 .await
20}
Was this page helpful?