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
337    #[cfg(feature = "serde")]
338    pub async fn body_json<T: DeserializeOwned>(&mut self) -> crate::Result<T> {
339        let body = self.take_body();
340        body.into_json().await
341    }
342
343    /// Read the body as `x-www-form-urlencoded`.
344    ///
345    /// This consumes the request. If you want to read the body without
346    /// consuming the request, consider using the `take_body` method and
347    /// then calling `Body::into_json` or using the Response's AsyncRead
348    /// implementation to read the body.
349    ///
350    /// # Examples
351    ///
352    /// ```
353    /// # fn main() -> http_types::Result<()> { async_std::task::block_on(async {
354    /// use http_types::convert::{Deserialize, Serialize};
355    /// use http_types::{Body, Method, Response, StatusCode, Url};
356    ///
357    /// #[derive(Debug, Serialize, Deserialize)]
358    /// # #[serde(crate = "serde_crate")]
359    /// struct Cat {
360    ///     name: String,
361    /// }
362    ///
363    /// let cat = Cat {
364    ///     name: String::from("chashu"),
365    /// };
366    /// let mut res = Response::new(StatusCode::Ok);
367    /// res.set_body(Body::from_form(&cat)?);
368    ///
369    /// let cat: Cat = res.body_form().await?;
370    /// assert_eq!(&cat.name, "chashu");
371    /// # Ok(()) }) }
372    /// ```
373    #[cfg(feature = "serde")]
374    pub async fn body_form<T: DeserializeOwned>(&mut self) -> crate::Result<T> {
375        let body = self.take_body();
376        body.into_form().await
377    }
378
379    /// Set the response MIME.
380    pub fn set_content_type(&mut self, mime: Mime) -> Option<HeaderValues> {
381        let value: HeaderValue = mime.into();
382
383        // A Mime instance is guaranteed to be valid header name.
384        self.insert_header(CONTENT_TYPE, value).unwrap()
385    }
386
387    /// Copy MIME data from the body.
388    fn copy_content_type_from_body(&mut self) {
389        if self.header(CONTENT_TYPE).is_none() {
390            if let Some(mime) = self.body.mime().cloned() {
391                self.set_content_type(mime);
392            }
393        }
394    }
395
396    /// Get the current content type
397    pub fn content_type(&self) -> Option<Mime> {
398        self.header(CONTENT_TYPE)?.last().as_str().parse().ok()
399    }
400
401    /// Get the length of the body stream, if it has been set.
402    ///
403    /// This value is set when passing a fixed-size object into as the body.
404    /// E.g. a string, or a buffer. Consumers of this API should check this
405    /// value to decide whether to use `Chunked` encoding, or set the
406    /// response length.
407    pub fn len(&self) -> Option<u64> {
408        self.body.len()
409    }
410
411    /// Returns `true` if the set length of the body stream is zero, `false`
412    /// otherwise.
413    pub fn is_empty(&self) -> Option<bool> {
414        self.body.is_empty()
415    }
416
417    /// Get the HTTP version, if one has been set.
418    ///
419    /// # Examples
420    ///
421    /// ```
422    /// # fn main() -> Result<(), http_types::Error> {
423    /// #
424    /// use http_types::{Response, StatusCode, Version};
425    ///
426    /// let mut res = Response::new(StatusCode::Ok);
427    /// assert_eq!(res.version(), None);
428    ///
429    /// res.set_version(Some(Version::Http2_0));
430    /// assert_eq!(res.version(), Some(Version::Http2_0));
431    /// #
432    /// # Ok(()) }
433    /// ```
434    pub fn version(&self) -> Option<Version> {
435        self.version
436    }
437
438    /// Sets a string representation of the peer address that this
439    /// response was sent to. This might take the form of an ip/fqdn
440    /// and port or a local socket address.
441    pub fn set_peer_addr(&mut self, peer_addr: Option<impl std::string::ToString>) {
442        self.peer_addr = peer_addr.map(|addr| addr.to_string());
443    }
444
445    /// Sets a string representation of the local address that this
446    /// response was sent on. This might take the form of an ip/fqdn and
447    /// port, or a local socket address.
448    pub fn set_local_addr(&mut self, local_addr: Option<impl std::string::ToString>) {
449        self.local_addr = local_addr.map(|addr| addr.to_string());
450    }
451
452    /// Get the peer socket address for the underlying transport, if appropriate
453    pub fn peer_addr(&self) -> Option<&str> {
454        self.peer_addr.as_deref()
455    }
456
457    /// Get the local socket address for the underlying transport, if
458    /// appropriate
459    pub fn local_addr(&self) -> Option<&str> {
460        self.local_addr.as_deref()
461    }
462
463    /// Set the HTTP version.
464    ///
465    /// # Examples
466    ///
467    /// ```
468    /// # fn main() -> Result<(), http_types::Error> {
469    /// #
470    /// use http_types::{Response, StatusCode, Version};
471    ///
472    /// let mut res = Response::new(StatusCode::Ok);
473    /// res.set_version(Some(Version::Http2_0));
474    /// #
475    /// # Ok(()) }
476    /// ```
477    pub fn set_version(&mut self, version: Option<Version>) {
478        self.version = version;
479    }
480
481    /// Set the status.
482    pub fn set_status(&mut self, status: StatusCode) {
483        self.status = status;
484    }
485
486    /// Sends trailers to the a receiver.
487    pub fn send_trailers(&mut self) -> trailers::Sender {
488        self.has_trailers = true;
489        let sender = self
490            .trailers_sender
491            .take()
492            .expect("Trailers sender can only be constructed once");
493        trailers::Sender::new(sender)
494    }
495
496    /// Receive trailers from a sender.
497    pub fn recv_trailers(&mut self) -> trailers::Receiver {
498        let receiver = self
499            .trailers_receiver
500            .take()
501            .expect("Trailers receiver can only be constructed once");
502        trailers::Receiver::new(receiver)
503    }
504
505    /// Returns `true` if sending trailers is in progress.
506    pub fn has_trailers(&self) -> bool {
507        self.has_trailers
508    }
509
510    /// Sends an upgrade connection to the a receiver.
511    #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
512    pub fn send_upgrade(&mut self) -> upgrade::Sender {
513        self.has_upgrade = true;
514        let sender = self
515            .upgrade_sender
516            .take()
517            .expect("Upgrade sender can only be constructed once");
518        upgrade::Sender::new(sender)
519    }
520
521    /// Receive an upgraded connection from a sender.
522    #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
523    pub async fn recv_upgrade(&mut self) -> upgrade::Receiver {
524        self.has_upgrade = true;
525        let receiver = self
526            .upgrade_receiver
527            .take()
528            .expect("Upgrade receiver can only be constructed once");
529        upgrade::Receiver::new(receiver)
530    }
531
532    /// Returns `true` if a protocol upgrade is in progress.
533    #[cfg_attr(feature = "docs", doc(cfg(unstable)))]
534    pub fn has_upgrade(&self) -> bool {
535        self.has_upgrade
536    }
537
538    /// An iterator visiting all header pairs in arbitrary order.
539    pub fn iter(&self) -> headers::Iter<'_> {
540        self.headers.iter()
541    }
542
543    /// An iterator visiting all header pairs in arbitrary order, with mutable
544    /// references to the values.
545    pub fn iter_mut(&mut self) -> headers::IterMut<'_> {
546        self.headers.iter_mut()
547    }
548
549    /// An iterator visiting all header names in arbitrary order.
550    pub fn header_names(&self) -> Names<'_> {
551        self.headers.names()
552    }
553
554    /// An iterator visiting all header values in arbitrary order.
555    pub fn header_values(&self) -> Values<'_> {
556        self.headers.values()
557    }
558
559    /// Returns a reference to the existing local.
560    pub fn ext(&self) -> &Extensions {
561        &self.ext
562    }
563
564    /// Returns a mutuable reference to the existing local state.
565    ///
566    ///
567    /// # Examples
568    ///
569    /// ```
570    /// # fn main() -> Result<(), http_types::Error> {
571    /// #
572    /// use http_types::{Response, StatusCode, Version};
573    ///
574    /// let mut res = Response::new(StatusCode::Ok);
575    /// res.ext_mut().insert("hello from the extension");
576    /// assert_eq!(res.ext().get(), Some(&"hello from the extension"));
577    /// #
578    /// # Ok(()) }
579    /// ```
580    pub fn ext_mut(&mut self) -> &mut Extensions {
581        &mut self.ext
582    }
583}
584
585impl Clone for Response {
586    /// Clone the response, resolving the body to `Body::empty()` and removing
587    /// extensions.
588    fn clone(&self) -> Self {
589        Self {
590            status: self.status,
591            headers: self.headers.clone(),
592            version: self.version,
593            trailers_sender: self.trailers_sender.clone(),
594            trailers_receiver: self.trailers_receiver.clone(),
595            has_trailers: false,
596            upgrade_sender: self.upgrade_sender.clone(),
597            upgrade_receiver: self.upgrade_receiver.clone(),
598            has_upgrade: false,
599            body: Body::empty(),
600            ext: Extensions::new(),
601            peer_addr: self.peer_addr.clone(),
602            local_addr: self.local_addr.clone(),
603        }
604    }
605}
606
607impl AsyncRead for Response {
608    #[allow(rustdoc::missing_doc_code_examples)]
609    fn poll_read(
610        mut self: Pin<&mut Self>,
611        cx: &mut Context<'_>,
612        buf: &mut [u8],
613    ) -> Poll<io::Result<usize>> {
614        Pin::new(&mut self.body).poll_read(cx, buf)
615    }
616}
617
618impl AsyncBufRead for Response {
619    #[allow(rustdoc::missing_doc_code_examples)]
620    fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&'_ [u8]>> {
621        let this = self.project();
622        this.body.poll_fill_buf(cx)
623    }
624
625    fn consume(mut self: Pin<&mut Self>, amt: usize) {
626        Pin::new(&mut self.body).consume(amt)
627    }
628}
629
630impl AsRef<Headers> for Response {
631    fn as_ref(&self) -> &Headers {
632        &self.headers
633    }
634}
635
636impl AsMut<Headers> for Response {
637    fn as_mut(&mut self) -> &mut Headers {
638        &mut self.headers
639    }
640}
641
642impl From<()> for Response {
643    fn from(_: ()) -> Self {
644        Response::new(StatusCode::NoContent)
645    }
646}
647impl Index<HeaderName> for Response {
648    type Output = HeaderValues;
649
650    /// Returns a reference to the value corresponding to the supplied name.
651    ///
652    /// # Panics
653    ///
654    /// Panics if the name is not present in `Response`.
655    #[inline]
656    fn index(&self, name: HeaderName) -> &HeaderValues {
657        self.headers.index(name)
658    }
659}
660
661impl Index<&str> for Response {
662    type Output = HeaderValues;
663
664    /// Returns a reference to the value corresponding to the supplied name.
665    ///
666    /// # Panics
667    ///
668    /// Panics if the name is not present in `Response`.
669    #[inline]
670    fn index(&self, name: &str) -> &HeaderValues {
671        self.headers.index(name)
672    }
673}
674
675impl From<StatusCode> for Response {
676    fn from(s: StatusCode) -> Self {
677        Response::new(s)
678    }
679}
680
681impl<T> From<T> for Response
682where
683    T: Into<Body>,
684{
685    fn from(value: T) -> Self {
686        let body: Body = value.into();
687        let mut res = Response::new(StatusCode::Ok);
688        res.set_body(body);
689        res
690    }
691}
692
693impl IntoIterator for Response {
694    type Item = (HeaderName, HeaderValues);
695    type IntoIter = headers::IntoIter;
696
697    /// Returns a iterator of references over the remaining items.
698    #[inline]
699    fn into_iter(self) -> Self::IntoIter {
700        self.headers.into_iter()
701    }
702}
703
704impl<'a> IntoIterator for &'a Response {
705    type Item = (&'a HeaderName, &'a HeaderValues);
706    type IntoIter = headers::Iter<'a>;
707
708    #[inline]
709    fn into_iter(self) -> Self::IntoIter {
710        self.headers.iter()
711    }
712}
713
714impl<'a> IntoIterator for &'a mut Response {
715    type Item = (&'a HeaderName, &'a mut HeaderValues);
716    type IntoIter = headers::IterMut<'a>;
717
718    #[inline]
719    fn into_iter(self) -> Self::IntoIter {
720        self.headers.iter_mut()
721    }
722}
723
724#[cfg(test)]
725mod test {
726    use super::Response;
727
728    #[test]
729    fn construct_shorthand_with_valid_status_code() {
730        let _res = Response::new(200);
731    }
732
733    #[test]
734    #[should_panic(expected = "Could not convert into a valid `StatusCode`")]
735    fn construct_shorthand_with_invalid_status_code() {
736        let _res = Response::new(600);
737    }
738}