mirror of
https://github.com/fafhrd91/actix-web
synced 2025-07-01 16:55:08 +02:00
move response extensions out of head (#2585)
This commit is contained in:
@ -1,9 +1,6 @@
|
||||
//! HTTP response builder.
|
||||
|
||||
use std::{
|
||||
cell::{Ref, RefMut},
|
||||
fmt, str,
|
||||
};
|
||||
use std::{cell::RefCell, fmt, str};
|
||||
|
||||
use crate::{
|
||||
body::{EitherBody, MessageBody},
|
||||
@ -202,20 +199,6 @@ impl ResponseBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Responses extensions
|
||||
#[inline]
|
||||
pub fn extensions(&self) -> Ref<'_, Extensions> {
|
||||
let head = self.head.as_ref().expect("cannot reuse response builder");
|
||||
head.extensions.borrow()
|
||||
}
|
||||
|
||||
/// Mutable reference to a the response's extensions
|
||||
#[inline]
|
||||
pub fn extensions_mut(&mut self) -> RefMut<'_, Extensions> {
|
||||
let head = self.head.as_ref().expect("cannot reuse response builder");
|
||||
head.extensions.borrow_mut()
|
||||
}
|
||||
|
||||
/// Generate response with a wrapped body.
|
||||
///
|
||||
/// This `ResponseBuilder` will be left in a useless state.
|
||||
@ -238,7 +221,12 @@ impl ResponseBuilder {
|
||||
}
|
||||
|
||||
let head = self.head.take().expect("cannot reuse response builder");
|
||||
Ok(Response { head, body })
|
||||
|
||||
Ok(Response {
|
||||
head,
|
||||
body,
|
||||
extensions: RefCell::new(Extensions::new()),
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate response with an empty body.
|
||||
|
@ -1,25 +1,19 @@
|
||||
//! Response head type and caching pool.
|
||||
|
||||
use std::{
|
||||
cell::{Ref, RefCell, RefMut},
|
||||
ops,
|
||||
};
|
||||
use std::{cell::RefCell, ops};
|
||||
|
||||
use crate::{
|
||||
header::HeaderMap, message::Flags, ConnectionType, Extensions, StatusCode, Version,
|
||||
};
|
||||
use crate::{header::HeaderMap, message::Flags, ConnectionType, StatusCode, Version};
|
||||
|
||||
thread_local! {
|
||||
static RESPONSE_POOL: BoxedResponsePool = BoxedResponsePool::create();
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ResponseHead {
|
||||
pub version: Version,
|
||||
pub status: StatusCode,
|
||||
pub headers: HeaderMap,
|
||||
pub reason: Option<&'static str>,
|
||||
pub(crate) extensions: RefCell<Extensions>,
|
||||
pub(crate) flags: Flags,
|
||||
}
|
||||
|
||||
@ -33,18 +27,17 @@ impl ResponseHead {
|
||||
headers: HeaderMap::with_capacity(12),
|
||||
reason: None,
|
||||
flags: Flags::empty(),
|
||||
extensions: RefCell::new(Extensions::new()),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Read the message headers.
|
||||
#[inline]
|
||||
pub fn headers(&self) -> &HeaderMap {
|
||||
&self.headers
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Mutable reference to the message headers.
|
||||
#[inline]
|
||||
pub fn headers_mut(&mut self) -> &mut HeaderMap {
|
||||
&mut self.headers
|
||||
}
|
||||
@ -61,20 +54,8 @@ impl ResponseHead {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Set connection type of the message
|
||||
#[inline]
|
||||
pub fn set_connection_type(&mut self, ctype: ConnectionType) {
|
||||
match ctype {
|
||||
ConnectionType::Close => self.flags.insert(Flags::CLOSE),
|
||||
@ -133,14 +114,14 @@ impl ResponseHead {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Get response body chunking state
|
||||
#[inline]
|
||||
pub fn chunked(&self) -> bool {
|
||||
!self.flags.contains(Flags::NO_CHUNKING)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Set no chunking for payload
|
||||
#[inline]
|
||||
pub fn no_chunking(&mut self, val: bool) {
|
||||
if val {
|
||||
self.flags.insert(Flags::NO_CHUNKING);
|
||||
@ -183,7 +164,7 @@ impl Drop for BoxedResponseHead {
|
||||
}
|
||||
}
|
||||
|
||||
/// Request's objects pool
|
||||
/// Response head object pool.
|
||||
#[doc(hidden)]
|
||||
pub struct BoxedResponsePool(#[allow(clippy::vec_box)] RefCell<Vec<Box<ResponseHead>>>);
|
||||
|
||||
@ -192,7 +173,7 @@ impl BoxedResponsePool {
|
||||
BoxedResponsePool(RefCell::new(Vec::with_capacity(128)))
|
||||
}
|
||||
|
||||
/// Get message from the pool
|
||||
/// Get message from the pool.
|
||||
#[inline]
|
||||
fn get_message(&self, status: StatusCode) -> BoxedResponseHead {
|
||||
if let Some(mut head) = self.0.borrow_mut().pop() {
|
||||
@ -208,12 +189,12 @@ impl BoxedResponsePool {
|
||||
}
|
||||
}
|
||||
|
||||
/// Release request instance
|
||||
/// Release request instance.
|
||||
#[inline]
|
||||
fn release(&self, mut msg: Box<ResponseHead>) {
|
||||
fn release(&self, msg: Box<ResponseHead>) {
|
||||
let pool = &mut self.0.borrow_mut();
|
||||
|
||||
if pool.len() < 128 {
|
||||
msg.extensions.get_mut().clear();
|
||||
pool.push(msg);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! HTTP response.
|
||||
|
||||
use std::{
|
||||
cell::{Ref, RefMut},
|
||||
cell::{Ref, RefCell, RefMut},
|
||||
fmt, str,
|
||||
};
|
||||
|
||||
@ -9,7 +9,7 @@ use bytes::{Bytes, BytesMut};
|
||||
use bytestring::ByteString;
|
||||
|
||||
use crate::{
|
||||
body::{BoxBody, MessageBody},
|
||||
body::{BoxBody, EitherBody, MessageBody},
|
||||
header::{self, HeaderMap, TryIntoHeaderValue},
|
||||
responses::BoxedResponseHead,
|
||||
Error, Extensions, ResponseBuilder, ResponseHead, StatusCode,
|
||||
@ -19,6 +19,7 @@ use crate::{
|
||||
pub struct Response<B> {
|
||||
pub(crate) head: BoxedResponseHead,
|
||||
pub(crate) body: B,
|
||||
pub(crate) extensions: RefCell<Extensions>,
|
||||
}
|
||||
|
||||
impl Response<BoxBody> {
|
||||
@ -28,6 +29,7 @@ impl Response<BoxBody> {
|
||||
Response {
|
||||
head: BoxedResponseHead::new(status),
|
||||
body: BoxBody::new(()),
|
||||
extensions: RefCell::new(Extensions::new()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,6 +76,7 @@ impl<B> Response<B> {
|
||||
Response {
|
||||
head: BoxedResponseHead::new(status),
|
||||
body,
|
||||
extensions: RefCell::new(Extensions::new()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,20 +123,21 @@ impl<B> Response<B> {
|
||||
}
|
||||
|
||||
/// Returns true if keep-alive is enabled.
|
||||
#[inline]
|
||||
pub fn keep_alive(&self) -> bool {
|
||||
self.head.keep_alive()
|
||||
}
|
||||
|
||||
/// Returns a reference to the extensions of this response.
|
||||
/// Returns a reference to the request-local data/extensions container.
|
||||
#[inline]
|
||||
pub fn extensions(&self) -> Ref<'_, Extensions> {
|
||||
self.head.extensions.borrow()
|
||||
self.extensions.borrow()
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the extensions of this response.
|
||||
/// Returns a mutable reference to the request-local data/extensions container.
|
||||
#[inline]
|
||||
pub fn extensions_mut(&mut self) -> RefMut<'_, Extensions> {
|
||||
self.head.extensions.borrow_mut()
|
||||
self.extensions.borrow_mut()
|
||||
}
|
||||
|
||||
/// Returns a reference to the body of this response.
|
||||
@ -143,24 +147,29 @@ impl<B> Response<B> {
|
||||
}
|
||||
|
||||
/// Sets new body.
|
||||
#[inline]
|
||||
pub fn set_body<B2>(self, body: B2) -> Response<B2> {
|
||||
Response {
|
||||
head: self.head,
|
||||
body,
|
||||
extensions: self.extensions,
|
||||
}
|
||||
}
|
||||
|
||||
/// Drops body and returns new response.
|
||||
#[inline]
|
||||
pub fn drop_body(self) -> Response<()> {
|
||||
self.set_body(())
|
||||
}
|
||||
|
||||
/// Sets new body, returning new response and previous body value.
|
||||
#[inline]
|
||||
pub(crate) fn replace_body<B2>(self, body: B2) -> (Response<B2>, B) {
|
||||
(
|
||||
Response {
|
||||
head: self.head,
|
||||
body,
|
||||
extensions: self.extensions,
|
||||
},
|
||||
self.body,
|
||||
)
|
||||
@ -171,11 +180,15 @@ impl<B> Response<B> {
|
||||
/// # Implementation Notes
|
||||
/// Due to internal performance optimizations, the first element of the returned tuple is a
|
||||
/// `Response` as well but only contains the head of the response this was called on.
|
||||
#[inline]
|
||||
pub fn into_parts(self) -> (Response<()>, B) {
|
||||
self.replace_body(())
|
||||
}
|
||||
|
||||
/// Returns new response with mapped body.
|
||||
/// Map the current body type to another using a closure. Returns a new response.
|
||||
///
|
||||
/// Closure receives the response head and the current body type.
|
||||
#[inline]
|
||||
pub fn map_body<F, B2>(mut self, f: F) -> Response<B2>
|
||||
where
|
||||
F: FnOnce(&mut ResponseHead, B) -> B2,
|
||||
@ -185,6 +198,7 @@ impl<B> Response<B> {
|
||||
Response {
|
||||
head: self.head,
|
||||
body,
|
||||
extensions: self.extensions,
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,6 +211,7 @@ impl<B> Response<B> {
|
||||
}
|
||||
|
||||
/// Returns body, consuming this response.
|
||||
#[inline]
|
||||
pub fn into_body(self) -> B {
|
||||
self.body
|
||||
}
|
||||
@ -239,9 +254,9 @@ impl<I: Into<Response<BoxBody>>, E: Into<Error>> From<Result<I, E>> for Response
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ResponseBuilder> for Response<BoxBody> {
|
||||
impl From<ResponseBuilder> for Response<EitherBody<()>> {
|
||||
fn from(mut builder: ResponseBuilder) -> Self {
|
||||
builder.finish().map_into_boxed_body()
|
||||
builder.finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user