warp/filters/
cookie.rs

1//! Cookie Filters
2
3use futures_util::future;
4use headers::Cookie;
5
6use super::header;
7use crate::filter::{Filter, One};
8use crate::reject::Rejection;
9use std::convert::Infallible;
10use std::str::FromStr;
11
12/// Creates a `Filter` that requires a cookie by name.
13///
14/// If found, extracts the value of the cookie, otherwise rejects.
15pub fn cookie<T>(name: &'static str) -> impl Filter<Extract = One<T>, Error = Rejection> + Copy
16where
17    T: FromStr + Send + 'static,
18{
19    header::header2().and_then(move |cookie: Cookie| {
20        let cookie = cookie
21            .get(name)
22            .ok_or_else(|| crate::reject::missing_cookie(name))
23            .and_then(|s| T::from_str(s).map_err(|_| crate::reject::missing_cookie(name)));
24        future::ready(cookie)
25    })
26}
27
28/// Creates a `Filter` that looks for an optional cookie by name.
29///
30/// If found, extracts the value of the cookie, otherwise continues
31/// the request, extracting `None`.
32pub fn optional<T>(
33    name: &'static str,
34) -> impl Filter<Extract = One<Option<T>>, Error = Infallible> + Copy
35where
36    T: FromStr + Send + 'static,
37{
38    header::optional2().map(move |opt: Option<Cookie>| {
39        let cookie = opt.and_then(|cookie| cookie.get(name).map(|x| T::from_str(x)));
40        match cookie {
41            Some(Ok(t)) => Some(t),
42            Some(Err(_)) => None,
43            None => None,
44        }
45    })
46}