From d7d4392d87719d397d0a0e9e0a1bb1a6386a0b54 Mon Sep 17 00:00:00 2001 From: Cameron Dershem Date: Wed, 26 Jun 2019 01:27:17 -0400 Subject: [PATCH] Requests is done-ish. --- content/docs/request.md | 26 ++++++++++---------- examples/requests/Cargo.toml | 1 + examples/requests/src/main.rs | 9 +++++-- examples/requests/src/manual.rs | 8 ++++++- examples/requests/src/streaming.rs | 35 +++++++++++++++++---------- examples/requests/src/urlencoded.rs | 37 +++++++++++++++-------------- 6 files changed, 69 insertions(+), 47 deletions(-) diff --git a/content/docs/request.md b/content/docs/request.md index 31962f4..f2cfcec 100644 --- a/content/docs/request.md +++ b/content/docs/request.md @@ -6,7 +6,7 @@ weight: 200 # Content Encoding -Actix automatically *decompresses* payloads. The following codecs are supported: +Actix-web automatically *decompresses* payloads. The following codecs are supported: * Brotli * Chunked @@ -42,29 +42,24 @@ body first and then deserialize the json into an object. # Chunked transfer encoding -Actix automatically decodes *chunked* encoding. `HttpRequest::payload()` already contains -the decoded byte stream. If the request payload is compressed with one of the supported -compression codecs (br, gzip, deflate), then the byte stream is decompressed. +Actix automatically decodes *chunked* encoding. The [`web::Payload`][payloadextractor] +extractor already contains the decoded byte stream. If the request payload is compressed +with one of the supported compression codecs (br, gzip, deflate), then the byte stream +is decompressed. # Multipart body -Actix provides multipart stream support. -[*Multipart*][multipartstruct] is implemented as a stream of multipart items. Each item -can be a [*Field*][fieldstruct] or a nested *Multipart* stream.`HttpResponse::multipart()` -returns the *Multipart* stream for the current request. +Actix provides multipart stream support with an external crate, [`actix-multipart`][multipartcrate]. The following demonstrates multipart stream handling for a simple form: -{{< include-example example="requests" file="multipart.rs" section="multipart" >}} - > A full example is available in the [examples directory][multipartexample]. # Urlencoded body -Actix provides support for *application/x-www-form-urlencoded* encoded bodies. -`HttpResponse::urlencoded()` returns a [*UrlEncoded*][urlencoder] future, which resolves -to the deserialized instance. The type of the instance must implement the `Deserialize` -trait from *serde*. +Actix-web provides support for *application/x-www-form-urlencoded* encoded bodies with +the [`web::Form`][urlencoded] extractor which resolves to the deserialized instance. The +type of the instance must implement the `Deserialize` trait from *serde*. The *UrlEncoded* future can resolve into an error in several cases: @@ -89,3 +84,6 @@ In the following example, we read and print the request payload chunk by chunk: [fieldstruct]: ../../actix-web/actix_web/multipart/struct.Field.html [multipartexample]: https://github.com/actix/examples/tree/master/multipart/ [urlencoder]: ../../actix-web/actix_web/dev/struct.UrlEncoded.html +[payloadextractor]: https://docs.rs/actix-web/1.0.2/actix_web/web/struct.Payload.html +[multipartcrate]: https://crates.io/crates/actix-multipart +[urlencoded]:Jhttps://docs.rs/actix-web/1.0.2/actix_web/web/struct.Form.html diff --git a/examples/requests/Cargo.toml b/examples/requests/Cargo.toml index cc4ba8d..4d26310 100644 --- a/examples/requests/Cargo.toml +++ b/examples/requests/Cargo.toml @@ -9,3 +9,4 @@ serde_json = "1.0" actix-web = "1.0" futures = "0.1" bytes = "0.4" +actix-multipart = "0.1" diff --git a/examples/requests/src/main.rs b/examples/requests/src/main.rs index b44e0bd..7d822e2 100644 --- a/examples/requests/src/main.rs +++ b/examples/requests/src/main.rs @@ -3,8 +3,9 @@ pub mod manual; pub mod multipart; pub mod streaming; pub mod urlencoded; + // -use actix_web::{web, App, Result}; +use actix_web::{web, App, HttpServer, Result}; use serde::Deserialize; #[derive(Deserialize)] @@ -18,6 +19,10 @@ fn index(info: web::Json) -> Result { } fn main() { - App::new().route("/index.html", web::post().to(index)); + HttpServer::new(|| App::new().route("/", web::post().to(index))) + .bind("127.0.0.1:8088") + .unwrap() + .run() + .unwrap(); } // diff --git a/examples/requests/src/manual.rs b/examples/requests/src/manual.rs index a850b0e..44eeefc 100644 --- a/examples/requests/src/manual.rs +++ b/examples/requests/src/manual.rs @@ -43,5 +43,11 @@ pub fn index_manual( // pub fn main() { - App::new().route("/", web::post().to_async(index_manual)); + use actix_web::HttpServer; + + HttpServer::new(|| App::new().route("/", web::post().to_async(index_manual))) + .bind("127.0.0.1:8088") + .unwrap() + .run() + .unwrap(); } diff --git a/examples/requests/src/streaming.rs b/examples/requests/src/streaming.rs index 6444171..a219d4a 100644 --- a/examples/requests/src/streaming.rs +++ b/examples/requests/src/streaming.rs @@ -1,15 +1,26 @@ // -// use actix_web::{error, web, Error, HttpResponse}; -// use futures::{future::result, Future, Stream}; +use actix_web::{error, web, Error, HttpResponse}; +use futures::{future::result, Future, Stream}; -// pub fn index(payload: web::Payload) -> Box> { -// payload -// .from_err() -// .fold((), |_, chunk| { -// println!("Chunk: {:?}", chunk); -// result::<_, error::PayloadError>(Ok(())) -// }) -// .map(|_| HttpResponse::Ok().finish()) -// .responder() -// } +pub fn index(payload: web::Payload) -> Box> { + Box::new( + payload + .from_err() + .fold((), |_, chunk| { + println!("Chunk: {:?}", chunk); + result::<_, error::PayloadError>(Ok(())) + }) + .map(|_| HttpResponse::Ok().into()), + ) +} // + +pub fn main() { + use actix_web::{App, HttpServer}; + + HttpServer::new(|| App::new().route("/", web::post().to_async(index))) + .bind("127.0.0.1:8088") + .unwrap() + .run() + .unwrap(); +} diff --git a/examples/requests/src/urlencoded.rs b/examples/requests/src/urlencoded.rs index 5e64efb..211c5a6 100644 --- a/examples/requests/src/urlencoded.rs +++ b/examples/requests/src/urlencoded.rs @@ -1,22 +1,23 @@ // -// use actix_web::{Error, HttpRequest, HttpResponse}; -// use futures::future::{ok, Future}; -// use serde::Deserialize; +use actix_web::{web, HttpResponse}; +use serde::Deserialize; -// #[derive(Deserialize)] -// struct FormData { -// username: String, -// } +#[derive(Deserialize)] +struct FormData { + username: String, +} -// fn index(req: &HttpRequest) -> Box> { -// req.urlencoded::() // <- get UrlEncoded future -// .from_err() -// .and_then(|data| { -// // <- deserialized instance -// println!("USERNAME: {:?}", data.username); -// ok(HttpResponse::Ok().into()) -// }) -// .responder() -// } +fn index(form: web::Form) -> HttpResponse { + HttpResponse::Ok().body(format!("username: {}", form.username)) +} // -pub fn main() {} + +pub fn main() { + use actix_web::{App, HttpServer}; + + HttpServer::new(|| App::new().route("/", web::post().to(index))) + .bind("127.0.0.1:8088") + .unwrap() + .run() + .unwrap(); +}