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::TryFrom;
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/// # extern crate serde;
144/// # extern crate serde_json;
145/// # extern crate http;
146/// use http::Response;
147/// use serde::de;
148///
149/// fn deserialize<T>(req: Response<Vec<u8>>) -> serde_json::Result<Response<T>>
150///     where for<'de> T: de::Deserialize<'de>,
151/// {
152///     let (parts, body) = req.into_parts();
153///     let body = serde_json::from_slice(&body)?;
154///     Ok(Response::from_parts(parts, body))
155/// }
156/// #
157/// # fn main() {}
158/// ```
159///
160/// Or alternatively, serialize the body of a response to json
161///
162/// ```
163/// # extern crate serde;
164/// # extern crate serde_json;
165/// # extern crate http;
166/// use http::Response;
167/// use serde::ser;
168///
169/// fn serialize<T>(req: Response<T>) -> serde_json::Result<Response<Vec<u8>>>
170///     where T: ser::Serialize,
171/// {
172///     let (parts, body) = req.into_parts();
173///     let body = serde_json::to_vec(&body)?;
174///     Ok(Response::from_parts(parts, body))
175/// }
176/// #
177/// # fn main() {}
178/// ```
179pub struct Response<T> {
180    head: Parts,
181    body: T,
182}
183
184/// Component parts of an HTTP `Response`
185///
186/// The HTTP response head consists of a status, version, and a set of
187/// header fields.
188pub struct Parts {
189    /// The response's status
190    pub status: StatusCode,
191
192    /// The response's version
193    pub version: Version,
194
195    /// The response's headers
196    pub headers: HeaderMap<HeaderValue>,
197
198    /// The response's extensions
199    pub extensions: Extensions,
200
201    _priv: (),
202}
203
204/// An HTTP response builder
205///
206/// This type can be used to construct an instance of `Response` through a
207/// builder-like pattern.
208#[derive(Debug)]
209pub struct Builder {
210    inner: Result<Parts>,
211}
212
213impl Response<()> {
214    /// Creates a new builder-style object to manufacture a `Response`
215    ///
216    /// This method returns an instance of `Builder` which can be used to
217    /// create a `Response`.
218    ///
219    /// # Examples
220    ///
221    /// ```
222    /// # use http::*;
223    /// let response = Response::builder()
224    ///     .status(200)
225    ///     .header("X-Custom-Foo", "Bar")
226    ///     .body(())
227    ///     .unwrap();
228    /// ```
229    #[inline]
230    pub fn builder() -> Builder {
231        Builder::new()
232    }
233}
234
235impl<T> Response<T> {
236    /// Creates a new blank `Response` with the body
237    ///
238    /// The component ports of this response will be set to their default, e.g.
239    /// the ok status, no headers, etc.
240    ///
241    /// # Examples
242    ///
243    /// ```
244    /// # use http::*;
245    /// let response = Response::new("hello world");
246    ///
247    /// assert_eq!(response.status(), StatusCode::OK);
248    /// assert_eq!(*response.body(), "hello world");
249    /// ```
250    #[inline]
251    pub fn new(body: T) -> Response<T> {
252        Response {
253            head: Parts::new(),
254            body: body,
255        }
256    }
257
258    /// Creates a new `Response` with the given head and body
259    ///
260    /// # Examples
261    ///
262    /// ```
263    /// # use http::*;
264    /// let response = Response::new("hello world");
265    /// let (mut parts, body) = response.into_parts();
266    ///
267    /// parts.status = StatusCode::BAD_REQUEST;
268    /// let response = Response::from_parts(parts, body);
269    ///
270    /// assert_eq!(response.status(), StatusCode::BAD_REQUEST);
271    /// assert_eq!(*response.body(), "hello world");
272    /// ```
273    #[inline]
274    pub fn from_parts(parts: Parts, body: T) -> Response<T> {
275        Response {
276            head: parts,
277            body: body,
278        }
279    }
280
281    /// Returns the `StatusCode`.
282    ///
283    /// # Examples
284    ///
285    /// ```
286    /// # use http::*;
287    /// let response: Response<()> = Response::default();
288    /// assert_eq!(response.status(), StatusCode::OK);
289    /// ```
290    #[inline]
291    pub fn status(&self) -> StatusCode {
292        self.head.status
293    }
294
295    /// Returns a mutable reference to the associated `StatusCode`.
296    ///
297    /// # Examples
298    ///
299    /// ```
300    /// # use http::*;
301    /// let mut response: Response<()> = Response::default();
302    /// *response.status_mut() = StatusCode::CREATED;
303    /// assert_eq!(response.status(), StatusCode::CREATED);
304    /// ```
305    #[inline]
306    pub fn status_mut(&mut self) -> &mut StatusCode {
307        &mut self.head.status
308    }
309
310    /// Returns a reference to the associated version.
311    ///
312    /// # Examples
313    ///
314    /// ```
315    /// # use http::*;
316    /// let response: Response<()> = Response::default();
317    /// assert_eq!(response.version(), Version::HTTP_11);
318    /// ```
319    #[inline]
320    pub fn version(&self) -> Version {
321        self.head.version
322    }
323
324    /// Returns a mutable reference to the associated version.
325    ///
326    /// # Examples
327    ///
328    /// ```
329    /// # use http::*;
330    /// let mut response: Response<()> = Response::default();
331    /// *response.version_mut() = Version::HTTP_2;
332    /// assert_eq!(response.version(), Version::HTTP_2);
333    /// ```
334    #[inline]
335    pub fn version_mut(&mut self) -> &mut Version {
336        &mut self.head.version
337    }
338
339    /// Returns a reference to the associated header field map.
340    ///
341    /// # Examples
342    ///
343    /// ```
344    /// # use http::*;
345    /// let response: Response<()> = Response::default();
346    /// assert!(response.headers().is_empty());
347    /// ```
348    #[inline]
349    pub fn headers(&self) -> &HeaderMap<HeaderValue> {
350        &self.head.headers
351    }
352
353    /// Returns a mutable reference to the associated header field map.
354    ///
355    /// # Examples
356    ///
357    /// ```
358    /// # use http::*;
359    /// # use http::header::*;
360    /// let mut response: Response<()> = Response::default();
361    /// response.headers_mut().insert(HOST, HeaderValue::from_static("world"));
362    /// assert!(!response.headers().is_empty());
363    /// ```
364    #[inline]
365    pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
366        &mut self.head.headers
367    }
368
369    /// Returns a reference to the associated extensions.
370    ///
371    /// # Examples
372    ///
373    /// ```
374    /// # use http::*;
375    /// let response: Response<()> = Response::default();
376    /// assert!(response.extensions().get::<i32>().is_none());
377    /// ```
378    #[inline]
379    pub fn extensions(&self) -> &Extensions {
380        &self.head.extensions
381    }
382
383    /// Returns a mutable reference to the associated extensions.
384    ///
385    /// # Examples
386    ///
387    /// ```
388    /// # use http::*;
389    /// # use http::header::*;
390    /// let mut response: Response<()> = Response::default();
391    /// response.extensions_mut().insert("hello");
392    /// assert_eq!(response.extensions().get(), Some(&"hello"));
393    /// ```
394    #[inline]
395    pub fn extensions_mut(&mut self) -> &mut Extensions {
396        &mut self.head.extensions
397    }
398
399    /// Returns a reference to the associated HTTP body.
400    ///
401    /// # Examples
402    ///
403    /// ```
404    /// # use http::*;
405    /// let response: Response<String> = Response::default();
406    /// assert!(response.body().is_empty());
407    /// ```
408    #[inline]
409    pub fn body(&self) -> &T {
410        &self.body
411    }
412
413    /// Returns a mutable reference to the associated HTTP body.
414    ///
415    /// # Examples
416    ///
417    /// ```
418    /// # use http::*;
419    /// let mut response: Response<String> = Response::default();
420    /// response.body_mut().push_str("hello world");
421    /// assert!(!response.body().is_empty());
422    /// ```
423    #[inline]
424    pub fn body_mut(&mut self) -> &mut T {
425        &mut self.body
426    }
427
428    /// Consumes the response, returning just the body.
429    ///
430    /// # Examples
431    ///
432    /// ```
433    /// # use http::Response;
434    /// let response = Response::new(10);
435    /// let body = response.into_body();
436    /// assert_eq!(body, 10);
437    /// ```
438    #[inline]
439    pub fn into_body(self) -> T {
440        self.body
441    }
442
443    /// Consumes the response returning the head and body parts.
444    ///
445    /// # Examples
446    ///
447    /// ```
448    /// # use http::*;
449    /// let response: Response<()> = Response::default();
450    /// let (parts, body) = response.into_parts();
451    /// assert_eq!(parts.status, StatusCode::OK);
452    /// ```
453    #[inline]
454    pub fn into_parts(self) -> (Parts, T) {
455        (self.head, self.body)
456    }
457
458    /// Consumes the response returning a new response with body mapped to the
459    /// return type of the passed in function.
460    ///
461    /// # Examples
462    ///
463    /// ```
464    /// # use http::*;
465    /// let response = Response::builder().body("some string").unwrap();
466    /// let mapped_response: Response<&[u8]> = response.map(|b| {
467    ///   assert_eq!(b, "some string");
468    ///   b.as_bytes()
469    /// });
470    /// assert_eq!(mapped_response.body(), &"some string".as_bytes());
471    /// ```
472    #[inline]
473    pub fn map<F, U>(self, f: F) -> Response<U>
474    where
475        F: FnOnce(T) -> U,
476    {
477        Response {
478            body: f(self.body),
479            head: self.head,
480        }
481    }
482}
483
484impl<T: Default> Default for Response<T> {
485    #[inline]
486    fn default() -> Response<T> {
487        Response::new(T::default())
488    }
489}
490
491impl<T: fmt::Debug> fmt::Debug for Response<T> {
492    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
493        f.debug_struct("Response")
494            .field("status", &self.status())
495            .field("version", &self.version())
496            .field("headers", self.headers())
497            // omits Extensions because not useful
498            .field("body", self.body())
499            .finish()
500    }
501}
502
503impl Parts {
504    /// Creates a new default instance of `Parts`
505    fn new() -> Parts {
506        Parts {
507            status: StatusCode::default(),
508            version: Version::default(),
509            headers: HeaderMap::default(),
510            extensions: Extensions::default(),
511            _priv: (),
512        }
513    }
514}
515
516impl fmt::Debug for Parts {
517    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
518        f.debug_struct("Parts")
519            .field("status", &self.status)
520            .field("version", &self.version)
521            .field("headers", &self.headers)
522            // omits Extensions because not useful
523            // omits _priv because not useful
524            .finish()
525    }
526}
527
528impl Builder {
529    /// Creates a new default instance of `Builder` to construct either a
530    /// `Head` or a `Response`.
531    ///
532    /// # Examples
533    ///
534    /// ```
535    /// # use http::*;
536    ///
537    /// let response = response::Builder::new()
538    ///     .status(200)
539    ///     .body(())
540    ///     .unwrap();
541    /// ```
542    #[inline]
543    pub fn new() -> Builder {
544        Builder::default()
545    }
546
547    /// Set the HTTP status for this response.
548    ///
549    /// This function will configure the HTTP status code of the `Response` that
550    /// will be returned from `Builder::build`.
551    ///
552    /// By default this is `200`.
553    ///
554    /// # Examples
555    ///
556    /// ```
557    /// # use http::*;
558    ///
559    /// let response = Response::builder()
560    ///     .status(200)
561    ///     .body(())
562    ///     .unwrap();
563    /// ```
564    pub fn status<T>(self, status: T) -> Builder
565    where
566        StatusCode: TryFrom<T>,
567        <StatusCode as TryFrom<T>>::Error: Into<crate::Error>,
568    {
569        self.and_then(move |mut head| {
570            head.status = TryFrom::try_from(status).map_err(Into::into)?;
571            Ok(head)
572        })
573    }
574
575    /// Set the HTTP version for this response.
576    ///
577    /// This function will configure the HTTP version of the `Response` that
578    /// will be returned from `Builder::build`.
579    ///
580    /// By default this is HTTP/1.1
581    ///
582    /// # Examples
583    ///
584    /// ```
585    /// # use http::*;
586    ///
587    /// let response = Response::builder()
588    ///     .version(Version::HTTP_2)
589    ///     .body(())
590    ///     .unwrap();
591    /// ```
592    pub fn version(self, version: Version) -> Builder {
593        self.and_then(move |mut head| {
594            head.version = version;
595            Ok(head)
596        })
597    }
598
599    /// Appends a header to this response builder.
600    ///
601    /// This function will append the provided key/value as a header to the
602    /// internal `HeaderMap` being constructed. Essentially this is equivalent
603    /// to calling `HeaderMap::append`.
604    ///
605    /// # Examples
606    ///
607    /// ```
608    /// # use http::*;
609    /// # use http::header::HeaderValue;
610    ///
611    /// let response = Response::builder()
612    ///     .header("Content-Type", "text/html")
613    ///     .header("X-Custom-Foo", "bar")
614    ///     .header("content-length", 0)
615    ///     .body(())
616    ///     .unwrap();
617    /// ```
618    pub fn header<K, V>(self, key: K, value: V) -> Builder
619    where
620        HeaderName: TryFrom<K>,
621        <HeaderName as TryFrom<K>>::Error: Into<crate::Error>,
622        HeaderValue: TryFrom<V>,
623        <HeaderValue as TryFrom<V>>::Error: Into<crate::Error>,
624    {
625        self.and_then(move |mut head| {
626            let name = <HeaderName as TryFrom<K>>::try_from(key).map_err(Into::into)?;
627            let value = <HeaderValue as TryFrom<V>>::try_from(value).map_err(Into::into)?;
628            head.headers.append(name, value);
629            Ok(head)
630        })
631    }
632
633    /// Get header on this response builder.
634    ///
635    /// When builder has error returns None.
636    ///
637    /// # Example
638    ///
639    /// ```
640    /// # use http::Response;
641    /// # use http::header::HeaderValue;
642    /// let res = Response::builder()
643    ///     .header("Accept", "text/html")
644    ///     .header("X-Custom-Foo", "bar");
645    /// let headers = res.headers_ref().unwrap();
646    /// assert_eq!( headers["Accept"], "text/html" );
647    /// assert_eq!( headers["X-Custom-Foo"], "bar" );
648    /// ```
649    pub fn headers_ref(&self) -> Option<&HeaderMap<HeaderValue>> {
650        self.inner.as_ref().ok().map(|h| &h.headers)
651    }
652
653    /// Get header on this response builder.
654    /// when builder has error returns None
655    ///
656    /// # Example
657    ///
658    /// ```
659    /// # use http::*;
660    /// # use http::header::HeaderValue;
661    /// # use http::response::Builder;
662    /// let mut res = Response::builder();
663    /// {
664    ///   let headers = res.headers_mut().unwrap();
665    ///   headers.insert("Accept", HeaderValue::from_static("text/html"));
666    ///   headers.insert("X-Custom-Foo", HeaderValue::from_static("bar"));
667    /// }
668    /// let headers = res.headers_ref().unwrap();
669    /// assert_eq!( headers["Accept"], "text/html" );
670    /// assert_eq!( headers["X-Custom-Foo"], "bar" );
671    /// ```
672    pub fn headers_mut(&mut self) -> Option<&mut HeaderMap<HeaderValue>> {
673        self.inner.as_mut().ok().map(|h| &mut h.headers)
674    }
675
676    /// Adds an extension to this builder
677    ///
678    /// # Examples
679    ///
680    /// ```
681    /// # use http::*;
682    ///
683    /// let response = Response::builder()
684    ///     .extension("My Extension")
685    ///     .body(())
686    ///     .unwrap();
687    ///
688    /// assert_eq!(response.extensions().get::<&'static str>(),
689    ///            Some(&"My Extension"));
690    /// ```
691    pub fn extension<T>(self, extension: T) -> Builder
692    where
693        T: Any + Send + Sync + 'static,
694    {
695        self.and_then(move |mut head| {
696            head.extensions.insert(extension);
697            Ok(head)
698        })
699    }
700
701    /// Get a reference to the extensions for this response builder.
702    ///
703    /// If the builder has an error, this returns `None`.
704    ///
705    /// # Example
706    ///
707    /// ```
708    /// # use http::Response;
709    /// let req = Response::builder().extension("My Extension").extension(5u32);
710    /// let extensions = req.extensions_ref().unwrap();
711    /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension"));
712    /// assert_eq!(extensions.get::<u32>(), Some(&5u32));
713    /// ```
714    pub fn extensions_ref(&self) -> Option<&Extensions> {
715        self.inner.as_ref().ok().map(|h| &h.extensions)
716    }
717
718    /// Get a mutable reference to the extensions for this response builder.
719    ///
720    /// If the builder has an error, this returns `None`.
721    ///
722    /// # Example
723    ///
724    /// ```
725    /// # use http::Response;
726    /// let mut req = Response::builder().extension("My Extension");
727    /// let mut extensions = req.extensions_mut().unwrap();
728    /// assert_eq!(extensions.get::<&'static str>(), Some(&"My Extension"));
729    /// extensions.insert(5u32);
730    /// assert_eq!(extensions.get::<u32>(), Some(&5u32));
731    /// ```
732    pub fn extensions_mut(&mut self) -> Option<&mut Extensions> {
733        self.inner.as_mut().ok().map(|h| &mut h.extensions)
734    }
735
736    /// "Consumes" this builder, using the provided `body` to return a
737    /// constructed `Response`.
738    ///
739    /// # Errors
740    ///
741    /// This function may return an error if any previously configured argument
742    /// failed to parse or get converted to the internal representation. For
743    /// example if an invalid `head` was specified via `header("Foo",
744    /// "Bar\r\n")` the error will be returned when this function is called
745    /// rather than when `header` was called.
746    ///
747    /// # Examples
748    ///
749    /// ```
750    /// # use http::*;
751    ///
752    /// let response = Response::builder()
753    ///     .body(())
754    ///     .unwrap();
755    /// ```
756    pub fn body<T>(self, body: T) -> Result<Response<T>> {
757        self.inner.map(move |head| {
758            Response {
759                head,
760                body,
761            }
762        })
763    }
764
765    // private
766
767    fn and_then<F>(self, func: F) -> Self
768    where
769        F: FnOnce(Parts) -> Result<Parts>
770    {
771        Builder {
772            inner: self.inner.and_then(func),
773        }
774    }
775}
776
777impl Default for Builder {
778    #[inline]
779    fn default() -> Builder {
780        Builder {
781            inner: Ok(Parts::new()),
782        }
783    }
784}
785
786#[cfg(test)]
787mod tests {
788    use super::*;
789
790    #[test]
791    fn it_can_map_a_body_from_one_type_to_another() {
792        let response = Response::builder().body("some string").unwrap();
793        let mapped_response = response.map(|s| {
794            assert_eq!(s, "some string");
795            123u32
796        });
797        assert_eq!(mapped_response.body(), &123u32);
798    }
799}