diff --git a/content/docs/request.md b/content/docs/request.md index ad71c29..1843bf7 100644 --- a/content/docs/request.md +++ b/content/docs/request.md @@ -78,10 +78,10 @@ In the following example, we read and print the request payload chunk by chunk: {{< include-example example="requests" file="streaming.rs" section="streaming" >}} [examples]: https://github.com/actix/examples/tree/master/json/ -[multipartstruct]: https://docs.rs/actix-multipart/0.1.2/actix_multipart/struct.Multipart.html -[fieldstruct]: https://docs.rs/actix-multipart/0.1.2/actix_multipart/struct.Field.html +[multipartstruct]: https://docs.rs/actix-multipart/0.2/actix_multipart/struct.Multipart.html +[fieldstruct]: https://docs.rs/actix-multipart/0.2/actix_multipart/struct.Field.html [multipartexample]: https://github.com/actix/examples/tree/master/multipart/ -[urlencoded]: https://docs.rs/actix-web/1.0.2/actix_web/dev/struct.UrlEncoded.html -[payloadextractor]: https://docs.rs/actix-web/1.0.2/actix_web/web/struct.Payload.html +[urlencoded]: https://docs.rs/actix-web/2/actix_web/dev/struct.UrlEncoded.html +[payloadextractor]: https://docs.rs/actix-web/2/actix_web/web/struct.Payload.html [multipartcrate]: https://crates.io/crates/actix-multipart -[formencoded]:Jhttps://docs.rs/actix-web/1.0.2/actix_web/web/struct.Form.html +[formencoded]:Jhttps://docs.rs/actix-web/2/actix_web/web/struct.Form.html diff --git a/examples/requests/Cargo.toml b/examples/requests/Cargo.toml index 4d26310..3e3a598 100644 --- a/examples/requests/Cargo.toml +++ b/examples/requests/Cargo.toml @@ -6,7 +6,8 @@ edition = "2018" [dependencies] serde = "1.0" serde_json = "1.0" -actix-web = "1.0" -futures = "0.1" +actix-web = "2.0" +actix-rt = "1.0" +futures = "0.3.1" bytes = "0.4" -actix-multipart = "0.1" +actix-multipart = "0.2" diff --git a/examples/requests/src/main.rs b/examples/requests/src/main.rs index 7d822e2..c6a0c1f 100644 --- a/examples/requests/src/main.rs +++ b/examples/requests/src/main.rs @@ -14,15 +14,15 @@ struct Info { } /// extract `Info` using serde -fn index(info: web::Json) -> Result { +async fn index(info: web::Json) -> Result { Ok(format!("Welcome {}!", info.username)) } -fn main() { +#[actix_rt::main] +async fn main() -> std::io::Result<()> { HttpServer::new(|| App::new().route("/", web::post().to(index))) - .bind("127.0.0.1:8088") - .unwrap() + .bind("127.0.0.1:8088")? .run() - .unwrap(); + .await } // diff --git a/examples/requests/src/manual.rs b/examples/requests/src/manual.rs index 44eeefc..dade24c 100644 --- a/examples/requests/src/manual.rs +++ b/examples/requests/src/manual.rs @@ -1,7 +1,7 @@ // use actix_web::{error, web, App, Error, HttpResponse}; use bytes::BytesMut; -use futures::{Future, Stream}; +use futures::StreamExt; use serde::{Deserialize, Serialize}; use serde_json; @@ -13,41 +13,30 @@ struct MyObj { const MAX_SIZE: usize = 262_144; // max payload size is 256k -pub fn index_manual( - payload: web::Payload, -) -> impl Future { +async fn index_manual(mut payload: web::Payload) -> Result { // payload is a stream of Bytes objects - payload - // `Future::from_err` acts like `?` in that it coerces the error type from - // the future into the final error type - .from_err() - // `fold` will asynchronously read each chunk of the request body and - // call supplied closure, then it resolves to result of closure - .fold(BytesMut::new(), move |mut body, chunk| { - // limit max size of in-memory payload - if (body.len() + chunk.len()) > MAX_SIZE { - Err(error::ErrorBadRequest("overflow")) - } else { - body.extend_from_slice(&chunk); - Ok(body) - } - }) - // `Future::and_then` can be used to merge an asynchronous workflow with a - // synchronous workflow - .and_then(|body| { - // body is loaded, now we can deserialize serde-json - let obj = serde_json::from_slice::(&body)?; - Ok(HttpResponse::Ok().json(obj)) // <- send response - }) + let mut body = BytesMut::new(); + while let Some(chunk) = payload.next().await { + let chunk = chunk?; + // limit max size of in-memory payload + if (body.len() + chunk.len()) > MAX_SIZE { + return Err(error::ErrorBadRequest("overflow")); + } + body.extend_from_slice(&chunk); + } + + // body is loaded, now we can deserialize serde-json + let obj = serde_json::from_slice::(&body)?; + Ok(HttpResponse::Ok().json(obj)) // <- send response } // -pub fn main() { +#[actix_rt::main] +async fn main() -> std::io::Result<()> { use actix_web::HttpServer; - HttpServer::new(|| App::new().route("/", web::post().to_async(index_manual))) - .bind("127.0.0.1:8088") - .unwrap() + HttpServer::new(|| App::new().route("/", web::post().to(index_manual))) + .bind("127.0.0.1:8088")? .run() - .unwrap(); + .await } diff --git a/examples/requests/src/streaming.rs b/examples/requests/src/streaming.rs index 9f4ab33..11c74c2 100644 --- a/examples/requests/src/streaming.rs +++ b/examples/requests/src/streaming.rs @@ -1,26 +1,24 @@ // use actix_web::{error, web, Error, HttpResponse}; -use futures::{future::result, Future, Stream}; +use futures::{Future, Stream, StreamExt}; -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()), - ) +async fn index(mut body: web::Payload) -> Result { + let mut bytes = web::BytesMut::new(); + while let Some(item) = body.next().await { + bytes.extend_from_slice(&item?); + } + + println!("Chunk: {:?}", bytes); + Ok(HttpResponse::Ok().finish()) } // -pub fn main() { +#[actix_rt::main] +async fn main() -> std::io::Result<()> { use actix_web::{App, HttpServer}; - HttpServer::new(|| App::new().route("/", web::post().to_async(index))) - .bind("127.0.0.1:8088") - .unwrap() + HttpServer::new(|| App::new().route("/", web::post().to(index))) + .bind("127.0.0.1:8088")? .run() - .unwrap(); + .await } diff --git a/examples/requests/src/urlencoded.rs b/examples/requests/src/urlencoded.rs index 211c5a6..1486308 100644 --- a/examples/requests/src/urlencoded.rs +++ b/examples/requests/src/urlencoded.rs @@ -7,17 +7,17 @@ struct FormData { username: String, } -fn index(form: web::Form) -> HttpResponse { +async fn index(form: web::Form) -> HttpResponse { HttpResponse::Ok().body(format!("username: {}", form.username)) } // -pub fn main() { +#[actix_rt::main] +async fn main() -> std::io::Result<()> { use actix_web::{App, HttpServer}; HttpServer::new(|| App::new().route("/", web::post().to(index))) - .bind("127.0.0.1:8088") - .unwrap() + .bind("127.0.0.1:8088")? .run() - .unwrap(); + .await }