1
0
mirror of https://github.com/actix/actix-website synced 2024-12-04 12:41:55 +01:00

Update requests

This commit is contained in:
Yuki Okushi 2019-12-29 02:32:47 +09:00
parent b0e8a8d51d
commit 4f2f930349
6 changed files with 53 additions and 65 deletions

View File

@ -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" >}} {{< include-example example="requests" file="streaming.rs" section="streaming" >}}
[examples]: https://github.com/actix/examples/tree/master/json/ [examples]: https://github.com/actix/examples/tree/master/json/
[multipartstruct]: https://docs.rs/actix-multipart/0.1.2/actix_multipart/struct.Multipart.html [multipartstruct]: https://docs.rs/actix-multipart/0.2/actix_multipart/struct.Multipart.html
[fieldstruct]: https://docs.rs/actix-multipart/0.1.2/actix_multipart/struct.Field.html [fieldstruct]: https://docs.rs/actix-multipart/0.2/actix_multipart/struct.Field.html
[multipartexample]: https://github.com/actix/examples/tree/master/multipart/ [multipartexample]: https://github.com/actix/examples/tree/master/multipart/
[urlencoded]: https://docs.rs/actix-web/1.0.2/actix_web/dev/struct.UrlEncoded.html [urlencoded]: https://docs.rs/actix-web/2/actix_web/dev/struct.UrlEncoded.html
[payloadextractor]: https://docs.rs/actix-web/1.0.2/actix_web/web/struct.Payload.html [payloadextractor]: https://docs.rs/actix-web/2/actix_web/web/struct.Payload.html
[multipartcrate]: https://crates.io/crates/actix-multipart [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

View File

@ -6,7 +6,8 @@ edition = "2018"
[dependencies] [dependencies]
serde = "1.0" serde = "1.0"
serde_json = "1.0" serde_json = "1.0"
actix-web = "1.0" actix-web = "2.0"
futures = "0.1" actix-rt = "1.0"
futures = "0.3.1"
bytes = "0.4" bytes = "0.4"
actix-multipart = "0.1" actix-multipart = "0.2"

View File

@ -14,15 +14,15 @@ struct Info {
} }
/// extract `Info` using serde /// extract `Info` using serde
fn index(info: web::Json<Info>) -> Result<String> { async fn index(info: web::Json<Info>) -> Result<String> {
Ok(format!("Welcome {}!", info.username)) 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))) HttpServer::new(|| App::new().route("/", web::post().to(index)))
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }
// </json-request> // </json-request>

View File

@ -1,7 +1,7 @@
// <json-manual> // <json-manual>
use actix_web::{error, web, App, Error, HttpResponse}; use actix_web::{error, web, App, Error, HttpResponse};
use bytes::BytesMut; use bytes::BytesMut;
use futures::{Future, Stream}; use futures::StreamExt;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json; use serde_json;
@ -13,41 +13,30 @@ struct MyObj {
const MAX_SIZE: usize = 262_144; // max payload size is 256k const MAX_SIZE: usize = 262_144; // max payload size is 256k
pub fn index_manual( async fn index_manual(mut payload: web::Payload) -> Result<HttpResponse, Error> {
payload: web::Payload,
) -> impl Future<Item = HttpResponse, Error = Error> {
// payload is a stream of Bytes objects // payload is a stream of Bytes objects
payload let mut body = BytesMut::new();
// `Future::from_err` acts like `?` in that it coerces the error type from while let Some(chunk) = payload.next().await {
// the future into the final error type let chunk = chunk?;
.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 // limit max size of in-memory payload
if (body.len() + chunk.len()) > MAX_SIZE { if (body.len() + chunk.len()) > MAX_SIZE {
Err(error::ErrorBadRequest("overflow")) return Err(error::ErrorBadRequest("overflow"));
} else {
body.extend_from_slice(&chunk);
Ok(body)
} }
}) body.extend_from_slice(&chunk);
// `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 // body is loaded, now we can deserialize serde-json
let obj = serde_json::from_slice::<MyObj>(&body)?; let obj = serde_json::from_slice::<MyObj>(&body)?;
Ok(HttpResponse::Ok().json(obj)) // <- send response Ok(HttpResponse::Ok().json(obj)) // <- send response
})
} }
// </json-manual> // </json-manual>
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::HttpServer; use actix_web::HttpServer;
HttpServer::new(|| App::new().route("/", web::post().to_async(index_manual))) HttpServer::new(|| App::new().route("/", web::post().to(index_manual)))
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }

View File

@ -1,26 +1,24 @@
// <streaming> // <streaming>
use actix_web::{error, web, Error, HttpResponse}; 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<dyn Future<Item = HttpResponse, Error = Error>> { async fn index(mut body: web::Payload) -> Result<HttpResponse, Error> {
Box::new( let mut bytes = web::BytesMut::new();
payload while let Some(item) = body.next().await {
.from_err() bytes.extend_from_slice(&item?);
.fold((), |_, chunk| { }
println!("Chunk: {:?}", chunk);
result::<_, error::PayloadError>(Ok(())) println!("Chunk: {:?}", bytes);
}) Ok(HttpResponse::Ok().finish())
.map(|_| HttpResponse::Ok().into()),
)
} }
// </streaming> // </streaming>
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::{App, HttpServer}; use actix_web::{App, HttpServer};
HttpServer::new(|| App::new().route("/", web::post().to_async(index))) HttpServer::new(|| App::new().route("/", web::post().to(index)))
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }

View File

@ -7,17 +7,17 @@ struct FormData {
username: String, username: String,
} }
fn index(form: web::Form<FormData>) -> HttpResponse { async fn index(form: web::Form<FormData>) -> HttpResponse {
HttpResponse::Ok().body(format!("username: {}", form.username)) HttpResponse::Ok().body(format!("username: {}", form.username))
} }
// </urlencoded> // </urlencoded>
pub fn main() { #[actix_rt::main]
async fn main() -> std::io::Result<()> {
use actix_web::{App, HttpServer}; use actix_web::{App, HttpServer};
HttpServer::new(|| App::new().route("/", web::post().to(index))) HttpServer::new(|| App::new().route("/", web::post().to(index)))
.bind("127.0.0.1:8088") .bind("127.0.0.1:8088")?
.unwrap()
.run() .run()
.unwrap(); .await
} }