http_types_2/
response.rs

1use futures_lite::{io, prelude::*};
2
3use std::convert::{Into, TryInto};
4use std::fmt::Debug;
5use std::mem;
6use std::ops::Index;
7use std::pin::Pin;
8use std::task::{Context, Poll};
9
10#[cfg(feature = "serde")]
11use crate::convert::DeserializeOwned;
12use crate::headers::{
13    self, HeaderName, HeaderValue, HeaderValues, Headers, Names, ToHeaderValues, Values,
14    CONTENT_TYPE,
15};
16use crate::mime::Mime;
17use crate::trailers::{self, Trailers};
18use crate::upgrade;
19use crate::{Body, Extensions, StatusCode, Version};
20
21pin_project_lite::pin_project! {
22    /// An HTTP response.
23    ///
24    /// # Examples
25    ///
26    /// ```
27    /// # fn main() -> Result<(), http_types::Error> {
28    /// #
29    /// use http_types::{Response, StatusCode};
30    ///
31    /// let mut res = Response::new(StatusCode::Ok);
32    /// res.set_body("Hello, Nori!");
33    /// #
34    /// # Ok(()) }
35    /// ```
36    #[derive(Debug)]
37    pub struct Response {
38        status: StatusCode,
39        headers: Headers,
40        version: Option<Version>,
41        has_trailers: bool,
42        trailers_sender: Option<async_channel::Sender<Trailers>>,
43        trailers_receiver: Option<async_channel::Receiver<Trailers>>,
44        upgrade_sender: Option<async_channel::Sender<upgrade::Connection>>,
45        upgrade_receiver: Option<async_channel::Receiver<upgrade::Connection>>,
46        has_upgrade: bool,
47        #[pin]
48        body: Body,
49        ext: Extensions,
50        local_addr: Option<String>,
51        peer_addr: Option<String>,
52    }
53}
54
55impl Response {
56    /// Create a new response.
57    pub fn new<S>(status: S) -> Self
58    where
59        S: TryInto<StatusCode>,
60        S::Error: Debug,
61    {
62        let status = status
63            .try_into()
64            .expect("Could not convert into a valid `StatusCode`");
65        let (trailers_sender, trailers_receiver) = async_channel::bounded(1);
66        let (upgrade_sender, upgrade_receiver) = async_channel::bounded(1);
67        Self {
68            status,
69            headers: Headers::new(),
70            version: None,
71            body: Body::empty(),
72            trailers_sender: Some(trailers_sender),
73            trailers_receiver: Some(trailers_receiver),
74            has_trailers: false,
75            upgrade_sender: Some(upgrade_sender),
76            upgrade_receiver: Some(upgrade_receiver),
77            has_upgrade: false,
78            ext: Extensions::new(),
79            peer_addr: None,
80            local_addr: None,
81        }
82    }
83
84    /// Get the status
85    pub fn status(&self) -> StatusCode {
86        self.status
87    }
88
89    /// Get a mutable reference to a header.
90    pub fn header_mut(&mut self, name: impl Into<HeaderName>) -> Option<&mut HeaderValues> {
91        self.headers.get_mut(name.into())
92    }
93
94    /// Get an HTTP header.
95    pub fn header(&self, name: impl Into<HeaderName>) -> Option<&HeaderValues> {
96        self.headers.get(name.into())
97    }
98
99    /// Remove a header.
100    pub fn remove_header(&mut self, name: impl Into<HeaderName>) -> Option<HeaderValues> {
101        self.headers.remove(name.into())
102    }
103
104    /// Set an HTTP header.
105    ///
106    /// # Examples
107    ///
108    /// ```
109    /// # fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
110    /// #
111    /// use http_types::{Method, Response, StatusCode, Url};
112    ///
113    /// let mut req = Response::new(StatusCode::Ok);
114    /// req.insert_header("Content-Type", "text/plain");
115    /// #
116    /// # Ok(()) }
117    /// ```
118    pub fn insert_header(
119        &mut self,
120        name: impl Into<HeaderName>,
121        values: impl ToHeaderValues,
122    ) -> crate::Result<Option<HeaderValues>> {
123        self.headers.insert(name, values)
124    }
125
126    /// Append a header to the headers.
127    ///
128    /// Unlike `insert` this function will not override the contents of a
129    /// header, but insert a header if there aren't any. Or else append to
130    /// the existing list of headers.
131    ///
132    /// # Examples
133    ///
134    /// ```
135    /// # fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
136    /// #
137    /// use http_types::{Response, StatusCode};
138    ///
139    /// let mut res = Response::new(StatusCode::Ok);
140    /// res.append_header("Content-Type", "text/plain");
141    /// #
142    /// # Ok(()) }
143    /// ```
144    pub fn append_header(
145        &mut self,
146        name: impl Into<HeaderName>,
147        values: impl ToHeaderValues,
148    ) -> crate::Result<()> {
149        self.headers.append(name, values)
150    }
151
152    /// Set the body reader.
153    ///
154    /// # Examples
155    ///
156    /// ```
157    /// # fn main() -> Result<(), http_types::Error> {
158    /// #
159    /// use http_types::{Response, StatusCode};
160    ///
161    /// let mut res = Response::new(StatusCode::Ok);
162    /// res.set_body("Hello, Nori!");
163    /// #
164    /// # Ok(()) }
165    /// ```
166    pub fn set_body(&mut self, body: impl Into<Body>) {
167        self.replace_body(body);
168    }
169
170    /// Replace the response body with a new body, returning the old body.
171    ///
172    /// # Examples
173    ///
174    /// ```
175    /// # use async_std::io::prelude::*;
176    /// # fn main() -> http_types::Result<()> { async_std::task::block_on(async {
177    /// #
178    /// use http_types::{Body, Method, Response, StatusCode, Url};
179    ///
180    /// let mut req = Response::new(StatusCode::Ok);
181    /// req.set_body("Hello, Nori!");
182    ///
183    /// let mut body: Body = req.replace_body("Hello, Chashu");
184    ///
185    /// let mut string = String::new();
186    /// body.read_to_string(&mut string).await?;
187    /// assert_eq!(&string, "Hello, Nori!");
188    /// #
189    /// # Ok(()) }) }
190    /// ```
191    pub fn replace_body(&mut self, body: impl Into<Body>) -> Body {
192        let body = mem::replace(&mut self.body, body.into());
193        self.copy_content_type_from_body();
194        body
195    }
196
197    /// Swaps the value of the body with another body, without deinitializing
198    /// either one.
199    ///
200    /// # Examples
201    ///
202    /// ```
203    /// # use async_std::io::prelude::*;
204    /// # fn main() -> http_types::Result<()> { async_std::task::block_on(async {
205    /// #
206    /// use http_types::{Body, Method, Response, StatusCode, Url};
207    ///
208    /// let mut req = Response::new(StatusCode::Ok);
209    /// req.set_body("Hello, Nori!");
210    ///
211    /// let mut body = "Hello, Chashu!".into();
212    /// req.swap_body(&mut body);
213    ///
214    /// let mut string = String::new();
215    /// body.read_to_string(&mut string).await?;
216    /// assert_eq!(&string, "Hello, Nori!");
217    /// #
218    /// # Ok(()) }) }
219    /// ```
220    pub fn swap_body(&mut self, body: &mut Body) {
221        mem::swap(&mut self.body, body);
222        self.copy_content_type_from_body();
223    }
224
225    /// Take the response body, replacing it with an empty body.
226    ///
227    /// # Examples
228    ///
229    /// ```
230    /// # use async_std::io::prelude::*;
231    /// # fn main() -> http_types::Result<()> { async_std::task::block_on(async {
232    /// #
233    /// use http_types::{Body, Method, Response, StatusCode, Url};
234    ///
235    /// let mut req = Response::new(StatusCode::Ok);
236    /// req.set_body("Hello, Nori!");
237    /// let mut body: Body = req.take_body();
238    ///
239    /// let mut string = String::new();
240    /// body.read_to_string(&mut string).await?;
241    /// assert_eq!(&string, "Hello, Nori!");
242    ///
243    /// # let mut string = String::new();
244    /// # req.read_to_string(&mut string).await?;
245    /// # assert_eq!(&string, "");
246    /// #
247    /// # Ok(()) }) }
248    /// ```
249    pub fn take_body(&mut self) -> Body {
250        self.replace_body(Body::empty())
251    }
252
253    /// Read the body as a string.
254    ///
255    /// This consumes the response. If you want to read the body without
256    /// consuming the response, consider using the `take_body` method and
257    /// then calling `Body::into_string` or using the Response's AsyncRead
258    /// implementation to read the body.
259    ///
260    /// # Examples
261    ///
262    /// ```
263    /// # use std::io::prelude::*;
264    /// # fn main() -> http_types::Result<()> { async_std::task::block_on(async {
265    /// use async_std::io::Cursor;
266    /// use http_types::{Body, Method, Response, StatusCode, Url};
267    ///
268    /// let mut res = Response::new(StatusCode::Ok);
269    /// let cursor = Cursor::new("Hello Nori");
270    /// let body = Body::from_reader(cursor, None);
271    /// res.set_body(body);
272    /// assert_eq!(&res.body_string().await.unwrap(), "Hello Nori");
273    /// # Ok(()) }) }
274    /// ```
275    pub async fn body_string(&mut self) -> crate::Result<String> {
276        let body = self.take_body();
277        body.into_string().await
278    }
279
280    /// Read the body as bytes.
281    ///
282    /// This consumes the `Response`. If you want to read the body without
283    /// consuming the response, consider using the `take_body` method and
284    /// then calling `Body::into_bytes` or using the Response's AsyncRead
285    /// implementation to read the body.
286    ///
287    /// # Examples
288    ///
289    /// ```
290    /// # fn main() -> http_types::Result<()> { async_std::task::block_on(async {
291    /// use http_types::{Body, Method, Response, StatusCode, Url};
292    ///
293    /// let bytes = vec![1, 2, 3];
294    /// let mut res = Response::new(StatusCode::Ok);
295    /// res.set_body(Body::from_bytes(bytes));
296    ///
297    /// let bytes = res.body_bytes().await?;
298    /// assert_eq!(bytes, vec![1, 2, 3]);
299    /// # Ok(()) }) }
300    /// ```
301    pub async fn body_bytes(&mut self) -> crate::Result<Vec<u8>> {
302        let body = self.take_body();
303        body.into_bytes().await
304    }
305
306    /// Read the body as JSON.
307    ///
308    /// This consumes the response. If you want to read the body without
309    /// consuming the response, consider using the `take_body` method and
310    /// then calling `Body::into_json` or using the Response's AsyncRead
311    /// implementation to read the body.
312    ///
313    /// # Examples
314    ///
315    /// ```
316    /// # fn main() -> http_types::Result<()> { async_std::task::block_on(async {
317    /// use http_types::convert::{Deserialize, Serialize};
318    /// use http_types::{Body, Method, Response, StatusCode, Url};
319    ///
320    /// #[derive(Debug, Serialize, Deserialize)]
321    /// # #[serde(crate = "serde_crate")]
322    /// struct Cat {
323    ///     name: String,
324    /// }
325    ///
326    /// let cat = Cat {
327    ///     name: String::from("chashu"),
328    /// };
329    /// let mut res = Response::new(StatusCode::Ok);
330    /// res.set_body(Body::from_json(&cat)?);
331    ///
332    /// let cat: Cat = res.body_json().await?;
333    /// assert_eq!(&cat.name, "chashu");
334    /// # Ok(()) }) }
335    /// ```
336    #[cfg(feature = "serde")]
337    pub async fn body_json<T: DeserializeOwned>(&mut self) -> crate::Result<T> {
338        let body = self.take_body();
339        body.into_json().await
340    }
341
342    /// Read the body as `x-www-form-urlencoded`.
343    ///
344    /// This consumes the request. If you want to read the body without
345    /// consuming the request, consider using the `take_body` method and
346    /// then calling `Body::into_json` or using the Response's AsyncRead
347    /// implementation to read the body.
348    ///
349    /// # Examples
350    ///
351    /// ```
352    /// # fn main() -> http_types::Result<()> { async_std::task::block_on(async {
353    /// use http_types::convert::{Deserialize, Serialize};
354    /// use http_types::{Body, Method, Response, StatusCode, Url};
355    ///
356    /// #[derive(Debug, Serialize, Deserialize)]
357    /// # #[serde(crate = "serde_crate")]
358    /// struct Cat {
359    ///     name: String,
360    /// }
361    ///
362    /// let cat = Cat {
363    ///     name: String::from("chashu"),
364    /// };
365    /// let mut res = Response::new(StatusCode::Ok);
366    /// res.set_body(Body::from_form(&cat)?);
367    ///
368    /// let cat: Cat = res.body_form().await?;
369    /// assert_eq!(&cat.name, "chashu");
370    /// # Ok(()) }) }
371    /// ```
372    #[cfg(feature = "serde")]
373    pub async fn body_form<T: DeserializeOwned>(&mut self) -> crate::Result<T> {
374        let body = self.take_body();
375        body.into_form().await
376    }
377
378    /// Set the response MIME.
379    pub fn set_content_type(&mut self, mime: Mime) -> Option<HeaderValues> {
380        let value: HeaderValue = mime.into();
381
382        // A Mime instance is guaranteed to be valid header name.
383        self.insert_header(CONTENT_TYPE, value).unwrap()
384    }
385
386    /// Copy MIME data from the body.
387    fn copy_content_type_from_body(&mut self) {
388        if self.header(CONTENT_TYPE).is_none() {
389            if let Some(mime) = self.body.mime().cloned() {
390                self.set_content_type(mime);
391            }
392        }
393    }
394
395    /// Get the current content type
396    pub fn content_type(&self) -> Option<Mime> {
397        self.header(CONTENT_TYPE)?.last().as_str().parse().ok()
398    }
399
400    /// Get the length of the body stream, if it has been set.
401    ///
402    /// This value is set when passing a fixed-size object into as the body.
403    /// E.g. a string, or a buffer. Consumers of this API should check this
404    /// value to decide whether to use `Chunked` encoding, or set the
405    /// response length.
406    pub fn len(&self) -> Option<u64> {
407        self.body.len()
408    }
409
410    /// Returns `true` if the set length of the body stream is zero, `false`
411    /// otherwise.
412    pub fn is_empty(&self) -> Option<bool> {
413        self.body.is_empty()
414    }
415
416    /// Get the HTTP version, if one has been set.
417    ///
418    /// # Examples
419    ///
420    /// ```
421    /// # fn main() -> Result<(), http_types::Error> {
422    /// #
423    /// use http_types::{Response, StatusCode, Version};
424    ///
425    /// let mut res = Response::new(StatusCode::Ok);
426    /// assert_eq!(res.version(), None);
427    ///
428    /// res.set_version(Some(Version::Http2_0));
429    /// assert_eq!(res.version(), Some(Version::Http2_0));
430    /// #
431    /// # Ok(()) }
432    /// ```
433    pub fn version(&self) -> Option<Version> {
434        self.version
435    }
436
437    /// Sets a string representation of the peer address that this
438    /// response was sent to. This might take the form of an ip/fqdn
439    /// and port or a local socket address.
440    pub fn set_peer_addr(&mut self, peer_addr: Option<impl std::string::ToString>) {
441        self.peer_addr = peer_addr.map(|addr| addr.to_string());
442    }
443
444    /// Sets a string representation of the local address that this
445    /// response was sent on. This might take the form of an ip/fqdn and
446    /// port, or a local socket address.
447    pub fn set_local_addr(&mut self, local_addr: Option<impl std::string::ToString>) {
448        self.local_addr = local_addr.map(|addr| addr.to_string());
449    }
450
451    /// Get the peer socket address for the underlying transport, if appropriate
452    pub fn peer_addr(&self) -> Option<&str> {
453        self.peer_addr.as_deref()
454    }
455
456    /// Get the local socket address for the underlying transport, if
457    /// appropriate
458    pub fn local_addr(&self) -> Option<&str> {
459        self.local_addr.as_deref()
460    }
461
462    /// Set the HTTP version.
463    ///
464    /// # Examples
465    ///
466    /// ```
467    /// # fn main() -> Result<(), http_types::Error> {
468    /// #
469    /// use http_types::{Response, StatusCode, Version};
470    ///
471    /// let mut res = Response::new(StatusCode::Ok);
472    /// res.set_version(Some(Version::Http2_0));
473    /// #
474    /// # Ok(()) }
475    /// ```
476    pub fn set_version(&mut self, version: Option<Version>) {
477        self.version = version;
478    }
479
480    /// Set the status.
481    pub fn set_status(&mut self, status: StatusCode) {
482        self.status = status;
483    }
484
485    /// Sends trailers to the a receiver.
486    pub fn send_trailers(&mut self) -> trailers::Sender {
487        self.has_trailers = true;
488        let sender = self
489            .trailers_sender
490            .take()
491            .expect("Trailers sender can only be constructed once");
492        trailers::Sender::new(sender)
493    }
494
495    /// Receive trailers from a sender.
496    pub fn recv_trailers(&mut self) -> trailers::Receiver {
497        let receiver = self
498            .trailers_receiver
499            .take()
500            .expect("Trailers receiver can only be constructed once");
501        trailers::Receiver::new(receiver)
502    }
503
504    /// Returns `true` if sending trailers is in progress.
505    pub fn has_trailers(&self) -> bool {
506        self.has_trailers
507    }
508
509    /// Sends an upgrade connection to the a receiver.
510    pub fn send_upgrade(&mut self) -> upgrade::Sender {
511        self.has_upgrade = true;
512        let sender = self
513            .upgrade_sender
514            .take()
515            .expect("Upgrade sender can only be constructed once");
516        upgrade::Sender::new(sender)
517    }
518
519    /// Receive an upgraded connection from a sender.
520    pub async fn recv_upgrade(&mut self) -> upgrade::Receiver {
521        self.has_upgrade = true;
522        let receiver = self
523            .upgrade_receiver
524            .take()
525            .expect("Upgrade receiver can only be constructed once");
526        upgrade::Receiver::new(receiver)
527    }
528
529    /// Returns `true` if a protocol upgrade is in progress.
530    pub fn has_upgrade(&self) -> bool {
531        self.has_upgrade
532    }
533
534    /// An iterator visiting all header pairs in arbitrary order.
535    pub fn iter(&self) -> headers::Iter<'_> {
536        self.headers.iter()
537    }
538
539    /// An iterator visiting all header pairs in arbitrary order, with mutable
540    /// references to the values.
541    pub fn iter_mut(&mut self) -> headers::IterMut<'_> {
542        self.headers.iter_mut()
543    }
544
545    /// An iterator visiting all header names in arbitrary order.
546    pub fn header_names(&self) -> Names<'_> {
547        self.headers.names()
548    }
549
550    /// An iterator visiting all header values in arbitrary order.
551    pub fn header_values(&self) -> Values<'_> {
552        self.headers.values()
553    }
554
555    /// Returns a reference to the existing local.
556    pub fn ext(&self) -> &Extensions {
557        &self.ext
558    }
559
560    /// Returns a mutuable reference to the existing local state.
561    ///
562    ///
563    /// # Examples
564    ///
565    /// ```
566    /// # fn main() -> Result<(), http_types::Error> {
567    /// #
568    /// use http_types::{Response, StatusCode, Version};
569    ///
570    /// let mut res = Response::new(StatusCode::Ok);
571    /// res.ext_mut().insert("hello from the extension");
572    /// assert_eq!(res.ext().get(), Some(&"hello from the extension"));
573    /// #
574    /// # Ok(()) }
575    /// ```
576    pub fn ext_mut(&mut self) -> &mut Extensions {
577        &mut self.ext
578    }
579}
580
581impl Clone for Response {
582    /// Clone the response, resolving the body to `Body::empty()` and removing
583    /// extensions.
584    fn clone(&self) -> Self {
585        Self {
586            status: self.status,
587            headers: self.headers.clone(),
588            version: self.version,
589            trailers_sender: self.trailers_sender.clone(),
590            trailers_receiver: self.trailers_receiver.clone(),
591            has_trailers: false,
592            upgrade_sender: self.upgrade_sender.clone(),
593            upgrade_receiver: self.upgrade_receiver.clone(),
594            has_upgrade: false,
595            body: Body::empty(),
596            ext: Extensions::new(),
597            peer_addr: self.peer_addr.clone(),
598            local_addr: self.local_addr.clone(),
599        }
600    }
601}
602
603impl AsyncRead for Response {
604    #[allow(rustdoc::missing_doc_code_examples)]
605    fn poll_read(
606        mut self: Pin<&mut Self>,
607        cx: &mut Context<'_>,
608        buf: &mut [u8],
609    ) -> Poll<io::Result<usize>> {
610        Pin::new(&mut self.body).poll_read(cx, buf)
611    }
612}
613
614impl AsyncBufRead for Response {
615    #[allow(rustdoc::missing_doc_code_examples)]
616    fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&'_ [u8]>> {
617        let this = self.project();
618        this.body.poll_fill_buf(cx)
619    }
620
621    fn consume(mut self: Pin<&mut Self>, amt: usize) {
622        Pin::new(&mut self.body).consume(amt)
623    }
624}
625
626impl AsRef<Headers> for Response {
627    fn as_ref(&self) -> &Headers {
628        &self.headers
629    }
630}
631
632impl AsMut<Headers> for Response {
633    fn as_mut(&mut self) -> &mut Headers {
634        &mut self.headers
635    }
636}
637
638impl From<()> for Response {
639    fn from(_: ()) -> Self {
640        Response::new(StatusCode::NoContent)
641    }
642}
643impl Index<HeaderName> for Response {
644    type Output = HeaderValues;
645
646    /// Returns a reference to the value corresponding to the supplied name.
647    ///
648    /// # Panics
649    ///
650    /// Panics if the name is not present in `Response`.
651    #[inline]
652    fn index(&self, name: HeaderName) -> &HeaderValues {
653        self.headers.index(name)
654    }
655}
656
657impl Index<&str> for Response {
658    type Output = HeaderValues;
659
660    /// Returns a reference to the value corresponding to the supplied name.
661    ///
662    /// # Panics
663    ///
664    /// Panics if the name is not present in `Response`.
665    #[inline]
666    fn index(&self, name: &str) -> &HeaderValues {
667        self.headers.index(name)
668    }
669}
670
671impl From<StatusCode> for Response {
672    fn from(s: StatusCode) -> Self {
673        Response::new(s)
674    }
675}
676
677impl<T> From<T> for Response
678where
679    T: Into<Body>,
680{
681    fn from(value: T) -> Self {
682        let body: Body = value.into();
683        let mut res = Response::new(StatusCode::Ok);
684        res.set_body(body);
685        res
686    }
687}
688
689impl IntoIterator for Response {
690    type Item = (HeaderName, HeaderValues);
691    type IntoIter = headers::IntoIter;
692
693    /// Returns a iterator of references over the remaining items.
694    #[inline]
695    fn into_iter(self) -> Self::IntoIter {
696        self.headers.into_iter()
697    }
698}
699
700impl<'a> IntoIterator for &'a Response {
701    type Item = (&'a HeaderName, &'a HeaderValues);
702    type IntoIter = headers::Iter<'a>;
703
704    #[inline]
705    fn into_iter(self) -> Self::IntoIter {
706        self.headers.iter()
707    }
708}
709
710impl<'a> IntoIterator for &'a mut Response {
711    type Item = (&'a HeaderName, &'a mut HeaderValues);
712    type IntoIter = headers::IterMut<'a>;
713
714    #[inline]
715    fn into_iter(self) -> Self::IntoIter {
716        self.headers.iter_mut()
717    }
718}
719
720#[cfg(test)]
721mod test {
722    use super::Response;
723
724    #[test]
725    fn construct_shorthand_with_valid_status_code() {
726        let _res = Response::new(200);
727    }
728
729    #[test]
730    #[should_panic(expected = "Could not convert into a valid `StatusCode`")]
731    fn construct_shorthand_with_invalid_status_code() {
732        let _res = Response::new(600);
733    }
734}