mirror of https://github.com/fafhrd91/actix-web
remove response future impl
This commit is contained in:
parent
a1e6f10a8d
commit
ce40201ab5
|
@ -19,6 +19,7 @@
|
|||
* Stop re-exporting `http` crate's `HeaderMap` types in addition to ours. [#2171]
|
||||
* Down-casting for `MessageBody` types. [#2183]
|
||||
* `error::Result` alias. [#2201]
|
||||
* `impl Future` for `Response`. [#2201]
|
||||
|
||||
[#2171]: https://github.com/actix/actix-web/pull/2171
|
||||
[#2183]: https://github.com/actix/actix-web/pull/2183
|
||||
|
|
|
@ -293,14 +293,14 @@ impl ResponseHead {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Check if keep-alive is enabled
|
||||
#[inline]
|
||||
pub fn keep_alive(&self) -> bool {
|
||||
self.connection_type() == ConnectionType::KeepAlive
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Check upgrade status of this message
|
||||
#[inline]
|
||||
pub fn upgrade(&self) -> bool {
|
||||
self.connection_type() == ConnectionType::Upgrade
|
||||
}
|
||||
|
|
|
@ -19,22 +19,22 @@ use crate::{
|
|||
/// An HTTP response.
|
||||
pub struct Response<B> {
|
||||
pub(crate) head: BoxedResponseHead,
|
||||
pub(crate) body: Option<B>,
|
||||
pub(crate) body: B,
|
||||
pub(crate) error: Option<Error>,
|
||||
}
|
||||
|
||||
impl Response<Body> {
|
||||
/// Constructs a response
|
||||
/// Constructs a new response with default body.
|
||||
#[inline]
|
||||
pub fn new(status: StatusCode) -> Response<Body> {
|
||||
Response {
|
||||
head: BoxedResponseHead::new(status),
|
||||
body: Some(Body::Empty),
|
||||
body: Body::Empty,
|
||||
error: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create HTTP response builder with specific status.
|
||||
/// Constructs a new response builder.
|
||||
#[inline]
|
||||
pub fn build(status: StatusCode) -> ResponseBuilder {
|
||||
ResponseBuilder::new(status)
|
||||
|
@ -43,25 +43,25 @@ impl Response<Body> {
|
|||
// just a couple frequently used shortcuts
|
||||
// this list should not grow larger than a few
|
||||
|
||||
/// Creates a new response with status 200 OK.
|
||||
/// Constructs a new response with status 200 OK.
|
||||
#[inline]
|
||||
pub fn ok() -> Response<Body> {
|
||||
Response::new(StatusCode::OK)
|
||||
}
|
||||
|
||||
/// Creates a new response with status 400 Bad Request.
|
||||
/// Constructs a new response with status 400 Bad Request.
|
||||
#[inline]
|
||||
pub fn bad_request() -> Response<Body> {
|
||||
Response::new(StatusCode::BAD_REQUEST)
|
||||
}
|
||||
|
||||
/// Creates a new response with status 404 Not Found.
|
||||
/// Constructs a new response with status 404 Not Found.
|
||||
#[inline]
|
||||
pub fn not_found() -> Response<Body> {
|
||||
Response::new(StatusCode::NOT_FOUND)
|
||||
}
|
||||
|
||||
/// Creates a new response with status 500 Internal Server Error.
|
||||
/// Constructs a new response with status 500 Internal Server Error.
|
||||
#[inline]
|
||||
pub fn internal_server_error() -> Response<Body> {
|
||||
Response::new(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
|
@ -69,7 +69,7 @@ impl Response<Body> {
|
|||
|
||||
// end shortcuts
|
||||
|
||||
/// Constructs an error response
|
||||
/// Constructs a new response from an error.
|
||||
#[inline]
|
||||
pub fn from_error(error: Error) -> Response<Body> {
|
||||
let mut resp = error.as_response_error().error_response();
|
||||
|
@ -82,146 +82,139 @@ impl Response<Body> {
|
|||
}
|
||||
|
||||
impl<B> Response<B> {
|
||||
/// Constructs a response with body
|
||||
/// Constructs a new response with given body.
|
||||
#[inline]
|
||||
pub fn with_body(status: StatusCode, body: B) -> Response<B> {
|
||||
Response {
|
||||
head: BoxedResponseHead::new(status),
|
||||
body: Some(body),
|
||||
body: body,
|
||||
error: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a reference to the head of this response.
|
||||
#[inline]
|
||||
/// Http message part of the response
|
||||
pub fn head(&self) -> &ResponseHead {
|
||||
&*self.head
|
||||
}
|
||||
|
||||
/// Return a mutable reference to the head of this response.
|
||||
#[inline]
|
||||
/// Mutable reference to a HTTP message part of the response
|
||||
pub fn head_mut(&mut self) -> &mut ResponseHead {
|
||||
&mut *self.head
|
||||
}
|
||||
|
||||
/// The source `error` for this response
|
||||
/// Return the source `error` for this response, if one is set.
|
||||
#[inline]
|
||||
pub fn error(&self) -> Option<&Error> {
|
||||
self.error.as_ref()
|
||||
}
|
||||
|
||||
/// Get the response status code
|
||||
/// Return the status code of this response.
|
||||
#[inline]
|
||||
pub fn status(&self) -> StatusCode {
|
||||
self.head.status
|
||||
}
|
||||
|
||||
/// Set the `StatusCode` for this response
|
||||
/// Returns a mutable reference the status code of this response.
|
||||
#[inline]
|
||||
pub fn status_mut(&mut self) -> &mut StatusCode {
|
||||
&mut self.head.status
|
||||
}
|
||||
|
||||
/// Get the headers from the response
|
||||
/// Returns a reference to response headers.
|
||||
#[inline]
|
||||
pub fn headers(&self) -> &HeaderMap {
|
||||
&self.head.headers
|
||||
}
|
||||
|
||||
/// Get a mutable reference to the headers
|
||||
/// Returns a mutable reference to response headers.
|
||||
#[inline]
|
||||
pub fn headers_mut(&mut self) -> &mut HeaderMap {
|
||||
&mut self.head.headers
|
||||
}
|
||||
|
||||
/// Connection upgrade status
|
||||
/// Returns true if connection upgrade is enabled.
|
||||
#[inline]
|
||||
pub fn upgrade(&self) -> bool {
|
||||
self.head.upgrade()
|
||||
}
|
||||
|
||||
/// Keep-alive status for this connection
|
||||
/// Returns true if keep-alive is enabled.
|
||||
pub fn keep_alive(&self) -> bool {
|
||||
self.head.keep_alive()
|
||||
}
|
||||
|
||||
/// Responses extensions
|
||||
/// Returns a reference to the extensions of this response.
|
||||
#[inline]
|
||||
pub fn extensions(&self) -> Ref<'_, Extensions> {
|
||||
self.head.extensions.borrow()
|
||||
}
|
||||
|
||||
/// Mutable reference to a the response's extensions
|
||||
/// Returns a mutable reference to the extensions of this response.
|
||||
#[inline]
|
||||
pub fn extensions_mut(&mut self) -> RefMut<'_, Extensions> {
|
||||
self.head.extensions.borrow_mut()
|
||||
}
|
||||
|
||||
/// Get body of this response
|
||||
/// Returns a reference to the body of this response.
|
||||
#[inline]
|
||||
pub fn body(&self) -> &B {
|
||||
self.body.as_ref().unwrap()
|
||||
&self.body
|
||||
}
|
||||
|
||||
/// Set a body
|
||||
/// Sets new body.
|
||||
pub fn set_body<B2>(self, body: B2) -> Response<B2> {
|
||||
Response {
|
||||
head: self.head,
|
||||
body: Some(body),
|
||||
body,
|
||||
error: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Split response and body
|
||||
pub fn into_parts(self) -> (Response<()>, B) {
|
||||
(
|
||||
Response {
|
||||
head: self.head,
|
||||
body: Some(()),
|
||||
error: self.error,
|
||||
},
|
||||
self.body.unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Drop request's body
|
||||
/// Drops body and returns new response.
|
||||
pub fn drop_body(self) -> Response<()> {
|
||||
Response {
|
||||
head: self.head,
|
||||
body: Some(()),
|
||||
error: None,
|
||||
}
|
||||
self.set_body(())
|
||||
}
|
||||
|
||||
/// Set a body and return previous body value
|
||||
/// Sets new body, returning new response and previous body value.
|
||||
pub(crate) fn replace_body<B2>(self, body: B2) -> (Response<B2>, B) {
|
||||
(
|
||||
Response {
|
||||
head: self.head,
|
||||
body: Some(body),
|
||||
body,
|
||||
error: self.error,
|
||||
},
|
||||
self.body.unwrap(),
|
||||
self.body,
|
||||
)
|
||||
}
|
||||
|
||||
/// Set a body and return previous body value
|
||||
/// Returns split head and body.
|
||||
///
|
||||
/// # Implementation Notes
|
||||
/// Due to internal performance optimisations, the first element of the returned tuple is a
|
||||
/// `Response` as well but only contains the head of the response this was called on.
|
||||
pub fn into_parts(self) -> (Response<()>, B) {
|
||||
self.replace_body(())
|
||||
}
|
||||
|
||||
/// Returns new response with mapped body.
|
||||
pub fn map_body<F, B2>(mut self, f: F) -> Response<B2>
|
||||
where
|
||||
F: FnOnce(&mut ResponseHead, B) -> B2,
|
||||
{
|
||||
let body = f(&mut self.head, self.body.unwrap());
|
||||
let body = f(&mut self.head, self.body);
|
||||
|
||||
Response {
|
||||
head: self.head,
|
||||
body: Some(body),
|
||||
body,
|
||||
error: self.error,
|
||||
}
|
||||
}
|
||||
|
||||
/// Extract response body
|
||||
/// Returns body, consuming this response.
|
||||
pub fn into_body(self) -> B {
|
||||
self.body.unwrap()
|
||||
self.body
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,7 +235,7 @@ where
|
|||
for (key, val) in self.head.headers.iter() {
|
||||
let _ = writeln!(f, " {:?}: {:?}", key, val);
|
||||
}
|
||||
let _ = writeln!(f, " body: {:?}", self.body.as_ref().unwrap().size());
|
||||
let _ = writeln!(f, " body: {:?}", self.body.size());
|
||||
res
|
||||
}
|
||||
}
|
||||
|
@ -254,31 +247,6 @@ impl<B: Default> Default for Response<B> {
|
|||
}
|
||||
}
|
||||
|
||||
mod fut {
|
||||
use std::{
|
||||
convert::Infallible,
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
// TODO: document why this is needed
|
||||
impl<B: Unpin> Future for Response<B> {
|
||||
type Output = Result<Response<B>, Infallible>;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
Poll::Ready(Ok(Response {
|
||||
head: self.head.take(),
|
||||
body: self.body.take(),
|
||||
error: self.error.take(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper converters
|
||||
impl<I: Into<Response<Body>>, E: Into<Error>> From<Result<I, E>> for Response<Body> {
|
||||
fn from(res: Result<I, E>) -> Self {
|
||||
match res {
|
||||
|
|
|
@ -254,7 +254,7 @@ impl ResponseBuilder {
|
|||
|
||||
Ok(Response {
|
||||
head: response,
|
||||
body: Some(body),
|
||||
body,
|
||||
error: None,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::{
|
|||
cell::{Ref, RefMut},
|
||||
fmt,
|
||||
future::Future,
|
||||
mem,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
@ -11,7 +12,6 @@ use actix_http::{
|
|||
http::{header::HeaderMap, StatusCode},
|
||||
Extensions, Response, ResponseHead,
|
||||
};
|
||||
use futures_core::ready;
|
||||
|
||||
#[cfg(feature = "cookies")]
|
||||
use {
|
||||
|
@ -278,21 +278,24 @@ impl<B> From<HttpResponse<B>> for Response<B> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<B: Unpin> Future for HttpResponse<B> {
|
||||
type Output = Result<Response<B>, Error>;
|
||||
// Future is only implemented for Body payload type because it's the most useful for making simple
|
||||
// handlers without async blocks. Making it generic over all MessageBody types requires a future
|
||||
// impl on Response which would cause it's body field to be, undesirably, Option<B>.
|
||||
//
|
||||
// This impl is not particularly efficient due to the Response construction and should probably
|
||||
// not be invoked if performance is important. Prefer an async fn/block in such cases.
|
||||
impl Future for HttpResponse<Body> {
|
||||
type Output = Result<Response<Body>, Error>;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
if let Some(err) = self.error.take() {
|
||||
return Poll::Ready(Err(err));
|
||||
}
|
||||
|
||||
let res = &mut self.res;
|
||||
actix_rt::pin!(res);
|
||||
|
||||
match ready!(res.poll(cx)) {
|
||||
Ok(val) => Poll::Ready(Ok(val)),
|
||||
Err(err) => Poll::Ready(Err(err.into())),
|
||||
}
|
||||
Poll::Ready(Ok(mem::replace(
|
||||
&mut self.res,
|
||||
Response::new(StatusCode::default()),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -901,7 +901,7 @@ async fn test_normalize() {
|
|||
let srv = actix_test::start_with(actix_test::config().h1(), || {
|
||||
App::new()
|
||||
.wrap(NormalizePath::new(TrailingSlash::Trim))
|
||||
.service(web::resource("/one").route(web::to(|| HttpResponse::Ok().finish())))
|
||||
.service(web::resource("/one").route(web::to(|| HttpResponse::Ok())))
|
||||
});
|
||||
|
||||
let response = srv.get("/one/").send().await.unwrap();
|
||||
|
|
Loading…
Reference in New Issue