From c0cdc39ba9ccdc3c7b0243fccd118fdeed44163e Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Sun, 24 Jun 2018 22:21:04 +0600 Subject: [PATCH] do not store cookies on client response --- src/client/response.rs | 47 ++++++++++++++---------------------------- src/server/settings.rs | 3 +++ tests/test_client.rs | 4 ++-- 3 files changed, 20 insertions(+), 34 deletions(-) diff --git a/src/client/response.rs b/src/client/response.rs index f76d058e5..28d6f51bf 100644 --- a/src/client/response.rs +++ b/src/client/response.rs @@ -1,5 +1,3 @@ -use std::cell::UnsafeCell; -use std::rc::Rc; use std::{fmt, str}; use bytes::Bytes; @@ -32,64 +30,49 @@ impl Default for ClientMessage { } /// An HTTP Client response -pub struct ClientResponse(Rc>, Option>); +pub struct ClientResponse(ClientMessage, Option>); impl HttpMessage for ClientResponse { /// Get the headers from the response. #[inline] fn headers(&self) -> &HeaderMap { - &self.as_ref().headers + &self.0.headers } } impl 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) { 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. #[inline] pub fn version(&self) -> Version { - self.as_ref().version + self.0.version } /// Get the status from the server. #[inline] pub fn status(&self) -> StatusCode { - self.as_ref().status + self.0.status } /// Load response cookies. - pub fn cookies(&self) -> Result<&Vec>, CookieParseError> { - if self.as_ref().cookies.is_none() { - let msg = self.as_mut(); - let mut cookies = Vec::new(); - for val in msg.headers.get_all(header::SET_COOKIE).iter() { - let s = str::from_utf8(val.as_bytes()).map_err(CookieParseError::from)?; - cookies.push(Cookie::parse_encoded(s)?.into_owned()); - } - msg.cookies = Some(cookies) + pub fn cookies(&self) -> Result>, CookieParseError> { + let mut cookies = Vec::new(); + for val in self.0.headers.get_all(header::SET_COOKIE).iter() { + let s = str::from_utf8(val.as_bytes()).map_err(CookieParseError::from)?; + cookies.push(Cookie::parse_encoded(s)?.into_owned()); } - Ok(self.as_ref().cookies.as_ref().unwrap()) + Ok(cookies) } /// Return request cookie. - pub fn cookie(&self, name: &str) -> Option<&Cookie> { + pub fn cookie(&self, name: &str) -> Option { if let Ok(cookies) = self.cookies() { for cookie in cookies { if cookie.name() == name { @@ -132,11 +115,11 @@ mod tests { #[test] fn test_debug() { - let resp = ClientResponse::new(ClientMessage::default()); - resp.as_mut() + let mut resp = ClientResponse::new(ClientMessage::default()); + resp.0 .headers .insert(header::COOKIE, HeaderValue::from_static("cookie1=value1")); - resp.as_mut() + resp.0 .headers .insert(header::COOKIE, HeaderValue::from_static("cookie2=value2")); diff --git a/src/server/settings.rs b/src/server/settings.rs index 0fc81fe59..4ec1cde21 100644 --- a/src/server/settings.rs +++ b/src/server/settings.rs @@ -124,6 +124,7 @@ impl ServerSettings { /// Returns default `CpuPool` for server pub fn cpu_pool(&self) -> &CpuPool { + // Unsafe: ServerSetting is !Sync, DEFAULT_CPUPOOL is protected by Mutex unsafe { let val = &mut *self.cpu_pool.get(); if val.is_none() { @@ -230,10 +231,12 @@ impl WorkerSettings { } pub fn update_date(&self) { + // Unsafe: WorkerSetting is !Sync and !Send unsafe { &mut *self.date.get() }.update(); } pub fn set_date(&self, dst: &mut BytesMut, full: bool) { + // Unsafe: WorkerSetting is !Sync and !Send unsafe { if full { let mut buf: [u8; 39] = mem::uninitialized(); diff --git a/tests/test_client.rs b/tests/test_client.rs index 0d058c510..dc147ccd3 100644 --- a/tests/test_client.rs +++ b/tests/test_client.rs @@ -425,9 +425,9 @@ fn test_client_cookie_handling() { let response = srv.execute(request.send()).unwrap(); assert!(response.status().is_success()); let c1 = response.cookie("cookie1").expect("Missing cookie1"); - assert_eq!(c1, &cookie1); + assert_eq!(c1, cookie1); let c2 = response.cookie("cookie2").expect("Missing cookie2"); - assert_eq!(c2, &cookie2); + assert_eq!(c2, cookie2); } #[test]