mirror of
https://github.com/fafhrd91/actix-web
synced 2025-07-01 00:44:26 +02:00
split request data container out from requesthead
This commit is contained in:
@ -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))
|
||||
|
12
src/info.rs
12
src/info.rs
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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!(
|
||||
|
@ -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.
|
||||
|
27
src/test.rs
27
src/test.rs
@ -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)
|
||||
}
|
||||
|
Reference in New Issue
Block a user