http/response.rs
1//! HTTP response types.
2//!
3//! This module contains structs related to HTTP responses, notably the
4//! `Response` type itself as well as a builder to create responses. Typically
5//! you'll import the `http::Response` type rather than reaching into this
6//! module itself.
7//!
8//! # Examples
9//!
10//! Creating a `Response` to return
11//!
12//! ```
13//! use http::{Request, Response, StatusCode};
14//!
15//! fn respond_to(req: Request<()>) -> http::Result<Response<()>> {
16//! let mut builder = Response::builder()
17//! .header("Foo", "Bar")
18//! .status(StatusCode::OK);
19//!
20//! if req.headers().contains_key("Another-Header") {
21//! builder = builder.header("Another-Header", "Ack");
22//! }
23//!
24//! builder.body(())
25//! }
26//! ```
27//!
28//! A simple 404 handler
29//!
30//! ```
31//! use http::{Request, Response, StatusCode};
32//!
33//! fn not_found(_req: Request<()>) -> http::Result<Response<()>> {
34//! Response::builder()
35//! .status(StatusCode::NOT_FOUND)
36//! .body(())
37//! }
38//! ```
39//!
40//! Or otherwise inspecting the result of a request:
41//!
42//! ```no_run
43//! use http::{Request, Response};
44//!
45//! fn get(url: &str) -> http::Result<Response<()>> {
46//! // ...
47//! # panic!()
48//! }
49//!
50//! let response = get("https://www.rust-lang.org/").unwrap();
51//!
52//! if !response.status().is_success() {
53//! panic!("failed to get a successful response status!");
54//! }
55//!
56//! if let Some(date) = response.headers().get("Date") {
57//! // we've got a `Date` header!
58//! }
59//!
60//! let body = response.body();
61//! // ...
62//! ```
63
64use std::any::Any;
65use std::convert::TryInto;
66use std::fmt;
67
68use crate::header::{HeaderMap, HeaderName, HeaderValue};
69use crate::status::StatusCode;
70use crate::version::Version;
71use crate::{Extensions, Result};
72
73/// Represents an HTTP response
74///
75/// An HTTP response consists of a head and a potentially optional body. The body
76/// component is generic, enabling arbitrary types to represent the HTTP body.
77/// For example, the body could be `Vec<u8>`, a `Stream` of byte chunks, or a
78/// value that has been deserialized.
79///
80/// Typically you'll work with responses on the client side as the result of
81/// sending a `Request` and on the server you'll be generating a `Response` to
82/// send back to the client.
83///
84/// # Examples
85///
86/// Creating a `Response` to return
87///
88/// ```
89/// use http::{Request, Response, StatusCode};
90///
91/// fn respond_to(req: Request<()>) -> http::Result<Response<()>> {
92/// let mut builder = Response::builder()
93/// .header("Foo", "Bar")
94/// .status(StatusCode::OK);
95///
96/// if req.headers().contains_key("Another-Header") {
97/// builder = builder.header("Another-Header", "Ack");
98/// }
99///
100/// builder.body(())
101/// }
102/// ```
103///
104/// A simple 404 handler
105///
106/// ```
107/// use http::{Request, Response, StatusCode};
108///
109/// fn not_found(_req: Request<()>) -> http::Result<Response<()>> {
110/// Response::builder()
111/// .status(StatusCode::NOT_FOUND)
112/// .body(())
113/// }
114/// ```
115///
116/// Or otherwise inspecting the result of a request:
117///
118/// ```no_run
119/// use http::{Request, Response};
120///
121/// fn get(url: &str) -> http::Result<Response<()>> {
122/// // ...
123/// # panic!()
124/// }
125///
126/// let response = get("https://www.rust-lang.org/").unwrap();
127///
128/// if !response.status().is_success() {
129/// panic!("failed to get a successful response status!");
130/// }
131///
132/// if let Some(date) = response.headers().get("Date") {
133/// // we've got a `Date` header!
134/// }
135///
136/// let body = response.body();
137/// // ...
138/// ```
139///
140/// Deserialize a response of bytes via json:
141///
142/// ```
143/// use http::Response;
144/// use serde::de;
145///
146/// fn deserialize<T>(res: Response<Vec<u8>>) -> serde_json::Result<Response<T>>
147/// where for<'de> T: de::Deserialize<'de>,
148/// {
149/// let (parts, body) = res.into_parts();
150/// let body = serde_json::from_slice(&body)?;
151/// Ok(Response::from_parts(parts, body))
152/// }
153/// #
154/// # fn main() {}
155/// ```
156///
157/// Or alternatively, serialize the body of a response to json
158///
159/// ```
160/// use http::Response;
161/// use serde::ser;
162///
163/// fn serialize<T>(res: Response<T>) -> serde_json::Result<Response<Vec<u8>>>
164/// where T: ser::Serialize,
165/// {
166/// let (parts, body) = res.into_parts();
167/// let body = serde_json::to_vec(&body)?;
168/// Ok(Response::from_parts(parts, body))
169/// }
170/// #
171/// # fn main() {}
172/// ```
173#[derive(Clone)]
174pub struct Response<T> {
175 head: Parts,
176 body: T,
177}
178
179/// Component parts of an HTTP `Response`
180///
181/// The HTTP response head consists of a status, version, and a set of
182/// header fields.
183#[derive(Clone)]
184pub struct Parts {
185 /// The response's status
186 pub status: StatusCode,
187
188 /// The response's version
189 pub version: Version,
190
191 /// The response's headers
192 pub headers: HeaderMap<HeaderValue>,
193
194 /// The response's extensions
195 pub extensions: Extensions,
196
197 _priv: (),
198}
199
200/// An HTTP response builder
201///
202/// This type can be used to construct an instance of `Response` through a
203/// builder-like pattern.
204#[derive(Debug)]
205pub struct Builder {
206 inner: Result<Parts>,
207}
208
209impl Response<()> {
210 /// Creates a new builder-style object to manufacture a `Response`
211 ///
212 /// This method returns an instance of `Builder` which can be used to
213 /// create a `Response`.
214 ///
215 /// # Examples
216 ///
217 /// ```
218 /// # use http::*;
219 /// let response = Response::builder()
220 /// .status(200)
221 /// .header("X-Custom-Foo", "Bar")
222 /// .body(())
223 /// .unwrap();
224 /// ```
225 #[inline]
226 pub fn builder() -> Builder {
227 Builder::new()
228 }
229}
230
231impl<T> Response<T> {
232 /// Creates a new blank `Response` with the body
233 ///
234 /// The component parts of this response will be set to their default, e.g.
235 /// the ok status, no headers, etc.
236 ///
237 /// # Examples
238 ///
239 /// ```
240 /// # use http::*;
241 /// let response = Response::new("hello world");
242 ///
243 /// assert_eq!(response.status(), StatusCode::OK);
244 /// assert_eq!(*response.body(), "hello world");
245 /// ```
246 #[inline]
247 pub fn new(body: T) -> Response<T> {
248 Response {
249 head: Parts::new(),
250 body,
251 }
252 }
253
254 /// Creates a new `Response` with the given head and body
255 ///
256 /// # Examples
257 ///
258 /// ```
259 /// # use http::*;
260 /// let response = Response::new("hello world");
261 /// let (mut parts, body) = response.into_parts();
262 ///
263 /// parts.status = StatusCode::BAD_REQUEST;
264 /// let response = Response::from_parts(parts, body);
265 ///
266 /// assert_eq!(response.status(), StatusCode::BAD_REQUEST);
267 /// assert_eq!(*response.body(), "hello world");
268 /// ```
269 #[inline]
270 pub fn from_parts(parts: Parts, body: T) -> Response<T> {
271 Response { head: parts, body }
272 }
273
274 /// Returns the `StatusCode`.
275 ///
276 /// # Examples
277 ///
278 /// ```
279 /// # use http::*;
280 /// let response: Response<()> = Response::default();
281 /// assert_eq!(response.status(), StatusCode::OK);
282 /// ```
283 #[inline]
284 pub fn status(&self) -> StatusCode {
285 self.head.status
286 }
287
288 /// Returns a mutable reference to the associated `StatusCode`.
289 ///
290 /// # Examples
291 ///
292 /// ```
293 /// # use http::*;
294 /// let mut response: Response<()> = Response::default();
295 /// *response.status_mut() = StatusCode::CREATED;
296 /// assert_eq!(response.status(), StatusCode::CREATED);
297 /// ```
298 #[inline]
299 pub fn status_mut(&mut self) -> &mut StatusCode {
300 &mut self.head.status
301 }
302
303 /// Returns a reference to the associated version.
304 ///
305 /// # Examples
306 ///
307 /// ```
308 /// # use http::*;
309 /// let response: Response<()> = Response::default();
310 /// assert_eq!(response.version(), Version::HTTP_11);
311 /// ```
312 #[inline]
313 pub fn version(&self) -> Version {
314 self.head.version
315 }
316
317 /// Returns a mutable reference to the associated version.
318 ///
319 /// # Examples
320 ///
321 /// ```
322 /// # use http::*;
323 /// let mut response: Response<()> = Response::default();
324 /// *response.version_mut() = Version::HTTP_2;
325 /// assert_eq!(response.version(), Version::HTTP_2);
326 /// ```
327 #[inline]
328 pub fn version_mut(&mut self) -> &mut Version {
329 &mut self.head.version
330 }
331
332 /// Returns a reference to the associated header field map.
333 ///
334 /// # Examples
335 ///
336 /// ```
337 /// # use http::*;
338 /// let response: Response<()> = Response::default();
339 /// assert!(response.headers().is_empty());
340 /// ```
341 #[inline]
342 pub fn headers(&self) -> &HeaderMap<HeaderValue> {
343 &self.head.headers
344 }
345
346 /// Returns a mutable reference to the associated header field map.
347 ///
348 /// # Examples
349 ///
350 /// ```
351 /// # use http::*;
352 /// # use http::header::*;
353 /// let mut response: Response<()> = Response::default();
354 /// response.headers_mut().insert(HOST, HeaderValue::from_static("world"));
355 /// assert!(!response.headers().is_empty());
356 /// ```
357 #[inline]
358 pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
359 &mut self.head.headers
360 }
361
362 /// Returns a reference to the associated extensions.
363 ///
364 /// # Examples
365 ///
366 /// ```
367 /// # use http::*;
368 /// let response: Response<()> = Response::default();
369 /// assert!(response.extensions().get::<i32>().is_none());
370 /// ```
371 #[inline]
372 pub fn extensions(&self) -> &Extensions {
373 &self.head.extensions
374 }
375
376 /// Returns a mutable reference to the associated extensions.
377 ///
378 /// # Examples
379 ///
380 /// ```
381 /// # use http::*;
382 /// # use http::header::*;
383 /// let mut response: Response<()> = Response::default();
384 /// response.extensions_mut().insert("hello");
385 /// assert_eq!(response.extensions().get(), Some(&"hello"));
386 /// ```
387 #[inline]
388 pub fn extensions_mut(&mut self) -> &mut Extensions {
389 &mut self.head.extensions
390 }
391
392 /// Returns a reference to the associated HTTP body.
393 ///
394 /// # Examples
395 ///
396 /// ```
397 /// # use http::*;
398 /// let response: Response<String> = Response::default();
399 /// assert!(response.body().is_empty());
400 /// ```
401 #[inline]
402 pub fn body(&self) -> &T {
403 &self.body
404 }
405
406 /// Returns a mutable reference to the associated HTTP body.
407 ///
408 /// # Examples
409 ///
410 /// ```
411 /// # use http::*;
412 /// let mut response: Response<String> = Response::default();
413 /// response.body_mut().push_str("hello world");
414 /// assert!(!response.body().is_empty());
415 /// ```
416 #[inline]
417 pub fn body_mut(&mut self) -> &mut T {
418 &mut self.body
419 }
420
421 /// Consumes the response, returning just the body.
422 ///
423 /// # Examples
424 ///
425 /// ```
426 /// # use http::Response;
427 /// let response = Response::new(10);
428 /// let body = response.into_body();
429 /// assert_eq!(body, 10);
430 /// ```
431 #[inline]
432 pub fn into_body(self) -> T {
433 self.body
434 }
435
436 /// Consumes the response returning the head and body parts.
437 ///
438 /// # Examples
439 ///
440 /// ```
441 /// # use http::*;
442 /// let response: Response<()> = Response::default();
443 /// let (parts, body) = response.into_parts();
444 /// assert_eq!(parts.status, StatusCode::OK);
445 /// ```
446 #[inline]
447 pub fn into_parts(self) -> (Parts, T) {
448 (self.head, self.body)
449 }
450
451 /// Consumes the response returning a new response with body mapped to the
452 /// return type of the passed in function.
453 ///
454 /// # Examples
455 ///
456 /// ```
457 /// # use http::*;
458 /// let response = Response::builder().body("some string").unwrap();
459 /// let mapped_response: Response<&[u8]> = response.map(|b| {
460 /// assert_eq!(b, "some string");
461 /// b.as_bytes()
462 /// });
463 /// assert_eq!(mapped_response.body(), &"some string".as_bytes());
464 /// ```
465 #[inline]
466 pub fn map<F, U>(self, f: F) -> Response<U>
467 where
468 F: FnOnce(T) -> U,
469 {
470 Response {
471 body: f(self.body),
472 head: self.head,
473 }
474 }
475}
476
477impl<T: Default> Default for Response<T> {
478 #[inline]
479 fn default() -> Response<T> {
480 Response::new(T::default())
481 }
482}
483
484impl<T: fmt::Debug> fmt::Debug for Response<T> {
485 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
486 f.debug_struct("Response")
487 .field("status", &self.status())
488 .field("version", &self.version())
489 .field("headers", self.headers())
490 // omits Extensions because not useful
491 .field("body", self.body())
492 .finish()
493 }
494}
495
496impl Parts {
497 /// Creates a new default instance of `Parts`
498 fn new() -> Parts {
499 Parts {
500 status: StatusCode::default(),
501 version: Version::default(),
502 headers: HeaderMap::default(),
503 extensions: Extensions::default(),
504 _priv: (),
505 }
506 }
507}
508
509impl fmt::Debug for Parts {
510 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
511 f.debug_struct("Parts")
512 .field("status", &self.status)
513 .field("version", &self.version)
514 .field("headers", &self.headers)
515 // omits Extensions because not useful
516 // omits _priv because not useful
517 .finish()
518 }
519}
520
521impl Builder {
522 /// Creates a new default instance of `Builder` to construct either a
523 /// `Head` or a `Response`.
524 ///
525 /// # Examples
526 ///
527 /// ```
528 /// # use http::*;
529 ///
530 /// let response = response::Builder::new()
531 /// .status(200)
532 /// .body(())
533 /// .unwrap();
534 /// ```
535 #[inline]
536 pub fn new() -> Builder {
537 Builder::default()
538 }
539
540 /// Set the HTTP status for this response.
541 ///
542 /// By default this is `200`.
543 ///
544 /// # Examples
545 ///
546 /// ```
547 /// # use http::*;
548 ///
549 /// let response = Response::builder()
550 /// .status(200)
551 /// .body(())
552 /// .unwrap();
553 /// ```
554 pub fn status<T>(self, status: T) -> Builder
555 where
556 T: TryInto<StatusCode>,
557 <T as TryInto<StatusCode>>::Error: Into<crate::Error>,
558 {
559 self.and_then(move |mut head| {
560 head.status = status.try_into().map_err(Into::into)?;
561 Ok(head)
562 })
563 }
564
565 /// Set the HTTP version for this response.
566 ///
567 /// By default this is HTTP/1.1
568 ///
569 /// # Examples
570 ///
571 /// ```
572 /// # use http::*;
573 ///
574 /// let response = Response::builder()
575 /// .version(Version::HTTP_2)
576 /// .body(())
577 /// .unwrap();
578 /// ```
579 pub fn version(self, version: Version) -> Builder {
580 self.and_then(move |mut head| {
581 head.version = version;
582 Ok(head)
583 })
584 }
585
586 /// Appends a header to this response builder.
587 ///
588 /// This function will append the provided key/value as a header to the
589 /// internal `HeaderMap` being constructed. Essentially this is equivalent
590 /// to calling `HeaderMap::append`.
591 ///
592 /// # Examples
593 ///
594 /// ```
595 /// # use http::*;
596 /// # use http::header::HeaderValue;
597 ///
598 /// let response = Response::builder()
599 /// .header("Content-Type", "text/html")
600 /// .header("X-Custom-Foo", "bar")
601 /// .header("content-length", 0)
602 /// .body(())
603 /// .unwrap();
604 /// ```
605 pub fn header<K, V>(self, key: K, value: V) -> Builder
606 where
607 K: TryInto<HeaderName>,
608 <K as TryInto<HeaderName>>::Error: Into<crate::Error>,
609 V: TryInto<HeaderValue>,
610 <V as TryInto<HeaderValue>>::Error: Into<crate::Error>,
611 {
612 self.and_then(move |mut head| {
613 let name = key.try_into().map_err(Into::into)?;
614 let value = value.try_into().map_err(Into::into)?;
615 head.headers.try_append(name, value)?;
616 Ok(head)
617 })
618 }
619
620 /// Get header on this response builder.
621 ///
622 /// When builder has error returns None.
623 ///
624 /// # Example
625 ///
626 /// ```
627 /// # use http::Response;
628 /// # use http::header::HeaderValue;
629 /// let res = Response::builder()
630 /// .header("Accept", "text/html")
631 /// .header("X-Custom-Foo", "bar");
632 /// let headers = res.headers_ref().unwrap();
633 /// assert_eq!( headers["Accept"], "text/html" );
634 /// assert_eq!( headers["X-Custom-Foo"], "bar" );
635 /// ```
636 pub fn headers_ref(&self) -> Option<&HeaderMap<HeaderValue>> {
637 self.inner.as_ref().ok().map(|h| &h.headers)
638 }
639
640 /// Get header on this response builder.
641 /// when builder has error returns None
642 ///
643 /// # Example
644 ///
645 /// ```
646 /// # use http::*;
647 /// # use http::header::HeaderValue;
648 /// # use http::response::Builder;
649 /// let mut res = Response::builder();
650 /// {
651 /// let headers = res.headers_mut().unwrap();
652 /// headers.insert("Accept", HeaderValue::from_static("text/html"));
653 /// headers.insert("X-Custom-Foo", HeaderValue::from_static("bar"));
654 /// }
655 /// let headers = res.headers_ref().unwrap();
656 /// assert_eq!( headers["Accept"], "text/html" );
657 /// assert_eq!( headers["X-Custom-Foo"], "bar" );
658 /// ```
659 pub fn headers_mut(&mut self) -> Option<&mut HeaderMap<HeaderValue>> {
660 self.inner.as_mut().ok().map(|h| &mut h.headers)
661 }
662
663 /// Adds an extension to this builder
664 ///
665 /// # Examples
666 ///
667 /// ```
668 /// # use http::*;
669 ///
670 /// let response = Response::builder()
671 /// .extension("My Extension")
672 /// .body(())
673 /// .unwrap();
674 ///
675 /// assert_eq!(response.extensions().get::<&'static str>(),
676 /// Some(&"My Extension"));
677 /// ```
678 pub fn extension<T>(self, extension: T) -> Builder
679 where
680 T: Clone + Any + Send + Sync + 'static,
681 {
682 self.and_then(move |mut head| {
683 head.extensions.insert(extension);
684 Ok(head)
685 })
686 }
687
688 /// Get a reference to the extensions for this response builder.
689 ///
690 /// If the builder has an error, this returns `None`.
691 ///
692 /// # Example
693 ///
694 /// ```
695 /// # use http::Response;
696 /// let res = Response::builder().extension("My Extension").extension(5u32);
697 /// let extensions = res.extensions_ref().unwrap();
698 /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension"));
699 /// assert_eq!(extensions.get::<u32>(), Some(&5u32));
700 /// ```
701 pub fn extensions_ref(&self) -> Option<&Extensions> {
702 self.inner.as_ref().ok().map(|h| &h.extensions)
703 }
704
705 /// Get a mutable reference to the extensions for this response builder.
706 ///
707 /// If the builder has an error, this returns `None`.
708 ///
709 /// # Example
710 ///
711 /// ```
712 /// # use http::Response;
713 /// let mut res = Response::builder().extension("My Extension");
714 /// let mut extensions = res.extensions_mut().unwrap();
715 /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension"));
716 /// extensions.insert(5u32);
717 /// assert_eq!(extensions.get::<u32>(), Some(&5u32));
718 /// ```
719 pub fn extensions_mut(&mut self) -> Option<&mut Extensions> {
720 self.inner.as_mut().ok().map(|h| &mut h.extensions)
721 }
722
723 /// "Consumes" this builder, using the provided `body` to return a
724 /// constructed `Response`.
725 ///
726 /// # Errors
727 ///
728 /// This function may return an error if any previously configured argument
729 /// failed to parse or get converted to the internal representation. For
730 /// example if an invalid `head` was specified via `header("Foo",
731 /// "Bar\r\n")` the error will be returned when this function is called
732 /// rather than when `header` was called.
733 ///
734 /// # Examples
735 ///
736 /// ```
737 /// # use http::*;
738 ///
739 /// let response = Response::builder()
740 /// .body(())
741 /// .unwrap();
742 /// ```
743 pub fn body<T>(self, body: T) -> Result<Response<T>> {
744 self.inner.map(move |head| Response { head, body })
745 }
746
747 // private
748
749 fn and_then<F>(self, func: F) -> Self
750 where
751 F: FnOnce(Parts) -> Result<Parts>,
752 {
753 Builder {
754 inner: self.inner.and_then(func),
755 }
756 }
757}
758
759impl Default for Builder {
760 #[inline]
761 fn default() -> Builder {
762 Builder {
763 inner: Ok(Parts::new()),
764 }
765 }
766}
767
768#[cfg(test)]
769mod tests {
770 use super::*;
771
772 #[test]
773 fn it_can_map_a_body_from_one_type_to_another() {
774 let response = Response::builder().body("some string").unwrap();
775 let mapped_response = response.map(|s| {
776 assert_eq!(s, "some string");
777 123u32
778 });
779 assert_eq!(mapped_response.body(), &123u32);
780 }
781}