diff --git a/content/docs/response.md b/content/docs/response.md index 369b869..b890eb9 100644 --- a/content/docs/response.md +++ b/content/docs/response.md @@ -17,17 +17,7 @@ The methods `.body`, `.finish`, and `.json` finalize response creation and return a constructed *HttpResponse* instance. If this methods is called on the same builder instance multiple times, the builder will panic. -```rust -use actix_web::{HttpRequest, HttpResponse, http::ContentEncoding}; - -fn index(req: &HttpRequest) -> HttpResponse { - HttpResponse::Ok() - .content_encoding(ContentEncoding::Br) - .content_type("plain/text") - .header("X-Hdr", "sample") - .body("data") -} -``` +{{< include-example example="responses" file="main.rs" section="builder" >}} # Content encoding @@ -38,80 +28,34 @@ Actix automatically *compresses* payloads. The following codecs are supported: * Deflate * Identity -Response payload is compressed based on the *content_encoding* parameter. -By default, `ContentEncoding::Auto` is used. If `ContentEncoding::Auto` is selected, -then the compression depends on the request's `Accept-Encoding` header. +Response payload is compressed based on the *encoding* parameter from the +`middleware::BodyEncoding` trait. By default, `ContentEncoding::Auto` is +used. If `ContentEncoding::Auto` is selected, then the compression depends +on the request's `Accept-Encoding` header. > `ContentEncoding::Identity` can be used to disable compression. > If another content encoding is selected, the compression is enforced for that codec. For example, to enable `brotli` use `ContentEncoding::Br`: -```rust -use actix_web::{HttpRequest, HttpResponse, http::ContentEncoding}; - -fn index(req: HttpRequest) -> HttpResponse { - HttpResponse::Ok() - .content_encoding(ContentEncoding::Br) - .body("data") -} -``` +{{< include-example example="responses" file="brotli.rs" section="brotli" >}} In this case we explicitly disable content compression by setting content encoding to a `Identity` value: -```rust -use actix_web::{HttpRequest, HttpResponse, http::ContentEncoding}; - -fn index(req: HttpRequest) -> HttpResponse { - HttpResponse::Ok() - // v- disable compression - .content_encoding(ContentEncoding::Identity) - .body("data") -} -``` +{{< include-example example="responses" file="identity.rs" section="identity" >}} When dealing with an already compressed body (for example when serving assets), set the content encoding to `Identity` to avoid compressing the already compressed data and set the `content-encoding` header manually: -```rust -use actix_web::{HttpRequest, HttpResponse, http::ContentEncoding}; - -static HELLO_WORLD: &[u8] = &[ - 0x1f,0x8b,0x08,0x00,0xa2,0x30,0x10,0x5c, - 0x00,0x03,0xcb,0x48,0xcd,0xc9,0xc9,0x57, - 0x28,0xcf,0x2f,0xca,0x49,0xe1,0x02,0x00, - 0x2d,0x3b,0x08,0xaf,0x0c,0x00,0x00,0x00 -]; - -pub fn index(req: HttpRequest) -> HttpResponse { - HttpResponse::Ok() - .content_encoding(ContentEncoding::Identity) - .header("content-encoding", "gzip") - .body(HELLO_WORLD) -} -``` +{{< include-example example="responses" file="identity_two.rs" section="identity-two" >}} Also it is possible to set default content encoding on application level, by default `ContentEncoding::Auto` is used, which implies automatic content compression negotiation. -```rust -use actix_web::{App, HttpRequest, HttpResponse, http::ContentEncoding}; - -fn index(req: HttpRequest) -> HttpResponse { - HttpResponse::Ok() - .body("data") -} - -fn main() { - let app = App::new() - // v- disable compression for all routes - .default_encoding(ContentEncoding::Identity) - .resource("/index.html", |r| r.with(index)); -} -``` +{{< include-example example="responses" file="auto.rs" section="auto" >}} # JSON Response @@ -119,26 +63,7 @@ The `Json` type allows to respond with well-formed JSON data: simply return a va type Json where `T` is the type of a structure to serialize into *JSON*. The type `T` must implement the `Serialize` trait from *serde*. -```rust -# extern crate actix_web; -#[macro_use] extern crate serde_derive; -use actix_web::{App, HttpRequest, Json, Result, http::Method}; - -#[derive(Serialize)] -struct MyObj { - name: String, -} - -fn index(req: &HttpRequest) -> Result> { - Ok(Json(MyObj{name: req.match_info().query("name")?})) -} - -fn main() { - App::new() - .resource(r"/a/{name}", |r| r.method(Method::GET).f(index)) - .finish(); -} -``` +{{< include-example example="responses" file="json_resp.rs" section="json-resp" >}} # Chunked transfer encoding @@ -149,14 +74,4 @@ is enabled automatically. > Enabling chunked encoding for *HTTP/2.0* responses is forbidden. -```rust -use actix_web::*; -use bytes::Bytes; -use futures::stream::once; - -fn index(req: HttpRequest) -> HttpResponse { - HttpResponse::Ok() - .chunked() - .body(Body::Streaming(Box::new(once(Ok(Bytes::from_static(b"data")))))) -} -``` +{{< include-example example="responses" file="chunked.rs" section="chunked" >}} diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 05f095a..6b54cd8 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -19,4 +19,5 @@ exclude = [ "autoreload", "errors", "requests", + "responses", ] diff --git a/examples/responses/Cargo.toml b/examples/responses/Cargo.toml new file mode 100644 index 0000000..53b9236 --- /dev/null +++ b/examples/responses/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "responses" +version = "0.1.0" +edition = "2018" + +[dependencies] +actix-web = "1.0" +serde = "1.0" +futures = "0.1" +bytes = "0.4" diff --git a/examples/responses/src/auto.rs b/examples/responses/src/auto.rs new file mode 100644 index 0000000..598513a --- /dev/null +++ b/examples/responses/src/auto.rs @@ -0,0 +1,16 @@ +// +use actix_web::{ + http::ContentEncoding, middleware, web, App, HttpRequest, HttpResponse, +}; + +fn index(req: HttpRequest) -> HttpResponse { + HttpResponse::Ok().body("data") +} + +fn main() { + let app = App::new() + // v- disable compression for all routes + .wrap(middleware::Compress::new(ContentEncoding::Identity)) + .route("/", web::get().to(index)); +} +// diff --git a/examples/responses/src/brotli.rs b/examples/responses/src/brotli.rs new file mode 100644 index 0000000..e107ad7 --- /dev/null +++ b/examples/responses/src/brotli.rs @@ -0,0 +1,13 @@ +// +use actix_web::{ + http::ContentEncoding, middleware::BodyEncoding, HttpRequest, HttpResponse, +}; + +fn index_br(req: HttpRequest) -> HttpResponse { + HttpResponse::Ok() + .encoding(ContentEncoding::Br) + .body("data") +} +// + +fn main() {} diff --git a/examples/responses/src/chunked.rs b/examples/responses/src/chunked.rs new file mode 100644 index 0000000..0cd6d76 --- /dev/null +++ b/examples/responses/src/chunked.rs @@ -0,0 +1,14 @@ +// +// use actix_web::{web, HttpRequest, HttpResponse}; +// use bytes::Bytes; +// use futures::stream::once; + +// fn index(req: HttpRequest) -> HttpResponse { +// HttpResponse::Ok() +// .chunked() +// .body(Body::Streaming(Box::new(once(Ok(Bytes::from_static( +// b"data", +// )))))) +// } +// +fn main() {} diff --git a/examples/responses/src/identity.rs b/examples/responses/src/identity.rs new file mode 100644 index 0000000..89bd52e --- /dev/null +++ b/examples/responses/src/identity.rs @@ -0,0 +1,12 @@ +// +use actix_web::{ + http::ContentEncoding, middleware::BodyEncoding, HttpRequest, HttpResponse, +}; + +fn index(req: HttpRequest) -> HttpResponse { + HttpResponse::Ok() + // v- disable compression + .encoding(ContentEncoding::Identity) + .body("data") +} +// diff --git a/examples/responses/src/identity_two.rs b/examples/responses/src/identity_two.rs new file mode 100644 index 0000000..63371fa --- /dev/null +++ b/examples/responses/src/identity_two.rs @@ -0,0 +1,18 @@ +// +use actix_web::{ + http::ContentEncoding, middleware::BodyEncoding, HttpRequest, HttpResponse, +}; + +static HELLO_WORLD: &[u8] = &[ + 0x1f, 0x8b, 0x08, 0x00, 0xa2, 0x30, 0x10, 0x5c, 0x00, 0x03, 0xcb, 0x48, 0xcd, 0xc9, + 0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1, 0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, + 0x0c, 0x00, 0x00, 0x00, +]; + +pub fn index(_req: HttpRequest) -> HttpResponse { + HttpResponse::Ok() + .encoding(ContentEncoding::Identity) + .header("content-encoding", "gzip") + .body(HELLO_WORLD) +} +// diff --git a/examples/responses/src/json_resp.rs b/examples/responses/src/json_resp.rs new file mode 100644 index 0000000..c2344c0 --- /dev/null +++ b/examples/responses/src/json_resp.rs @@ -0,0 +1,19 @@ +// +use actix_web::{web, App, HttpRequest, Result}; +use serde::Serialize; + +#[derive(Serialize)] +struct MyObj { + name: String, +} + +fn index(req: HttpRequest) -> Result> { + Ok(web::Json(MyObj { + name: req.match_info().query("name").to_string(), + })) +} + +fn main() { + App::new().route(r"/a/{name}", web::get().to(index)); +} +// diff --git a/examples/responses/src/main.rs b/examples/responses/src/main.rs new file mode 100644 index 0000000..4c9f209 --- /dev/null +++ b/examples/responses/src/main.rs @@ -0,0 +1,21 @@ +mod auto; +mod brotli; +mod chunked; +mod identity; +mod identity_two; +mod json_resp; +// +use actix_web::{ + http::ContentEncoding, middleware::BodyEncoding, HttpRequest, HttpResponse, +}; + +fn index(_req: HttpRequest) -> HttpResponse { + HttpResponse::Ok() + .encoding(ContentEncoding::Br) + .content_type("plain/text") + .header("X-Hdr", "sample") + .body("data") +} +// + +fn main() {}