1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-08-19 04:15:38 +02:00

cleanup response

This commit is contained in:
Nikolay Kim
2017-12-15 20:00:12 -08:00
parent a8b2f1b821
commit 1daf50095a
3 changed files with 116 additions and 115 deletions

View File

@@ -29,86 +29,6 @@ pub enum ConnectionType {
Upgrade,
}
#[derive(Debug)]
struct InnerHttpResponse {
version: Option<Version>,
headers: HeaderMap,
status: StatusCode,
reason: Option<&'static str>,
body: Body,
chunked: bool,
encoding: ContentEncoding,
connection_type: Option<ConnectionType>,
response_size: u64,
error: Option<Error>,
}
impl InnerHttpResponse {
#[inline]
fn new(status: StatusCode, body: Body) -> InnerHttpResponse {
InnerHttpResponse {
version: None,
headers: HeaderMap::with_capacity(8),
status: status,
reason: None,
body: body,
chunked: false,
encoding: ContentEncoding::Auto,
connection_type: None,
response_size: 0,
error: None,
}
}
}
impl Default for InnerHttpResponse {
fn default() -> InnerHttpResponse {
InnerHttpResponse::new(StatusCode::OK, Body::Empty)
}
}
/// Internal use only! unsafe
struct Pool(VecDeque<Box<InnerHttpResponse>>);
thread_local!(static POOL: RefCell<Pool> = RefCell::new(Pool::new()));
impl Pool {
fn new() -> Pool {
Pool(VecDeque::with_capacity(128))
}
fn get() -> Box<InnerHttpResponse> {
POOL.with(|pool| {
if let Some(resp) = pool.borrow_mut().0.pop_front() {
resp
} else {
Box::new(InnerHttpResponse::default())
}
})
}
#[cfg_attr(feature = "cargo-clippy", allow(boxed_local))]
fn release(mut inner: Box<InnerHttpResponse>) {
POOL.with(|pool| {
if pool.borrow().0.len() < 128 {
inner.version.take();
inner.headers.clear();
inner.chunked = false;
inner.reason.take();
inner.body = Body::Empty;
inner.encoding = ContentEncoding::Auto;
inner.connection_type.take();
inner.response_size = 0;
inner.error.take();
pool.borrow_mut().0.push_front(inner);
}
})
}
}
/// An HTTP Response
pub struct HttpResponse(Option<Box<InnerHttpResponse>>);
@@ -123,27 +43,22 @@ impl Drop for HttpResponse {
impl HttpResponse {
#[inline(always)]
#[cfg_attr(feature = "cargo-clippy", allow(inline_always))]
fn get_ref(&self) -> &InnerHttpResponse {
self.0.as_ref().unwrap()
}
#[inline(always)]
#[cfg_attr(feature = "cargo-clippy", allow(inline_always))]
fn get_mut(&mut self) -> &mut InnerHttpResponse {
self.0.as_mut().unwrap()
}
#[inline]
fn from_inner(inner: Box<InnerHttpResponse>) -> HttpResponse {
HttpResponse(Some(inner))
}
/// Create http response builder with specific status.
#[inline]
pub fn build(status: StatusCode) -> HttpResponseBuilder {
let mut inner = Pool::get();
inner.status = status;
HttpResponseBuilder {
response: Some(inner),
response: Some(Pool::get(status)),
err: None,
cookies: None,
}
@@ -152,10 +67,7 @@ impl HttpResponse {
/// Constructs a response
#[inline]
pub fn new(status: StatusCode, body: Body) -> HttpResponse {
let mut inner = Pool::get();
inner.status = status;
inner.body = body;
HttpResponse(Some(inner))
HttpResponse(Some(Pool::with_body(status, body)))
}
/// Constructs a error response
@@ -470,7 +382,7 @@ impl HttpResponseBuilder {
}
}
response.body = body.into();
Ok(HttpResponse::from_inner(response))
Ok(HttpResponse(Some(response)))
}
/// Set a json body and generate `HttpResponse`
@@ -495,6 +407,7 @@ impl HttpResponseBuilder {
}
}
#[inline]
#[cfg_attr(feature = "cargo-clippy", allow(borrowed_box))]
fn parts<'a>(parts: &'a mut Option<Box<InnerHttpResponse>>, err: &Option<HttpError>)
-> Option<&'a mut Box<InnerHttpResponse>>
@@ -525,6 +438,7 @@ impl Responder for HttpResponseBuilder {
type Item = HttpResponse;
type Error = HttpError;
#[inline]
fn respond_to(mut self, _: HttpRequest) -> Result<HttpResponse, HttpError> {
self.finish()
}
@@ -650,6 +564,93 @@ impl Responder for BytesMut {
}
}
#[derive(Debug)]
struct InnerHttpResponse {
version: Option<Version>,
headers: HeaderMap,
status: StatusCode,
reason: Option<&'static str>,
body: Body,
chunked: bool,
encoding: ContentEncoding,
connection_type: Option<ConnectionType>,
response_size: u64,
error: Option<Error>,
}
impl InnerHttpResponse {
#[inline]
fn new(status: StatusCode, body: Body) -> InnerHttpResponse {
InnerHttpResponse {
version: None,
headers: HeaderMap::with_capacity(8),
status: status,
reason: None,
body: body,
chunked: false,
encoding: ContentEncoding::Auto,
connection_type: None,
response_size: 0,
error: None,
}
}
}
/// Internal use only! unsafe
struct Pool(VecDeque<Box<InnerHttpResponse>>);
thread_local!(static POOL: RefCell<Pool> = RefCell::new(Pool::new()));
impl Pool {
fn new() -> Pool {
Pool(VecDeque::with_capacity(128))
}
fn get(status: StatusCode) -> Box<InnerHttpResponse> {
POOL.with(|pool| {
if let Some(mut resp) = pool.borrow_mut().0.pop_front() {
resp.body = Body::Empty;
resp.status = status;
resp
} else {
Box::new(InnerHttpResponse::new(status, Body::Empty))
}
})
}
fn with_body(status: StatusCode, body: Body) -> Box<InnerHttpResponse> {
POOL.with(|pool| {
if let Some(mut resp) = pool.borrow_mut().0.pop_front() {
resp.status = status;
resp.body = Body::Empty;
resp
} else {
Box::new(InnerHttpResponse::new(status, body))
}
})
}
#[cfg_attr(feature = "cargo-clippy", allow(boxed_local))]
fn release(mut inner: Box<InnerHttpResponse>) {
POOL.with(|pool| {
let v = &mut pool.borrow_mut().0;
if v.len() < 128 {
inner.headers.clear();
inner.version = None;
inner.chunked = false;
inner.reason = None;
inner.encoding = ContentEncoding::Auto;
inner.connection_type = None;
inner.response_size = 0;
inner.error = None;
v.push_front(inner);
}
})
}
}
#[cfg(test)]
mod tests {
use super::*;