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}