actix_easy_multipart/
bytes.rs

1//! Reads a field into memory.
2use crate::{field_mime, Error, FieldReader, Limits};
3use actix_multipart::Field;
4use actix_web::HttpRequest;
5use bytes::BytesMut;
6use futures_core::future::LocalBoxFuture;
7use futures_util::{FutureExt, TryStreamExt};
8use mime::Mime;
9
10/// Read the field into memory.
11#[derive(Debug)]
12pub struct Bytes {
13    /// The data.
14    pub data: bytes::Bytes,
15    /// The value of the `content-type` header.
16    pub content_type: Option<Mime>,
17    /// The `filename` value in the `content-disposition` header.
18    pub file_name: Option<String>,
19}
20
21impl<'t> FieldReader<'t> for Bytes {
22    type Future = LocalBoxFuture<'t, Result<Self, Error>>;
23
24    fn read_field(_: &'t HttpRequest, mut field: Field, limits: &'t mut Limits) -> Self::Future {
25        async move {
26            let mut data = BytesMut::new();
27            while let Some(chunk) = field.try_next().await? {
28                limits.try_consume_limits(chunk.len(), true)?;
29                data.extend(chunk);
30            }
31            Ok(Bytes {
32                data: data.freeze(),
33                content_type: field_mime(&field),
34                file_name: field
35                    .content_disposition()
36                    .get_filename()
37                    .map(str::to_owned),
38            })
39        }
40        .boxed_local()
41    }
42}