diff --git a/CHANGES.md b/CHANGES.md index e39eaef6..922e0c7c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,10 @@ # Changes ## Unreleased - 2021-xx-xx +### Changed +- `HttpResponse` can now be used as a `Responder` with any body type. + +[#2501]: https://github.com/actix/actix-web/pull/2501 ## 4.0.0-beta.19 - 2022-01-04 diff --git a/Cargo.toml b/Cargo.toml index 13030782..a2b8fb88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -118,6 +118,7 @@ futures-util = { version = "0.3.7", default-features = false, features = ["std"] rand = "0.8" rcgen = "0.8" rustls-pemfile = "0.2" +static_assertions = "1" tls-openssl = { package = "openssl", version = "0.10.9" } tls-rustls = { package = "rustls", version = "0.20.0" } zstd = "0.9" diff --git a/src/response/builder.rs b/src/response/builder.rs index 93d8ab56..bdb0aaa1 100644 --- a/src/response/builder.rs +++ b/src/response/builder.rs @@ -23,7 +23,7 @@ use cookie::{Cookie, CookieJar}; use crate::{ error::{Error, JsonPayloadError}, - BoxError, HttpResponse, + BoxError, HttpRequest, HttpResponse, Responder, }; /// An HTTP response builder. @@ -424,6 +424,15 @@ impl Future for HttpResponseBuilder { } } +impl Responder for HttpResponseBuilder { + type Body = BoxBody; + + #[inline] + fn respond_to(mut self, _: &HttpRequest) -> HttpResponse { + self.finish() + } +} + #[cfg(test)] mod tests { use actix_http::body; diff --git a/src/response/customize_responder.rs b/src/response/customize_responder.rs index 11f6b291..8cb146dd 100644 --- a/src/response/customize_responder.rs +++ b/src/response/customize_responder.rs @@ -1,12 +1,9 @@ use actix_http::{ - body::{EitherBody, MessageBody}, - error::HttpError, - header::HeaderMap, - header::TryIntoHeaderPair, + body::EitherBody, error::HttpError, header::HeaderMap, header::TryIntoHeaderPair, StatusCode, }; -use crate::{BoxError, HttpRequest, HttpResponse, Responder}; +use crate::{HttpRequest, HttpResponse, Responder}; /// Allows overriding status code and headers for a [`Responder`]. /// @@ -143,7 +140,6 @@ impl CustomizeResponder { impl Responder for CustomizeResponder where T: Responder, - ::Error: Into, { type Body = EitherBody; diff --git a/src/response/responder.rs b/src/response/responder.rs index 319b824f..d1b9e49e 100644 --- a/src/response/responder.rs +++ b/src/response/responder.rs @@ -7,7 +7,7 @@ use actix_http::{ }; use bytes::{Bytes, BytesMut}; -use crate::{BoxError, Error, HttpRequest, HttpResponse, HttpResponseBuilder}; +use crate::{Error, HttpRequest, HttpResponse}; use super::CustomizeResponder; @@ -57,15 +57,6 @@ pub trait Responder { } } -impl Responder for HttpResponse { - type Body = BoxBody; - - #[inline] - fn respond_to(self, _: &HttpRequest) -> HttpResponse { - self - } -} - impl Responder for actix_http::Response { type Body = BoxBody; @@ -75,15 +66,6 @@ impl Responder for actix_http::Response { } } -impl Responder for HttpResponseBuilder { - type Body = BoxBody; - - #[inline] - fn respond_to(mut self, _: &HttpRequest) -> HttpResponse { - self.finish() - } -} - impl Responder for actix_http::ResponseBuilder { type Body = BoxBody; @@ -96,7 +78,6 @@ impl Responder for actix_http::ResponseBuilder { impl Responder for Option where T: Responder, - ::Error: Into, { type Body = EitherBody; @@ -111,7 +92,6 @@ where impl Responder for Result where T: Responder, - ::Error: Into, E: Into, { type Body = EitherBody; diff --git a/src/response/response.rs b/src/response/response.rs index 6fa2082e..f24a75b1 100644 --- a/src/response/response.rs +++ b/src/response/response.rs @@ -22,7 +22,7 @@ use { cookie::Cookie, }; -use crate::{error::Error, HttpResponseBuilder}; +use crate::{error::Error, HttpRequest, HttpResponseBuilder, Responder}; /// An outgoing response. pub struct HttpResponse { @@ -311,6 +311,18 @@ impl Future for HttpResponse { } } +impl Responder for HttpResponse +where + B: MessageBody + 'static, +{ + type Body = B; + + #[inline] + fn respond_to(self, _: &HttpRequest) -> HttpResponse { + self + } +} + #[cfg(feature = "cookies")] pub struct CookieIter<'a> { iter: std::slice::Iter<'a, HeaderValue>, @@ -333,9 +345,16 @@ impl<'a> Iterator for CookieIter<'a> { #[cfg(test)] mod tests { + use static_assertions::assert_impl_all; + use super::*; use crate::http::header::{HeaderValue, COOKIE}; + assert_impl_all!(HttpResponse: Responder); + assert_impl_all!(HttpResponse: Responder); + assert_impl_all!(HttpResponse<&'static str>: Responder); + assert_impl_all!(HttpResponse: Responder); + #[test] fn test_debug() { let resp = HttpResponse::Ok()