From f3e6f09c77d1b7cbc2f1160181b40754c15ef1bb Mon Sep 17 00:00:00 2001 From: Miraclx Date: Sat, 1 May 2021 15:24:50 +0100 Subject: [PATCH] add cookie adapter through actix-cookie subcrate --- Cargo.toml | 1 + actix-cookie/Cargo.toml | 17 +++++++++++++++ actix-cookie/src/lib.rs | 46 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 actix-cookie/Cargo.toml create mode 100644 actix-cookie/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 8d78c6939..4e233e6ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ "actix-cors", + "actix-cookie", "actix-identity", "actix-protobuf", "actix-protobuf/examples/prost-example", diff --git a/actix-cookie/Cargo.toml b/actix-cookie/Cargo.toml new file mode 100644 index 000000000..5d25d19c9 --- /dev/null +++ b/actix-cookie/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "actix-cookie" +version = "0.1.0" +authors = [ + "Near Inc ", +] +description = "Actix adapter for cookies functionality" +repository = "https://github.com/near/actix-extras.git" +license = "MIT OR Apache-2.0" +edition = "2018" + +[lib] +name = "actix_cookie" +path = "src/lib.rs" + +[dependencies] +actix-web = { version = "4.0.0-beta.6", default-features = false, features = ["cookies"] } diff --git a/actix-cookie/src/lib.rs b/actix-cookie/src/lib.rs new file mode 100644 index 000000000..35db093db --- /dev/null +++ b/actix-cookie/src/lib.rs @@ -0,0 +1,46 @@ +use std::cell::Ref; + +use actix_web::{ + cookie::{Cookie, ParseError as CookieParseError}, + dev::ServiceRequest, + http::header, + HttpMessage, +}; + +struct Cookies(Vec>); + +pub trait Cookied: HttpMessage { + fn cookies(&self) -> Result>>, CookieParseError> { + if self.extensions().get::().is_none() { + let mut cookies = Vec::new(); + for hdr in self.headers().get_all(header::COOKIE) { + let s = std::str::from_utf8(hdr.as_bytes()) + .map_err(CookieParseError::from)?; + for cookie_str in s.split(';').map(|s| s.trim()) { + if !cookie_str.is_empty() { + cookies.push(Cookie::parse_encoded(cookie_str)?.into_owned()); + } + } + } + self.extensions_mut().insert(Cookies(cookies)); + } + + Ok(Ref::map(self.extensions(), |ext| { + &ext.get::().unwrap().0 + })) + } + + /// Return request cookie. + fn cookie(&self, name: &str) -> Option> { + if let Ok(cookies) = self.cookies() { + for cookie in cookies.iter() { + if cookie.name() == name { + return Some(cookie.to_owned()); + } + } + } + None + } +} + +impl Cookied for ServiceRequest {}