1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-28 01:32:57 +01:00

do not store cookies on client response

This commit is contained in:
Nikolay Kim 2018-06-24 22:21:04 +06:00
parent 8e8a68f90b
commit c0cdc39ba9
3 changed files with 20 additions and 34 deletions

View File

@ -1,5 +1,3 @@
use std::cell::UnsafeCell;
use std::rc::Rc;
use std::{fmt, str}; use std::{fmt, str};
use bytes::Bytes; use bytes::Bytes;
@ -32,64 +30,49 @@ impl Default for ClientMessage {
} }
/// An HTTP Client response /// An HTTP Client response
pub struct ClientResponse(Rc<UnsafeCell<ClientMessage>>, Option<Box<Pipeline>>); pub struct ClientResponse(ClientMessage, Option<Box<Pipeline>>);
impl HttpMessage for ClientResponse { impl HttpMessage for ClientResponse {
/// Get the headers from the response. /// Get the headers from the response.
#[inline] #[inline]
fn headers(&self) -> &HeaderMap { fn headers(&self) -> &HeaderMap {
&self.as_ref().headers &self.0.headers
} }
} }
impl ClientResponse { impl ClientResponse {
pub(crate) fn new(msg: ClientMessage) -> ClientResponse { pub(crate) fn new(msg: ClientMessage) -> ClientResponse {
ClientResponse(Rc::new(UnsafeCell::new(msg)), None) ClientResponse(msg, None)
} }
pub(crate) fn set_pipeline(&mut self, pl: Box<Pipeline>) { pub(crate) fn set_pipeline(&mut self, pl: Box<Pipeline>) {
self.1 = Some(pl); self.1 = Some(pl);
} }
#[inline]
fn as_ref(&self) -> &ClientMessage {
unsafe { &*self.0.get() }
}
#[inline]
#[cfg_attr(feature = "cargo-clippy", allow(mut_from_ref))]
fn as_mut(&self) -> &mut ClientMessage {
unsafe { &mut *self.0.get() }
}
/// Get the HTTP version of this response. /// Get the HTTP version of this response.
#[inline] #[inline]
pub fn version(&self) -> Version { pub fn version(&self) -> Version {
self.as_ref().version self.0.version
} }
/// Get the status from the server. /// Get the status from the server.
#[inline] #[inline]
pub fn status(&self) -> StatusCode { pub fn status(&self) -> StatusCode {
self.as_ref().status self.0.status
} }
/// Load response cookies. /// Load response cookies.
pub fn cookies(&self) -> Result<&Vec<Cookie<'static>>, CookieParseError> { pub fn cookies(&self) -> Result<Vec<Cookie<'static>>, CookieParseError> {
if self.as_ref().cookies.is_none() { let mut cookies = Vec::new();
let msg = self.as_mut(); for val in self.0.headers.get_all(header::SET_COOKIE).iter() {
let mut cookies = Vec::new(); let s = str::from_utf8(val.as_bytes()).map_err(CookieParseError::from)?;
for val in msg.headers.get_all(header::SET_COOKIE).iter() { cookies.push(Cookie::parse_encoded(s)?.into_owned());
let s = str::from_utf8(val.as_bytes()).map_err(CookieParseError::from)?;
cookies.push(Cookie::parse_encoded(s)?.into_owned());
}
msg.cookies = Some(cookies)
} }
Ok(self.as_ref().cookies.as_ref().unwrap()) Ok(cookies)
} }
/// Return request cookie. /// Return request cookie.
pub fn cookie(&self, name: &str) -> Option<&Cookie> { pub fn cookie(&self, name: &str) -> Option<Cookie> {
if let Ok(cookies) = self.cookies() { if let Ok(cookies) = self.cookies() {
for cookie in cookies { for cookie in cookies {
if cookie.name() == name { if cookie.name() == name {
@ -132,11 +115,11 @@ mod tests {
#[test] #[test]
fn test_debug() { fn test_debug() {
let resp = ClientResponse::new(ClientMessage::default()); let mut resp = ClientResponse::new(ClientMessage::default());
resp.as_mut() resp.0
.headers .headers
.insert(header::COOKIE, HeaderValue::from_static("cookie1=value1")); .insert(header::COOKIE, HeaderValue::from_static("cookie1=value1"));
resp.as_mut() resp.0
.headers .headers
.insert(header::COOKIE, HeaderValue::from_static("cookie2=value2")); .insert(header::COOKIE, HeaderValue::from_static("cookie2=value2"));

View File

@ -124,6 +124,7 @@ impl ServerSettings {
/// Returns default `CpuPool` for server /// Returns default `CpuPool` for server
pub fn cpu_pool(&self) -> &CpuPool { pub fn cpu_pool(&self) -> &CpuPool {
// Unsafe: ServerSetting is !Sync, DEFAULT_CPUPOOL is protected by Mutex
unsafe { unsafe {
let val = &mut *self.cpu_pool.get(); let val = &mut *self.cpu_pool.get();
if val.is_none() { if val.is_none() {
@ -230,10 +231,12 @@ impl<H> WorkerSettings<H> {
} }
pub fn update_date(&self) { pub fn update_date(&self) {
// Unsafe: WorkerSetting is !Sync and !Send
unsafe { &mut *self.date.get() }.update(); unsafe { &mut *self.date.get() }.update();
} }
pub fn set_date(&self, dst: &mut BytesMut, full: bool) { pub fn set_date(&self, dst: &mut BytesMut, full: bool) {
// Unsafe: WorkerSetting is !Sync and !Send
unsafe { unsafe {
if full { if full {
let mut buf: [u8; 39] = mem::uninitialized(); let mut buf: [u8; 39] = mem::uninitialized();

View File

@ -425,9 +425,9 @@ fn test_client_cookie_handling() {
let response = srv.execute(request.send()).unwrap(); let response = srv.execute(request.send()).unwrap();
assert!(response.status().is_success()); assert!(response.status().is_success());
let c1 = response.cookie("cookie1").expect("Missing cookie1"); let c1 = response.cookie("cookie1").expect("Missing cookie1");
assert_eq!(c1, &cookie1); assert_eq!(c1, cookie1);
let c2 = response.cookie("cookie2").expect("Missing cookie2"); let c2 = response.cookie("cookie2").expect("Missing cookie2");
assert_eq!(c2, &cookie2); assert_eq!(c2, cookie2);
} }
#[test] #[test]