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}