tower_cookies/service/
future.rs1use crate::Cookies;
4use futures_util::ready;
5use http::{header, HeaderValue, Response};
6use pin_project_lite::pin_project;
7use std::{
8 future::Future,
9 pin::Pin,
10 task::{Context, Poll},
11};
12
13pin_project! {
14 #[derive(Debug)]
16 pub struct ResponseFuture<F> {
17 #[pin]
18 pub(crate) future: F,
19 pub(crate) cookies: Cookies,
20 }
21}
22
23impl<F, ResBody, E> Future for ResponseFuture<F>
24where
25 F: Future<Output = Result<Response<ResBody>, E>>,
26{
27 type Output = F::Output;
28
29 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
30 let this = self.project();
31 let mut res = ready!(this.future.poll(cx)?);
32
33 let mut cookies = this.cookies.inner.lock();
34 if cookies.changed {
35 let values: Vec<_> = cookies
36 .jar()
37 .delta()
38 .filter_map(|c| HeaderValue::from_str(&c.to_string()).ok())
39 .collect();
40 let headers = res.headers_mut();
41 for value in values {
42 headers.append(header::SET_COOKIE, value);
43 }
44 }
45
46 Poll::Ready(Ok(res))
47 }
48}