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