1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-27 09:42:57 +01:00

split request data container out from requesthead

This commit is contained in:
Rob Ede 2021-12-07 20:56:28 +00:00
parent d35b7644dc
commit 818c0f8cad
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
9 changed files with 62 additions and 51 deletions

View File

@ -19,7 +19,8 @@ impl Extensions {
#[inline]
pub fn new() -> Extensions {
Extensions {
map: AHashMap::default(),
map: AHashMap::with_capacity(2),
// map: AHashMap::new(),
}
}

View File

@ -50,7 +50,6 @@ pub struct RequestHead {
pub uri: Uri,
pub version: Version,
pub headers: HeaderMap,
pub extensions: RefCell<Extensions>,
pub peer_addr: Option<net::SocketAddr>,
flags: Flags,
}
@ -62,7 +61,6 @@ impl Default for RequestHead {
uri: Uri::default(),
version: Version::HTTP_11,
headers: HeaderMap::with_capacity(16),
extensions: RefCell::new(Extensions::new()),
peer_addr: None,
flags: Flags::empty(),
}
@ -73,7 +71,6 @@ impl Head for RequestHead {
fn clear(&mut self) {
self.flags = Flags::empty();
self.headers.clear();
self.extensions.get_mut().clear();
}
fn with_pool<F, R>(f: F) -> R
@ -85,18 +82,6 @@ impl Head for RequestHead {
}
impl RequestHead {
/// Message extensions
#[inline]
pub fn extensions(&self) -> Ref<'_, Extensions> {
self.extensions.borrow()
}
/// Mutable reference to a the message's extensions
#[inline]
pub fn extensions_mut(&self) -> RefMut<'_, Extensions> {
self.extensions.borrow_mut()
}
/// Read the message headers.
pub fn headers(&self) -> &HeaderMap {
&self.headers

View File

@ -1,7 +1,7 @@
//! HTTP requests.
use std::{
cell::{Ref, RefMut},
cell::{Ref, RefCell, RefMut},
fmt, net,
rc::Rc,
str,
@ -22,6 +22,7 @@ pub struct Request<P = PayloadStream> {
pub(crate) payload: Payload<P>,
pub(crate) head: Message<RequestHead>,
pub(crate) conn_data: Option<Rc<Extensions>>,
pub req_data: RefCell<Extensions>,
}
impl<P> HttpMessage for Request<P> {
@ -39,13 +40,13 @@ impl<P> HttpMessage for Request<P> {
/// Request extensions
#[inline]
fn extensions(&self) -> Ref<'_, Extensions> {
self.head.extensions()
self.req_data.borrow()
}
/// Mutable reference to a the request's extensions
#[inline]
fn extensions_mut(&self) -> RefMut<'_, Extensions> {
self.head.extensions_mut()
self.req_data.borrow_mut()
}
}
@ -54,6 +55,7 @@ impl From<Message<RequestHead>> for Request<PayloadStream> {
Request {
head,
payload: Payload::None,
req_data: RefCell::new(Extensions::new()),
conn_data: None,
}
}
@ -65,6 +67,7 @@ impl Request<PayloadStream> {
Request {
head: Message::new(),
payload: Payload::None,
req_data: RefCell::new(Extensions::new()),
conn_data: None,
}
}
@ -76,6 +79,7 @@ impl<P> Request<P> {
Request {
payload,
head: Message::new(),
req_data: RefCell::new(Extensions::new()),
conn_data: None,
}
}
@ -88,6 +92,7 @@ impl<P> Request<P> {
Request {
payload,
head: self.head,
req_data: self.req_data,
conn_data: self.conn_data,
},
pl,
@ -124,7 +129,7 @@ impl<P> Request<P> {
/// Mutable reference to the message's headers.
pub fn headers_mut(&mut self) -> &mut HeaderMap {
&mut self.head_mut().headers
&mut self.head.headers
}
/// Request's uri.
@ -136,7 +141,7 @@ impl<P> Request<P> {
/// Mutable reference to the request's uri.
#[inline]
pub fn uri_mut(&mut self) -> &mut Uri {
&mut self.head_mut().uri
&mut self.head.uri
}
/// Read the Request method.

View File

@ -198,6 +198,7 @@ where
actix_service::forward_ready!(service);
fn call(&self, mut req: Request) -> Self::Future {
let req_data = Rc::new(RefCell::new(req.req_data.take()));
let conn_data = req.take_conn_data();
let (head, payload) = req.into_parts();
@ -207,6 +208,7 @@ where
inner.path.reset();
inner.head = head;
inner.conn_data = conn_data;
inner.req_data = req_data;
req
} else {
HttpRequest::new(
@ -215,6 +217,7 @@ where
self.app_state.clone(),
self.app_data.clone(),
conn_data,
req_data,
)
};
self.service.call(ServiceRequest::new(req, payload))

View File

@ -1,4 +1,4 @@
use std::{cell::Ref, convert::Infallible, net::SocketAddr};
use std::{convert::Infallible, net::SocketAddr};
use actix_utils::future::{err, ok, Ready};
use derive_more::{Display, Error};
@ -72,15 +72,7 @@ pub struct ConnectionInfo {
}
impl ConnectionInfo {
/// Create *ConnectionInfo* instance for a request.
pub fn get<'a>(req: &'a RequestHead, cfg: &AppConfig) -> Ref<'a, Self> {
if !req.extensions().contains::<ConnectionInfo>() {
req.extensions_mut().insert(ConnectionInfo::new(req, cfg));
}
Ref::map(req.extensions(), |e| e.get().unwrap())
}
fn new(req: &RequestHead, cfg: &AppConfig) -> ConnectionInfo {
pub(crate) fn new(req: &RequestHead, cfg: &AppConfig) -> ConnectionInfo {
let mut host = None;
let mut scheme = None;
let mut realip_remote_addr = None;

View File

@ -38,6 +38,7 @@ pub(crate) struct HttpRequestInner {
pub(crate) path: Path<Url>,
pub(crate) app_data: SmallVec<[Rc<Extensions>; 4]>,
pub(crate) conn_data: Option<Rc<Extensions>>,
pub(crate) req_data: Rc<RefCell<Extensions>>,
app_state: Rc<AppInitServiceState>,
}
@ -49,6 +50,7 @@ impl HttpRequest {
app_state: Rc<AppInitServiceState>,
app_data: Rc<Extensions>,
conn_data: Option<Rc<Extensions>>,
req_data: Rc<RefCell<Extensions>>,
) -> HttpRequest {
let mut data = SmallVec::<[Rc<Extensions>; 4]>::new();
data.push(app_data);
@ -60,6 +62,7 @@ impl HttpRequest {
app_state,
app_data: data,
conn_data,
req_data,
}),
}
}
@ -156,16 +159,12 @@ impl HttpRequest {
self.resource_map().match_name(self.path())
}
/// Request extensions
#[inline]
pub fn extensions(&self) -> Ref<'_, Extensions> {
self.head().extensions()
pub fn req_data(&self) -> Ref<'_, Extensions> {
self.inner.req_data.borrow()
}
/// Mutable reference to a the request's extensions
#[inline]
pub fn extensions_mut(&self) -> RefMut<'_, Extensions> {
self.head().extensions_mut()
pub fn req_data_mut(&self) -> RefMut<'_, Extensions> {
self.inner.req_data.borrow_mut()
}
/// Returns a reference a piece of connection data set in an [on-connect] callback.
@ -248,7 +247,12 @@ impl HttpRequest {
/// borrowed.
#[inline]
pub fn connection_info(&self) -> Ref<'_, ConnectionInfo> {
ConnectionInfo::get(self.head(), self.app_config())
if !self.extensions().contains::<ConnectionInfo>() {
let info = ConnectionInfo::new(self.head(), &*self.app_config());
self.extensions_mut().insert(info);
}
Ref::map(self.extensions(), |e| e.get().unwrap())
}
/// App config
@ -329,13 +333,13 @@ impl HttpMessage for HttpRequest {
/// Request extensions
#[inline]
fn extensions(&self) -> Ref<'_, Extensions> {
self.inner.head.extensions()
self.req_data()
}
/// Mutable reference to a the request's extensions
#[inline]
fn extensions_mut(&self) -> RefMut<'_, Extensions> {
self.inner.head.extensions_mut()
self.req_data_mut()
}
#[inline]
@ -348,14 +352,14 @@ impl Drop for HttpRequest {
fn drop(&mut self) {
// if possible, contribute to current worker's HttpRequest allocation pool
// This relies on no Weak<HttpRequestInner> exists anywhere.(There is none)
// This relies on no Weak<HttpRequestInner> exists anywhere. (There is none.)
if let Some(inner) = Rc::get_mut(&mut self.inner) {
if inner.app_state.pool().is_available() {
// clear additional app_data and keep the root one for reuse.
inner.app_data.truncate(1);
// inner is borrowed mut here. get head's Extension mutably
// to reduce borrow check
inner.head.extensions.get_mut().clear();
// inner is borrowed mut here; get req data mutably to reduce borrow check
Rc::get_mut(&mut inner.req_data).unwrap().get_mut().clear();
// a re-borrow of pool is necessary here.
let req = self.inner.clone();

View File

@ -68,7 +68,7 @@ impl<T: Clone + 'static> FromRequest for ReqData<T> {
type Future = Ready<Result<Self, Error>>;
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
if let Some(st) = req.extensions().get::<T>() {
if let Some(st) = req.req_data().get::<T>() {
ok(ReqData(st.clone()))
} else {
log::debug!(

View File

@ -194,7 +194,7 @@ impl ServiceRequest {
/// Get *ConnectionInfo* for the current request.
#[inline]
pub fn connection_info(&self) -> Ref<'_, ConnectionInfo> {
ConnectionInfo::get(self.head(), &*self.app_config())
self.req.connection_info()
}
/// Get a reference to the Path parameters.

View File

@ -581,7 +581,14 @@ impl TestRequest {
let app_state = AppInitServiceState::new(Rc::new(self.rmap), self.config.clone());
ServiceRequest::new(
HttpRequest::new(self.path, head, app_state, Rc::new(self.app_data), None),
HttpRequest::new(
self.path,
head,
app_state,
Rc::new(self.app_data),
None,
Default::default(),
),
payload,
)
}
@ -599,7 +606,14 @@ impl TestRequest {
let app_state = AppInitServiceState::new(Rc::new(self.rmap), self.config.clone());
HttpRequest::new(self.path, head, app_state, Rc::new(self.app_data), None)
HttpRequest::new(
self.path,
head,
app_state,
Rc::new(self.app_data),
None,
Default::default(),
)
}
/// Complete request creation and generate `HttpRequest` and `Payload` instances
@ -610,7 +624,14 @@ impl TestRequest {
let app_state = AppInitServiceState::new(Rc::new(self.rmap), self.config.clone());
let req = HttpRequest::new(self.path, head, app_state, Rc::new(self.app_data), None);
let req = HttpRequest::new(
self.path,
head,
app_state,
Rc::new(self.app_data),
None,
Default::default(),
);
(req, payload)
}