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

make AnyBody generic on Body type (#2448)

This commit is contained in:
Rob Ede
2021-11-16 21:41:35 +00:00
committed by GitHub
parent 13cf5a9e44
commit d8cbb879dd
18 changed files with 283 additions and 210 deletions

View File

@ -14,7 +14,7 @@ pub use crate::types::form::UrlEncoded;
pub use crate::types::json::JsonBody;
pub use crate::types::readlines::Readlines;
pub use actix_http::body::{AnyBody, Body, BodySize, MessageBody, ResponseBody, SizedStream};
pub use actix_http::body::{AnyBody, Body, BodySize, MessageBody, SizedStream};
#[cfg(feature = "__compress")]
pub use actix_http::encoding::Decoder as Decompress;

View File

@ -7,7 +7,7 @@ use std::{
task::{Context, Poll},
};
use actix_http::body::{Body, MessageBody};
use actix_http::body::{AnyBody, MessageBody};
use actix_service::{Service, Transform};
use futures_core::{future::LocalBoxFuture, ready};
@ -124,7 +124,7 @@ where
B::Error: Into<Box<dyn StdError + 'static>>,
{
fn map_body(self) -> ServiceResponse {
self.map_body(|_, body| Body::from_message(body))
self.map_body(|_, body| AnyBody::new_boxed(body))
}
}

View File

@ -10,13 +10,14 @@ use std::{
};
use actix_http::{
body::{MessageBody, ResponseBody},
body::{AnyBody, MessageBody},
encoding::Encoder,
http::header::{ContentEncoding, ACCEPT_ENCODING},
StatusCode,
};
use actix_service::{Service, Transform};
use actix_utils::future::{ok, Either, Ready};
use bytes::Bytes;
use futures_core::ready;
use once_cell::sync::Lazy;
use pin_project::pin_project;
@ -61,7 +62,7 @@ where
B: MessageBody,
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
{
type Response = ServiceResponse<ResponseBody<Encoder<B>>>;
type Response = ServiceResponse<AnyBody<Encoder<B>>>;
type Error = Error;
type Transform = CompressMiddleware<S>;
type InitError = ();
@ -110,7 +111,7 @@ where
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
B: MessageBody,
{
type Response = ServiceResponse<ResponseBody<Encoder<B>>>;
type Response = ServiceResponse<AnyBody<Encoder<B>>>;
type Error = Error;
type Future = Either<CompressResponse<S, B>, Ready<Result<Self::Response, Self::Error>>>;
@ -142,15 +143,19 @@ where
// There is an HTTP header but we cannot match what client as asked for
Some(Err(_)) => {
let res = HttpResponse::with_body(
StatusCode::NOT_ACCEPTABLE,
SUPPORTED_ALGORITHM_NAMES.as_str(),
);
let enc = ContentEncoding::Identity;
let res = HttpResponse::new(StatusCode::NOT_ACCEPTABLE);
Either::right(ok(req.into_response(res.map_body(move |head, body| {
Encoder::response(enc, head, ResponseBody::Other(body.into()))
}))))
let res: HttpResponse<AnyBody<Encoder<B>>> = res.map_body(move |head, _| {
let body_bytes = Bytes::from(SUPPORTED_ALGORITHM_NAMES.as_bytes());
Encoder::response(
ContentEncoding::Identity,
head,
AnyBody::Bytes(body_bytes),
)
});
Either::right(ok(req.into_response(res)))
}
}
}
@ -172,7 +177,7 @@ where
B: MessageBody,
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
{
type Output = Result<ServiceResponse<ResponseBody<Encoder<B>>>, Error>;
type Output = Result<ServiceResponse<AnyBody<Encoder<B>>>, Error>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
@ -186,7 +191,7 @@ where
};
Poll::Ready(Ok(resp.map_body(move |head, body| {
Encoder::response(enc, head, ResponseBody::Body(body))
Encoder::response(enc, head, AnyBody::Body(body))
})))
}
Err(e) => Poll::Ready(Err(e)),

View File

@ -232,7 +232,7 @@ pub(crate) mod tests {
use bytes::{Bytes, BytesMut};
use super::*;
use crate::dev::{Body, ResponseBody};
use crate::dev::AnyBody;
use crate::http::{header::CONTENT_TYPE, HeaderValue, StatusCode};
use crate::test::{init_service, TestRequest};
use crate::{error, web, App};
@ -264,13 +264,13 @@ pub(crate) mod tests {
pub(crate) trait BodyTest {
fn bin_ref(&self) -> &[u8];
fn body(&self) -> &Body;
fn body(&self) -> &AnyBody;
}
impl BodyTest for Body {
fn bin_ref(&self) -> &[u8] {
match self {
Body::Bytes(ref bin) => bin,
AnyBody::Bytes(ref bin) => bin,
_ => unreachable!("bug in test impl"),
}
}
@ -279,27 +279,6 @@ pub(crate) mod tests {
}
}
impl BodyTest for ResponseBody<Body> {
fn bin_ref(&self) -> &[u8] {
match self {
ResponseBody::Body(ref b) => match b {
Body::Bytes(ref bin) => bin,
_ => unreachable!("bug in test impl"),
},
ResponseBody::Other(ref b) => match b {
Body::Bytes(ref bin) => bin,
_ => unreachable!("bug in test impl"),
},
}
}
fn body(&self) -> &Body {
match self {
ResponseBody::Body(ref b) => b,
ResponseBody::Other(ref b) => b,
}
}
}
#[actix_rt::test]
async fn test_responder() {
let req = TestRequest::default().to_http_request();

View File

@ -354,10 +354,10 @@ impl HttpResponseBuilder {
#[inline]
pub fn streaming<S, E>(&mut self, stream: S) -> HttpResponse
where
S: Stream<Item = Result<Bytes, E>> + Unpin + 'static,
S: Stream<Item = Result<Bytes, E>> + 'static,
E: Into<Box<dyn StdError>> + 'static,
{
self.body(AnyBody::from_message(BodyStream::new(stream)))
self.body(AnyBody::new_boxed(BodyStream::new(stream)))
}
/// Set a json body and generate `Response`

View File

@ -227,6 +227,9 @@ impl<B> HttpResponse<B> {
}
}
// TODO: into_body equivalent
// TODO: into_boxed_body
/// Extract response body
pub fn into_body(self) -> B {
self.res.into_body()