From eb9a6125fb8bff44baa9f74d64a327181ba97218 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 4 Dec 2021 04:05:37 +0000 Subject: [PATCH] remove body reexports from dev --- CHANGES.md | 1 + actix-http/src/message.rs | 9 +++++---- actix-test/src/lib.rs | 3 ++- src/dev.rs | 40 ++++++++++++++++++++++++++++++++++++--- src/handler.rs | 22 +++++++++++++++------ src/http/header/accept.rs | 2 +- src/middleware/logger.rs | 2 +- src/response/builder.rs | 1 - src/response/response.rs | 1 + src/route.rs | 2 -- src/types/path.rs | 2 +- src/types/payload.rs | 6 +++--- src/types/query.rs | 2 +- 13 files changed, 69 insertions(+), 24 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index c45e9c130..f19df4897 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,7 @@ ### Fixed * Accept wildcard `*` items in `AcceptLanguage`. [#2480] +* Re-exports `dev::{BodySize, MessageBody, SizedStream}`. They are exposed through the `body` module. [#2468] * Typed headers containing lists that require one or more items now enforce this minimum. [#2482] [#2468]: https://github.com/actix/actix-web/pull/2468 diff --git a/actix-http/src/message.rs b/actix-http/src/message.rs index e0bed0631..c8e1ce6db 100644 --- a/actix-http/src/message.rs +++ b/actix-http/src/message.rs @@ -46,8 +46,8 @@ pub trait Head: Default + 'static { #[derive(Debug)] pub struct RequestHead { - pub uri: Uri, pub method: Method, + pub uri: Uri, pub version: Version, pub headers: HeaderMap, pub extensions: RefCell, @@ -58,13 +58,13 @@ pub struct RequestHead { impl Default for RequestHead { fn default() -> RequestHead { RequestHead { - uri: Uri::default(), method: Method::default(), + uri: Uri::default(), version: Version::HTTP_11, headers: HeaderMap::with_capacity(16), - flags: Flags::empty(), - peer_addr: None, extensions: RefCell::new(Extensions::new()), + peer_addr: None, + flags: Flags::empty(), } } } @@ -192,6 +192,7 @@ impl RequestHead { } #[derive(Debug)] +#[allow(clippy::large_enum_variant)] pub enum RequestHeadType { Owned(RequestHead), Rc(Rc, Option), diff --git a/actix-test/src/lib.rs b/actix-test/src/lib.rs index bc557441b..1decd6e98 100644 --- a/actix-test/src/lib.rs +++ b/actix-test/src/lib.rs @@ -41,7 +41,8 @@ use actix_http::{ }; use actix_service::{map_config, IntoServiceFactory, ServiceFactory, ServiceFactoryExt as _}; use actix_web::{ - dev::{AppConfig, MessageBody, Server, ServerHandle, Service}, + body::MessageBody, + dev::{AppConfig, Server, ServerHandle, Service}, rt::{self, System}, web, Error, }; diff --git a/src/dev.rs b/src/dev.rs index 9529d6a28..d86647b58 100644 --- a/src/dev.rs +++ b/src/dev.rs @@ -14,9 +14,6 @@ pub use crate::types::form::UrlEncoded; pub use crate::types::json::JsonBody; pub use crate::types::readlines::Readlines; -#[allow(deprecated)] -pub use actix_http::body::{BodySize, MessageBody, SizedStream}; - pub use actix_http::{Extensions, Payload, PayloadStream, RequestHead, Response, ResponseHead}; pub use actix_router::{Path, ResourceDef, ResourcePath, Url}; pub use actix_server::{Server, ServerHandle}; @@ -105,3 +102,40 @@ impl BodyEncoding for crate::HttpResponse { self } } + +// pin_project_lite::pin_project! { +#[derive(Debug)] +pub enum AnyBody { + None, + Full { body: crate::web::Bytes }, + Boxed { body: actix_http::body::BoxBody }, +} +// } + +impl crate::body::MessageBody for AnyBody { + type Error = crate::BoxError; + + /// Body size hint. + fn size(&self) -> crate::body::BodySize { + match self { + AnyBody::None => crate::body::BodySize::None, + AnyBody::Full { body } => body.size(), + AnyBody::Boxed { body } => body.size(), + } + } + + /// Attempt to pull out the next chunk of body bytes. + fn poll_next( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll>> { + match self.get_mut() { + AnyBody::None => std::task::Poll::Ready(None), + AnyBody::Full { body } => { + let bytes = std::mem::take(body); + std::task::Poll::Ready(Some(Ok(bytes))) + } + AnyBody::Boxed { body } => body.as_pin_mut().poll_next(cx), + } + } +} diff --git a/src/handler.rs b/src/handler.rs index 8ed40e1d7..e543ecc7f 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -9,11 +9,13 @@ use crate::{ }; /// A request handler is an async function that accepts zero or more parameters that can be -/// extracted from a request (i.e., [`impl FromRequest`](crate::FromRequest)) and returns a type -/// that can be converted into an [`HttpResponse`] (that is, it impls the [`Responder`] trait). +/// extracted from a request (i.e., [`impl FromRequest`]) and returns a type that can be converted +/// into an [`HttpResponse`] (that is, it impls the [`Responder`] trait). /// /// If you got the error `the trait Handler<_, _, _> is not implemented`, then your function is not -/// a valid handler. See [Request Handlers](https://actix.rs/docs/handlers/) for more information. +/// a valid handler. See for more information. +/// +/// [`impl FromRequest`]: crate::FromRequest pub trait Handler: Clone + 'static where R: Future, @@ -22,7 +24,7 @@ where fn call(&self, param: T) -> R; } -pub fn handler_service(handler: F) -> BoxedHttpServiceFactory +pub(crate) fn handler_service(handler: F) -> BoxedHttpServiceFactory where F: Handler, T: FromRequest, @@ -36,8 +38,9 @@ where async move { let (req, mut payload) = req.into_parts(); + let res = match T::from_request(&req, &mut payload).await { - Err(err) => HttpResponse::from_error(err).map_into_boxed_body(), + Err(err) => HttpResponse::from_error(err), Ok(data) => handler .call(data) @@ -51,7 +54,14 @@ where })) } -/// FromRequest trait impl for tuples +/// Generates a [`Handler`] trait impl for N-ary functions where N is specified with a sequence of +/// space separated type parameters. +/// +/// # Examples +/// ```ignore +/// factory_tuple! {} // implements Handler for types: fn() -> Res +/// factory_tuple! { A B C } // implements Handler for types: fn(A, B, C) -> Res +/// ``` macro_rules! factory_tuple ({ $($param:ident)* } => { impl Handler<($($param,)*), Res> for Func where Func: Fn($($param),*) -> Res + Clone + 'static, diff --git a/src/http/header/accept.rs b/src/http/header/accept.rs index fe291c011..70e4118cf 100644 --- a/src/http/header/accept.rs +++ b/src/http/header/accept.rs @@ -208,7 +208,7 @@ impl Accept { /// If no q-factors are provided, the first mime type is chosen. Note that items without /// q-factors are given the maximum preference value. /// - /// As per the spec, will return [`Mime::STAR_STAR`] (indicating no preference) if the contained + /// As per the spec, will return [`mime::STAR_STAR`] (indicating no preference) if the contained /// list is empty. /// /// [q-factor weighting]: https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2 diff --git a/src/middleware/logger.rs b/src/middleware/logger.rs index 6ab16a4eb..f89b13a1c 100644 --- a/src/middleware/logger.rs +++ b/src/middleware/logger.rs @@ -22,7 +22,7 @@ use regex::{Regex, RegexSet}; use time::{format_description::well_known::Rfc3339, OffsetDateTime}; use crate::{ - dev::{BodySize, MessageBody}, + body::{BodySize, MessageBody}, http::HeaderName, service::{ServiceRequest, ServiceResponse}, Error, HttpResponse, Result, diff --git a/src/response/builder.rs b/src/response/builder.rs index 228fc615e..4d0c0a7f7 100644 --- a/src/response/builder.rs +++ b/src/response/builder.rs @@ -1,7 +1,6 @@ use std::{ cell::{Ref, RefMut}, convert::TryInto, - error::Error as StdError, future::Future, pin::Pin, task::{Context, Poll}, diff --git a/src/response/response.rs b/src/response/response.rs index 376db3fa9..a0bf248db 100644 --- a/src/response/response.rs +++ b/src/response/response.rs @@ -241,6 +241,7 @@ impl HttpResponse { where B: MessageBody + 'static, { + // TODO: avoid double boxing with down-casting, if it improves perf self.map_body(|_, body| BoxBody::new(body)) } diff --git a/src/route.rs b/src/route.rs index e6ab45745..1eb323068 100644 --- a/src/route.rs +++ b/src/route.rs @@ -1,5 +1,3 @@ -#![allow(clippy::rc_buffer)] // inner value is mutated before being shared (`Rc::get_mut`) - use std::{future::Future, mem, rc::Rc}; use actix_http::http::Method; diff --git a/src/types/path.rs b/src/types/path.rs index cd24deb81..4b60d27c0 100644 --- a/src/types/path.rs +++ b/src/types/path.rs @@ -90,7 +90,7 @@ impl fmt::Display for Path { } } -/// See [here](#usage) for example of usage as an extractor. +/// See [here](#Examples) for example of usage as an extractor. impl FromRequest for Path where T: de::DeserializeOwned, diff --git a/src/types/payload.rs b/src/types/payload.rs index 00047e8b1..73987def5 100644 --- a/src/types/payload.rs +++ b/src/types/payload.rs @@ -43,12 +43,12 @@ use crate::{ /// Ok(format!("Request Body Bytes:\n{:?}", bytes)) /// } /// ``` -pub struct Payload(crate::dev::Payload); +pub struct Payload(dev::Payload); impl Payload { /// Unwrap to inner Payload type. #[inline] - pub fn into_inner(self) -> crate::dev::Payload { + pub fn into_inner(self) -> dev::Payload { self.0 } } @@ -62,7 +62,7 @@ impl Stream for Payload { } } -/// See [here](#usage) for example of usage as an extractor. +/// See [here](#Examples) for example of usage as an extractor. impl FromRequest for Payload { type Error = Error; type Future = Ready>; diff --git a/src/types/query.rs b/src/types/query.rs index ba2034bfc..9fac21173 100644 --- a/src/types/query.rs +++ b/src/types/query.rs @@ -105,7 +105,7 @@ impl fmt::Display for Query { } } -/// See [here](#usage) for example of usage as an extractor. +/// See [here](#Examples) for example of usage as an extractor. impl FromRequest for Query { type Error = Error; type Future = Ready>;