http_types_rs/
response.rs

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