pub struct Response {
pub status: StatusCode,
pub headers: HeaderMap,
pub body: Body,
}Expand description
A fully-buffered HTTP response: status line, headers, and an in-memory body.
The three fields are public so middleware can post-process a response (for
example inserting a header). Construct one with Response::new (status
only), Response::text (a text/plain body), or Response::bytes (an
arbitrary content type), then refine it with the chainable
with_status and
with_header builders. Most handlers return an
IntoResponse value instead of building this directly.
use churust_core::Response;
use http::StatusCode;
let res = Response::text("created").with_status(StatusCode::CREATED);
assert_eq!(res.status, StatusCode::CREATED);
assert_eq!(res.body.as_slice(), Some(&b"created"[..]));Fields§
§status: StatusCodeThe HTTP status code of the response.
headers: HeaderMapThe response headers.
body: BodyThe response body — buffered bytes or a lazy stream.
Implementations§
Source§impl Response
impl Response
Sourcepub fn new(status: StatusCode) -> Self
pub fn new(status: StatusCode) -> Self
Create an empty-bodied response with the given status and no headers.
use churust_core::Response;
use http::StatusCode;
let res = Response::new(StatusCode::NO_CONTENT);
assert_eq!(res.status, StatusCode::NO_CONTENT);
assert!(res.body.is_empty());Sourcepub fn text(body: impl Into<String>) -> Self
pub fn text(body: impl Into<String>) -> Self
Create a 200 OK response with a text/plain; charset=utf-8 body.
use churust_core::Response;
use http::StatusCode;
let res = Response::text("hello");
assert_eq!(res.status, StatusCode::OK);
assert_eq!(
res.headers.get(http::header::CONTENT_TYPE).unwrap(),
"text/plain; charset=utf-8"
);Sourcepub fn bytes(content_type: &'static str, body: impl Into<Bytes>) -> Self
pub fn bytes(content_type: &'static str, body: impl Into<Bytes>) -> Self
Create a 200 OK response with a raw byte body and an explicit
Content-Type. Use this for non-text payloads (JSON, images, etc.); the
content_type must be a 'static string.
use churust_core::Response;
let res = Response::bytes("application/octet-stream", vec![1u8, 2, 3]);
assert_eq!(res.body.as_slice(), Some(&[1u8, 2, 3][..]));
assert_eq!(
res.headers.get(http::header::CONTENT_TYPE).unwrap(),
"application/octet-stream"
);Sourcepub fn stream(content_type: &'static str, body: Body) -> Self
pub fn stream(content_type: &'static str, body: Body) -> Self
Create a 200 OK response whose body is produced lazily from stream,
with an explicit Content-Type. Use for large or dynamic payloads.
use churust_core::{Body, Response};
use bytes::Bytes;
let chunks = futures_util::stream::iter(vec![Ok::<_, std::io::Error>(Bytes::from("hi"))]);
let res = Response::stream("text/plain", Body::from_stream(chunks));
assert!(res.body.as_bytes().is_none());Sourcepub fn with_status(self, status: StatusCode) -> Self
pub fn with_status(self, status: StatusCode) -> Self
Override the status code, returning self for chaining.
use churust_core::Response;
use http::StatusCode;
let res = Response::text("teapot").with_status(StatusCode::IM_A_TEAPOT);
assert_eq!(res.status, StatusCode::IM_A_TEAPOT);Append a Set-Cookie header.
Appends rather than replaces, so several cookies each get their own header — which is what the spec requires; folding them into one comma- separated value does not work in practice.
Sourcepub fn with_header(self, name: HeaderName, value: HeaderValue) -> Self
pub fn with_header(self, name: HeaderName, value: HeaderValue) -> Self
Insert (or replace) a header, returning self for chaining.
use churust_core::Response;
use http::{header::LOCATION, HeaderValue};
let res = Response::new(http::StatusCode::FOUND)
.with_header(LOCATION, HeaderValue::from_static("/login"));
assert_eq!(res.headers.get(LOCATION).unwrap(), "/login");Sourcepub fn vary_on(&mut self, field: &str)
pub fn vary_on(&mut self, field: &str)
Add a field name to Vary without disturbing what is already there.
Middleware that varies its output on a request header has to say so, and more than one layer can want to. Each has to merge rather than overwrite: a plugin that inserted its own field alone erased the other’s, and a shared cache then served a response keyed on the wrong thing — compressed bytes handed to a client that never said it could decode them, or one origin’s response handed to another.
Merging is here, in one place, because the merge is only correct if every layer does it the same way: field names are case-insensitive, so the comparison is too, and the value is appended in lower case so a response passing through several layers reads as one consistent list rather than a mixture. Two implementations agreeing by convention is what this replaces.
Already-present fields and a Vary: * — which varies on everything — are
left alone.
use churust_core::Response;
let mut res = Response::text("ok");
res.vary_on("accept-encoding");
res.vary_on("Origin");
assert_eq!(res.headers.get("vary").unwrap(), "accept-encoding, origin");
// Asking twice changes nothing, whatever the spelling.
res.vary_on("ORIGIN");
assert_eq!(res.headers.get("vary").unwrap(), "accept-encoding, origin");Trait Implementations§
Source§impl IntoResponse for Response
impl IntoResponse for Response
Source§fn into_response(self) -> Response
fn into_response(self) -> Response
self and produce the Response to send.