1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-07-01 00:44:26 +02:00

add connection level data container (#2491)

This commit is contained in:
Rob Ede
2021-12-07 17:23:34 +00:00
committed by GitHub
parent 069cf2da07
commit d35b7644dc
18 changed files with 152 additions and 125 deletions

View File

@ -197,7 +197,8 @@ where
actix_service::forward_ready!(service);
fn call(&self, req: Request) -> Self::Future {
fn call(&self, mut req: Request) -> Self::Future {
let conn_data = req.take_conn_data();
let (head, payload) = req.into_parts();
let req = if let Some(mut req) = self.app_state.pool().pop() {
@ -205,6 +206,7 @@ where
inner.path.get_mut().update(&head.uri);
inner.path.reset();
inner.head = head;
inner.conn_data = conn_data;
req
} else {
HttpRequest::new(
@ -212,6 +214,7 @@ where
head,
self.app_state.clone(),
self.app_data.clone(),
conn_data,
)
};
self.service.call(ServiceRequest::new(req, payload))

View File

@ -37,6 +37,7 @@ pub(crate) struct HttpRequestInner {
pub(crate) head: Message<RequestHead>,
pub(crate) path: Path<Url>,
pub(crate) app_data: SmallVec<[Rc<Extensions>; 4]>,
pub(crate) conn_data: Option<Rc<Extensions>>,
app_state: Rc<AppInitServiceState>,
}
@ -47,6 +48,7 @@ impl HttpRequest {
head: Message<RequestHead>,
app_state: Rc<AppInitServiceState>,
app_data: Rc<Extensions>,
conn_data: Option<Rc<Extensions>>,
) -> HttpRequest {
let mut data = SmallVec::<[Rc<Extensions>; 4]>::new();
data.push(app_data);
@ -57,6 +59,7 @@ impl HttpRequest {
path,
app_state,
app_data: data,
conn_data,
}),
}
}
@ -165,6 +168,20 @@ impl HttpRequest {
self.head().extensions_mut()
}
/// Returns a reference a piece of connection data set in an [on-connect] callback.
///
/// ```ignore
/// let opt_t = req.conn_data::<PeerCertificate>();
/// ```
///
/// [on-connect]: crate::HttpServiceBuilder::on_connect_ext
pub fn conn_data<T: 'static>(&self) -> Option<&T> {
self.inner
.conn_data
.as_deref()
.and_then(|container| container.get::<T>())
}
/// Generates URL for a named resource.
///
/// This substitutes in sequence all URL parameters that appear in the resource itself and in

View File

@ -101,9 +101,9 @@ where
/// Sets function that will be called once before each connection is handled.
/// It will receive a `&std::any::Any`, which contains underlying connection type and an
/// [Extensions] container so that request-local data can be passed to middleware and handlers.
/// [Extensions] container so that connection data can be accessed in middleware and handlers.
///
/// For example:
/// # Connection Types
/// - `actix_tls::accept::openssl::TlsStream<actix_web::rt::net::TcpStream>` when using openssl.
/// - `actix_tls::accept::rustls::TlsStream<actix_web::rt::net::TcpStream>` when using rustls.
/// - `actix_web::rt::net::TcpStream` when no encryption is used.

View File

@ -172,12 +172,10 @@ impl ServiceRequest {
self.head().uri.path()
}
/// The query string in the URL.
///
/// E.g., id=10
/// Counterpart to [`HttpRequest::query_string`](super::HttpRequest::query_string()).
#[inline]
pub fn query_string(&self) -> &str {
self.uri().query().unwrap_or_default()
self.req.query_string()
}
/// Peer socket address.
@ -241,6 +239,7 @@ impl ServiceRequest {
}
/// Counterpart to [`HttpRequest::app_data`](super::HttpRequest::app_data()).
#[inline]
pub fn app_data<T: 'static>(&self) -> Option<&T> {
for container in self.req.inner.app_data.iter().rev() {
if let Some(data) = container.get::<T>() {
@ -251,6 +250,12 @@ impl ServiceRequest {
None
}
/// Counterpart to [`HttpRequest::conn_data`](super::HttpRequest::conn_data()).
#[inline]
pub fn conn_data<T: 'static>(&self) -> Option<&T> {
self.req.conn_data()
}
#[cfg(feature = "cookies")]
pub fn cookies(&self) -> Result<Ref<'_, Vec<Cookie<'static>>>, CookieParseError> {
self.req.cookies()
@ -263,6 +268,7 @@ impl ServiceRequest {
}
/// Set request payload.
#[inline]
pub fn set_payload(&mut self, payload: Payload) {
self.payload = payload;
}
@ -280,6 +286,7 @@ impl ServiceRequest {
}
impl Resource<Url> for ServiceRequest {
#[inline]
fn resource_path(&mut self) -> &mut Path<Url> {
self.match_info_mut()
}
@ -404,12 +411,11 @@ impl<B> ServiceResponse<B> {
}
/// Extract response body
#[inline]
pub fn into_body(self) -> B {
self.response.into_body()
}
}
impl<B> ServiceResponse<B> {
/// Set a new body
#[inline]
pub fn map_body<F, B2>(self, f: F) -> ServiceResponse<B2>

View File

@ -581,7 +581,7 @@ 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)),
HttpRequest::new(self.path, head, app_state, Rc::new(self.app_data), None),
payload,
)
}
@ -599,7 +599,7 @@ 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))
HttpRequest::new(self.path, head, app_state, Rc::new(self.app_data), None)
}
/// Complete request creation and generate `HttpRequest` and `Payload` instances
@ -610,7 +610,7 @@ 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));
let req = HttpRequest::new(self.path, head, app_state, Rc::new(self.app_data), None);
(req, payload)
}