pavex/cookie/
components.rs1use crate::Response;
2use crate::cookie::ResponseCookies;
3use crate::cookie::errors::{ExtractRequestCookiesError, InjectResponseCookiesError};
4use crate::error::UnexpectedError;
5use crate::request::RequestHead;
6use biscotti::{Processor, RequestCookies};
7use http::HeaderValue;
8use http::header::{COOKIE, SET_COOKIE};
9use pavex_macros::{post_process, request_scoped};
10use tracing_log_error::log_error;
11
12#[request_scoped(pavex = crate)]
16pub fn extract_request_cookies<'request>(
17 request_head: &'request RequestHead,
18 processor: &Processor,
19) -> Result<RequestCookies<'request>, ExtractRequestCookiesError> {
20 fn extract_request_cookie<'request>(
21 header: &'request HeaderValue,
22 processor: &Processor,
23 cookies: &mut RequestCookies<'request>,
24 ) -> Result<(), ExtractRequestCookiesError> {
25 let header = header
26 .to_str()
27 .map_err(ExtractRequestCookiesError::InvalidHeaderValue)?;
28 cookies.extend_from_header(header, processor).map_err(|e| {
29 use biscotti::errors::ParseError::*;
30 match e {
31 MissingPair(e) => ExtractRequestCookiesError::MissingPair(e),
32 EmptyName(e) => ExtractRequestCookiesError::EmptyName(e),
33 Crypto(e) => ExtractRequestCookiesError::Crypto(e),
34 Decoding(e) => ExtractRequestCookiesError::Decoding(e),
35 _ => ExtractRequestCookiesError::Unexpected(UnexpectedError::new(e)),
36 }
37 })?;
38 Ok(())
39 }
40
41 let mut cookies = RequestCookies::new();
42 for header in request_head.headers.get_all(COOKIE).into_iter() {
43 if let Err(e) = extract_request_cookie(header, processor, &mut cookies) {
54 log_error!(
55 e,
56 level: tracing::Level::WARN,
57 "A request cookie is invalid, ignoring it"
58 );
59 }
60 }
61
62 Ok(cookies)
63}
64
65#[post_process(pavex = crate)]
70pub fn inject_response_cookies(
71 mut response: Response,
72 response_cookies: ResponseCookies,
73 processor: &Processor,
74) -> Result<Response, InjectResponseCookiesError> {
75 for value in response_cookies.header_values(processor) {
76 let value = HeaderValue::from_str(&value).map_err(|_| InjectResponseCookiesError {
77 invalid_header_value: value,
78 })?;
79 response = response.append_header(SET_COOKIE, value);
80 }
81 Ok(response)
82}