Skip to content

Commit 4ffcfe6

Browse files
committed
use Body rather than BoxBody
1 parent f865576 commit 4ffcfe6

31 files changed

+178
-237
lines changed

Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@ members = [
1010
# with `cargo +nightly update -Z minimal-versions`
1111
"internal-minimal-versions",
1212
]
13+
14+
[patch.crates-io]
15+
hyper = { git = "https://github.com/hyperium/hyper", branch = "david/body-wrap-body" }

axum-core/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ bytes = "1.0"
1616
futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
1717
http = "0.2.7"
1818
http-body = "0.4.5"
19+
hyper = "0.14"
1920
mime = "0.3.16"
2021

2122
[dev-dependencies]
2223
axum = { path = "../axum", version = "0.5" }
2324
futures-util = "0.3"
24-
hyper = "0.14"
2525
tokio = { version = "1.0", features = ["macros"] }

axum-core/src/body.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
use crate::{BoxError, Error};
44
use bytes::Bytes;
55
use bytes::{Buf, BufMut};
6-
use http_body::Body;
6+
use http_body::Body as _;
7+
8+
#[doc(no_inline)]
9+
pub use hyper::Body;
710

811
/// A boxed [`Body`] trait object.
912
///
@@ -55,7 +58,7 @@ where
5558
// THE SOFTWARE.
5659
pub(crate) async fn to_bytes<T>(body: T) -> Result<Bytes, T::Error>
5760
where
58-
T: Body,
61+
T: http_body::Body,
5962
{
6063
futures_util::pin_mut!(body);
6164

axum-core/src/error.rs

-7
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,6 @@ impl Error {
1414
inner: error.into(),
1515
}
1616
}
17-
18-
pub(crate) fn downcast_inner<T>(self) -> Result<Box<T>, BoxError>
19-
where
20-
T: std::error::Error + 'static,
21-
{
22-
self.inner.downcast()
23-
}
2417
}
2518

2619
impl fmt::Display for Error {

axum-core/src/extract/mod.rs

+8-14
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,17 @@
55
//! [`axum::extract`]: https://docs.rs/axum/latest/axum/extract/index.html
66
77
use self::rejection::*;
8-
use crate::{body::BoxBody, response::IntoResponse, BoxError};
8+
use crate::{body::Body, response::IntoResponse, BoxError};
99
use async_trait::async_trait;
1010
use bytes::Bytes;
11-
use http::{Extensions, HeaderMap, Method, Uri, Version};
11+
use http::{Extensions, HeaderMap, Method, Request, Uri, Version};
1212
use std::convert::Infallible;
1313

1414
pub mod rejection;
1515

1616
mod request_parts;
1717
mod tuple;
1818

19-
/// Type alias for [`http::Request`] whose body type defaults to [`BoxBody`], the most common body
20-
/// type used with axum.
21-
pub type Request<T = BoxBody> = http::Request<T>;
22-
2319
/// Types that can be created from requests.
2420
///
2521
/// See [`axum::extract`] for more details.
@@ -84,7 +80,7 @@ pub struct RequestParts {
8480
version: Version,
8581
headers: HeaderMap,
8682
extensions: Extensions,
87-
body: Option<BoxBody>,
83+
body: Option<Body>,
8884
}
8985

9086
impl RequestParts {
@@ -112,15 +108,13 @@ impl RequestParts {
112108
body,
113109
) = req.into_parts();
114110

115-
let body = crate::body::boxed(body);
116-
117111
RequestParts {
118112
method,
119113
uri,
120114
version,
121115
headers,
122116
extensions,
123-
body: Some(body),
117+
body: Some(Body::wrap_body(body)),
124118
}
125119
}
126120

@@ -165,7 +159,7 @@ impl RequestParts {
165159
/// been called.
166160
///
167161
/// [`take_body`]: RequestParts::take_body
168-
pub fn try_into_request(self) -> Result<Request<BoxBody>, BodyAlreadyExtracted> {
162+
pub fn try_into_request(self) -> Result<Request<Body>, BodyAlreadyExtracted> {
169163
let Self {
170164
method,
171165
uri,
@@ -243,20 +237,20 @@ impl RequestParts {
243237
/// Gets a reference to the request body.
244238
///
245239
/// Returns `None` if the body has been taken by another extractor.
246-
pub fn body(&self) -> Option<&BoxBody> {
240+
pub fn body(&self) -> Option<&Body> {
247241
self.body.as_ref()
248242
}
249243

250244
/// Gets a mutable reference to the request body.
251245
///
252246
/// Returns `None` if the body has been taken by another extractor.
253247
// this returns `&mut Option<B>` rather than `Option<&mut B>` such that users can use it to set the body.
254-
pub fn body_mut(&mut self) -> &mut Option<BoxBody> {
248+
pub fn body_mut(&mut self) -> &mut Option<Body> {
255249
&mut self.body
256250
}
257251

258252
/// Takes the body out of the request, leaving a `None` in its place.
259-
pub fn take_body(&mut self) -> Option<BoxBody> {
253+
pub fn take_body(&mut self) -> Option<Body> {
260254
self.body.take()
261255
}
262256
}

axum-core/src/extract/rejection.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,14 @@ impl FailedToBufferBody {
4545
where
4646
E: Into<BoxError>,
4747
{
48-
let err = match err.into().downcast::<crate::Error>() {
49-
Ok(err) => err,
50-
Err(err) => return Self::UnknownBodyError(UnknownBodyError::from_err(err)),
51-
};
52-
match err.downcast_inner::<http_body::LengthLimitError>() {
53-
Ok(err) => Self::LengthLimitError(LengthLimitError::from_err(err)),
54-
Err(err) => Self::UnknownBodyError(UnknownBodyError::from_err(err)),
48+
let err = err.into();
49+
if err
50+
.source()
51+
.map_or(false, |source| source.is::<http_body::LengthLimitError>())
52+
{
53+
Self::LengthLimitError(LengthLimitError::from_err(err))
54+
} else {
55+
Self::UnknownBodyError(UnknownBodyError::from_err(err))
5556
}
5657
}
5758
}

axum-core/src/extract/request_parts.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use super::{rejection::*, FromRequest, RequestParts};
2-
use crate::body::BoxBody;
2+
use crate::body::Body;
33
use async_trait::async_trait;
44
use bytes::Bytes;
55
use http::{Extensions, HeaderMap, Method, Request, Uri, Version};
66
use std::convert::Infallible;
77

88
#[async_trait]
9-
impl FromRequest for Request<BoxBody> {
9+
impl FromRequest for Request<Body> {
1010
type Rejection = BodyAlreadyExtracted;
1111

1212
async fn from_request(req: &mut RequestParts) -> Result<Self, Self::Rejection> {
@@ -68,7 +68,7 @@ impl FromRequest for HeaderMap {
6868
}
6969

7070
#[async_trait]
71-
impl FromRequest for BoxBody {
71+
impl FromRequest for Body {
7272
type Rejection = BodyAlreadyExtracted;
7373

7474
async fn from_request(req: &mut RequestParts) -> Result<Self, Self::Rejection> {
@@ -140,6 +140,6 @@ fn unwrap_infallible<T>(result: Result<T, Infallible>) -> T {
140140
}
141141
}
142142

143-
pub(crate) fn take_body(req: &mut RequestParts) -> Result<BoxBody, BodyAlreadyExtracted> {
143+
pub(crate) fn take_body(req: &mut RequestParts) -> Result<Body, BodyAlreadyExtracted> {
144144
req.take_body().ok_or(BodyAlreadyExtracted)
145145
}

axum-extra/src/json_lines.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use axum::{
44
async_trait,
5-
body::{BoxBody, Bytes, HttpBody, StreamBody},
5+
body::{Body, Bytes, HttpBody, StreamBody},
66
extract::{rejection::BodyAlreadyExtracted, FromRequest, RequestParts},
77
response::{IntoResponse, Response},
88
BoxError,
@@ -136,15 +136,17 @@ where
136136
pin_project! {
137137
struct BodyStream {
138138
#[pin]
139-
body: BoxBody,
139+
body: Body,
140140
}
141141
}
142142

143143
impl Stream for BodyStream {
144144
type Item = Result<Bytes, axum::Error>;
145145

146146
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
147-
Pin::new(&mut self.body).poll_data(cx)
147+
Pin::new(&mut self.body)
148+
.poll_data(cx)
149+
.map_err(axum::Error::new)
148150
}
149151
}
150152

axum-extra/src/routing/mod.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Additional types for defining routes.
22
33
use axum::{
4-
body::BoxBody,
4+
body::Body,
55
handler::Handler,
66
http::Request,
77
response::{Redirect, Response},
@@ -162,10 +162,7 @@ pub trait RouterExt: sealed::Sealed {
162162
/// ```
163163
fn route_with_tsr<T>(self, path: &str, service: T) -> Self
164164
where
165-
T: Service<Request<BoxBody>, Response = Response, Error = Infallible>
166-
+ Clone
167-
+ Send
168-
+ 'static,
165+
T: Service<Request<Body>, Response = Response, Error = Infallible> + Clone + Send + 'static,
169166
T::Future: Send + 'static,
170167
Self: Sized;
171168
}
@@ -253,10 +250,7 @@ impl RouterExt for Router {
253250

254251
fn route_with_tsr<T>(mut self, path: &str, service: T) -> Self
255252
where
256-
T: Service<Request<BoxBody>, Response = Response, Error = Infallible>
257-
+ Clone
258-
+ Send
259-
+ 'static,
253+
T: Service<Request<Body>, Response = Response, Error = Infallible> + Clone + Send + 'static,
260254
T::Future: Send + 'static,
261255
Self: Sized,
262256
{

axum-extra/src/routing/resource.rs

+4-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use axum::{
2-
body::BoxBody,
2+
body::Body,
33
handler::Handler,
44
http::Request,
55
response::Response,
@@ -138,10 +138,7 @@ impl Resource {
138138
/// The routes will be nested at `/{resource_name}/:{resource_name}_id`.
139139
pub fn nest<T>(mut self, svc: T) -> Self
140140
where
141-
T: Service<Request<BoxBody>, Response = Response, Error = Infallible>
142-
+ Clone
143-
+ Send
144-
+ 'static,
141+
T: Service<Request<Body>, Response = Response, Error = Infallible> + Clone + Send + 'static,
145142
T::Future: Send + 'static,
146143
{
147144
let path = self.show_update_destroy_path();
@@ -154,10 +151,7 @@ impl Resource {
154151
/// The routes will be nested at `/{resource_name}`.
155152
pub fn nest_collection<T>(mut self, svc: T) -> Self
156153
where
157-
T: Service<Request<BoxBody>, Response = Response, Error = Infallible>
158-
+ Clone
159-
+ Send
160-
+ 'static,
154+
T: Service<Request<Body>, Response = Response, Error = Infallible> + Clone + Send + 'static,
161155
T::Future: Send + 'static,
162156
{
163157
let path = self.index_create_path();
@@ -175,10 +169,7 @@ impl Resource {
175169

176170
fn route<T>(mut self, path: &str, svc: T) -> Self
177171
where
178-
T: Service<Request<BoxBody>, Response = Response, Error = Infallible>
179-
+ Clone
180-
+ Send
181-
+ 'static,
172+
T: Service<Request<Body>, Response = Response, Error = Infallible> + Clone + Send + 'static,
182173
T::Future: Send + 'static,
183174
{
184175
self.router = self.router.route(path, svc);

axum-extra/src/routing/spa.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use axum::{
2-
body::BoxBody,
2+
body::Body,
33
error_handling::HandleError,
44
response::Response,
55
routing::{get_service, Route},
@@ -151,8 +151,8 @@ impl<F, T> From<SpaRouter<T, F>> for Router
151151
where
152152
F: Clone + Send + 'static,
153153
HandleError<Route<io::Error>, F, T>:
154-
Service<Request<BoxBody>, Response = Response, Error = Infallible>,
155-
<HandleError<Route<io::Error>, F, T> as Service<Request<BoxBody>>>::Future: Send,
154+
Service<Request<Body>, Response = Response, Error = Infallible>,
155+
<HandleError<Route<io::Error>, F, T> as Service<Request<Body>>>::Future: Send,
156156
T: 'static,
157157
{
158158
fn from(spa: SpaRouter<T, F>) -> Self {
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use axum::extract::{Extension, Request};
1+
use axum::{extract::Extension, body::Body, http::Request};
22
use axum_macros::debug_handler;
33

44
#[debug_handler]
5-
async fn handler(_: Request, _: Extension<String>) {}
5+
async fn handler(_: Request<Body>, _: Extension<String>) {}
66

77
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: `Request` extractor should always be last
22
--> tests/debug_handler/fail/request_not_last.rs:5:18
33
|
4-
5 | async fn handler(_: Request, _: Extension<String>) {}
5-
| ^^^^^^^^^^
4+
5 | async fn handler(_: Request<Body>, _: Extension<String>) {}
5+
| ^^^^^^^^^^^^^^^^
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use axum::extract::{Extension, Request};
1+
use axum::{extract::Extension, body::Body, http::Request};
22
use axum_macros::debug_handler;
33

44
#[debug_handler]
5-
async fn handler(_: Extension<String>, _: Request) {}
5+
async fn handler(_: Extension<String>, _: Request<Body>) {}
66

77
fn main() {}

0 commit comments

Comments
 (0)