From e2a54e62d1c3f135f119295b72bd9c9f0e0e4a97 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Fri, 13 Nov 2020 14:52:53 +0100 Subject: [PATCH] Mock-up for a multipart client implementation --- actix-multipart/Cargo.toml | 3 ++ actix-multipart/src/client.rs | 52 +++++++++++++++++++++++++++++++++++ actix-multipart/src/lib.rs | 1 + 3 files changed, 56 insertions(+) create mode 100644 actix-multipart/src/client.rs diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index e2e9dbf14..8c6b060eb 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -18,13 +18,16 @@ path = "src/lib.rs" [dependencies] actix-web = { version = "3.0.0", default-features = false } actix-service = "1.0.6" +actix-http = "2.1.0" actix-utils = "2.0.0" bytes = "0.5.3" derive_more = "0.99.2" httparse = "1.3" +futures = { version = "0.3.5", default-features = false } futures-util = { version = "0.3.5", default-features = false } log = "0.4" mime = "0.3" +rand = "0.7" twoway = "0.2" [dev-dependencies] diff --git a/actix-multipart/src/client.rs b/actix-multipart/src/client.rs new file mode 100644 index 000000000..75614da66 --- /dev/null +++ b/actix-multipart/src/client.rs @@ -0,0 +1,52 @@ +//! Multipart payload support for Actix Web Client + +use bytes::Bytes; +use futures::prelude::*; + +pub struct Form<'a> { + boundary: String, + fields: Vec>, +} + +/// A field in a multipart Form +pub struct Field<'a> { + inner: FieldInner<'a>, + content_type: String, + content_length: Option, +} + +impl<'a> Default for Form<'a> { + fn default() -> Self { + use rand::{distributions::Alphanumeric, thread_rng, Rng}; + let rng = thread_rng(); + + Self::with_boundary(rng.sample_iter(&Alphanumeric).take(60).collect()) + } +} + +impl<'a> Form<'a> { + /// Constructs a new multipart Form with a specific boundary. + /// + /// If you do not want to manually construct a boundary, use `Form::default()`. + pub fn with_boundary(boundary: String) -> Self { + Form { + boundary, + fields: Vec::new(), + } + } + + pub fn add_stream(&mut self, content_type: String, content: S) + where + S: Stream> + 'a, + { + self.fields.push(Field { + inner: FieldInner::Stream(Box::new(content)), + content_type, + content_length: None, // XXX + }) + } +} + +enum FieldInner<'a> { + Stream(Box> + 'a>), +} diff --git a/actix-multipart/src/lib.rs b/actix-multipart/src/lib.rs index 46dd0ee9b..9431c9ce9 100644 --- a/actix-multipart/src/lib.rs +++ b/actix-multipart/src/lib.rs @@ -3,6 +3,7 @@ #![deny(rust_2018_idioms)] #![allow(clippy::borrow_interior_mutable_const)] +pub mod client; mod error; mod extractor; mod server;