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}