1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
use iron; pub use hyper::header::{CookiePair as Cookie, CookieJar}; use backend::{self, Request}; use server::header; use ::{Extensible}; struct CookieJarKey; impl ::typemap::Key for CookieJarKey { type Value = CookieJar<'static>; } pub trait CookieExt { fn find_cookie_jar(&mut self) -> Option<&mut CookieJar<'static>>; fn store_cookie_jar(&mut self, jar: CookieJar<'static>); fn cookies<'a>(&'a mut self) -> &'a mut CookieJar<'static> { self.find_cookie_jar().unwrap() } } impl<'r> CookieExt for (backend::Request + 'r) { fn find_cookie_jar<'a>(&'a mut self) -> Option<&'a mut CookieJar<'static>> { self.ext_mut().get_mut::<CookieJarKey>() } fn store_cookie_jar(&mut self, jar: CookieJar<'static>) { self.ext_mut().insert::<CookieJarKey>(jar); } } pub struct CookieDecodeMiddleware { secret_token: Vec<u8> } impl iron::BeforeMiddleware for CookieDecodeMiddleware { fn before(&self, req: &mut iron::Request) -> iron::IronResult<()> { let token = &self.secret_token; let jar = req.headers().get::<header::Cookie>() .map(|cookies| cookies.to_cookie_jar(token)) .unwrap_or_else(|| CookieJar::new(token)); req.ext_mut().insert::<CookieJarKey>(jar); Ok(()) } } #[allow(missing_copy_implementations)] pub struct CookieEncodeMiddleware; impl iron::AfterMiddleware for CookieEncodeMiddleware { fn after(&self, req: &mut iron::Request, mut res: iron::Response) -> iron::IronResult<iron::Response> { let maybe_jar = (req as &mut backend::Request).find_cookie_jar(); match maybe_jar { Some(jar) => { res.headers.set(header::SetCookie::from_cookie_jar(jar)); }, None => () } Ok(res) } } pub fn new(secret_token: &[u8]) -> (CookieDecodeMiddleware, CookieEncodeMiddleware) { ( CookieDecodeMiddleware{secret_token: secret_token.to_vec()}, CookieEncodeMiddleware ) }