mirror of
https://github.com/tokio-rs/axum.git
synced 2024-12-27 06:50:52 +01:00
Remove Sync
requirement from response bodies (#440)
As we learned [in Tonic] bodies don't need to be `Sync` because they can only be polled from one thread at a time. This changes axum's bodies to no longer require `Sync` and makes `BoxBody` an alias for `UnsyncBoxBody<Bytes, axum::Error>`. [in Tonic]: https://github.com/hyperium/tonic/issues/117
This commit is contained in:
parent
9465128f3e
commit
3d07d40e02
13 changed files with 47 additions and 30 deletions
|
@ -34,6 +34,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
thus wasn't necessary
|
||||
- **breaking:** Vendor `AddExtensionLayer` and `AddExtension` to reduce public
|
||||
dependencies
|
||||
- **breaking:** `body::BoxBody` is now a type alias for
|
||||
`http_body::combinators::UnsyncBoxBody` and thus is no longer `Sync`. This
|
||||
is because bodies are streams and requiring streams to be `Sync` is
|
||||
unnecessary.
|
||||
- **added:** Implement `IntoResponse` for `http_body::combinators::UnsyncBoxBody`.
|
||||
- Routing:
|
||||
- Big internal refactoring of routing leading to several improvements ([#363])
|
||||
- **added:** Wildcard routes like `.route("/api/users/*rest", service)` are now supported.
|
||||
|
|
|
@ -29,8 +29,8 @@ bitflags = "1.0"
|
|||
bytes = "1.0"
|
||||
futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
|
||||
http = "0.2"
|
||||
http-body = "0.4.3"
|
||||
hyper = { version = "0.14", features = ["server", "tcp", "stream"] }
|
||||
http-body = "0.4.4"
|
||||
hyper = { version = "0.14.14", features = ["server", "tcp", "stream"] }
|
||||
matchit = "0.4.4"
|
||||
percent-encoding = "2.1"
|
||||
pin-project-lite = "0.2.7"
|
||||
|
|
|
@ -20,15 +20,15 @@ pub use bytes::Bytes;
|
|||
///
|
||||
/// This is used in axum as the response body type for applications. Its
|
||||
/// necessary to unify multiple response bodies types into one.
|
||||
pub type BoxBody = http_body::combinators::BoxBody<Bytes, Error>;
|
||||
pub type BoxBody = http_body::combinators::UnsyncBoxBody<Bytes, Error>;
|
||||
|
||||
/// Convert a [`http_body::Body`] into a [`BoxBody`].
|
||||
pub fn box_body<B>(body: B) -> BoxBody
|
||||
where
|
||||
B: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
||||
B: http_body::Body<Data = Bytes> + Send + 'static,
|
||||
B::Error: Into<BoxError>,
|
||||
{
|
||||
body.map_err(Error::new).boxed()
|
||||
body.map_err(Error::new).boxed_unsync()
|
||||
}
|
||||
|
||||
pub(crate) fn empty() -> BoxBody {
|
||||
|
|
|
@ -114,8 +114,8 @@ where
|
|||
S: Service<Request<ReqBody>, Response = Response<ResBody>> + Clone,
|
||||
F: FnOnce(S::Error) -> Res + Clone,
|
||||
Res: IntoResponse,
|
||||
ResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
||||
ResBody::Error: Into<BoxError> + Send + Sync + 'static,
|
||||
ResBody: http_body::Body<Data = Bytes> + Send + 'static,
|
||||
ResBody::Error: Into<BoxError>,
|
||||
{
|
||||
type Response = Response<BoxBody>;
|
||||
type Error = Infallible;
|
||||
|
@ -181,8 +181,8 @@ pub mod future {
|
|||
Fut: Future<Output = Result<Response<B>, E>>,
|
||||
F: FnOnce(E) -> Res,
|
||||
Res: IntoResponse,
|
||||
B: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
||||
B::Error: Into<BoxError> + Send + Sync + 'static,
|
||||
B: http_body::Body<Data = Bytes> + Send + 'static,
|
||||
B::Error: Into<BoxError>,
|
||||
{
|
||||
type Output = Result<Response<BoxBody>, Infallible>;
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ where
|
|||
E: FromRequest<ReqBody> + 'static,
|
||||
ReqBody: Default + Send + 'static,
|
||||
S: Service<Request<ReqBody>, Response = Response<ResBody>> + Clone,
|
||||
ResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
||||
ResBody: http_body::Body<Data = Bytes> + Send + 'static,
|
||||
ResBody::Error: Into<BoxError>,
|
||||
{
|
||||
type Response = Response<BoxBody>;
|
||||
|
@ -213,7 +213,7 @@ where
|
|||
E: FromRequest<ReqBody>,
|
||||
S: Service<Request<ReqBody>, Response = Response<ResBody>>,
|
||||
ReqBody: Default,
|
||||
ResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
||||
ResBody: http_body::Body<Data = Bytes> + Send + 'static,
|
||||
ResBody::Error: Into<BoxError>,
|
||||
{
|
||||
type Output = Result<Response<BoxBody>, S::Error>;
|
||||
|
|
|
@ -53,7 +53,7 @@ pub struct Multipart {
|
|||
impl<B> FromRequest<B> for Multipart
|
||||
where
|
||||
B: http_body::Body<Data = Bytes> + Default + Unpin + Send + 'static,
|
||||
B::Error: Into<BoxError> + 'static,
|
||||
B::Error: Into<BoxError>,
|
||||
{
|
||||
type Rejection = MultipartRejection;
|
||||
|
||||
|
|
|
@ -281,8 +281,8 @@ where
|
|||
S::Future: Send,
|
||||
T: 'static,
|
||||
ReqBody: Send + 'static,
|
||||
ResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
||||
ResBody::Error: Into<BoxError> + Send + Sync + 'static,
|
||||
ResBody: http_body::Body<Data = Bytes> + Send + 'static,
|
||||
ResBody::Error: Into<BoxError>,
|
||||
{
|
||||
type Sealed = sealed::Hidden;
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ where
|
|||
impl<H, T, K, V> IntoResponse for (Headers<H>, T)
|
||||
where
|
||||
T: IntoResponse,
|
||||
T::Body: Body<Data = Bytes> + Send + Sync + 'static,
|
||||
T::Body: Body<Data = Bytes> + Send + 'static,
|
||||
<T::Body as Body>::Error: Into<BoxError>,
|
||||
H: IntoIterator<Item = (K, V)>,
|
||||
K: TryInto<HeaderName>,
|
||||
|
@ -141,7 +141,7 @@ where
|
|||
impl<H, T, K, V> IntoResponse for (StatusCode, Headers<H>, T)
|
||||
where
|
||||
T: IntoResponse,
|
||||
T::Body: Body<Data = Bytes> + Send + Sync + 'static,
|
||||
T::Body: Body<Data = Bytes> + Send + 'static,
|
||||
<T::Body as Body>::Error: Into<BoxError>,
|
||||
H: IntoIterator<Item = (K, V)>,
|
||||
K: TryInto<HeaderName>,
|
||||
|
|
|
@ -163,7 +163,7 @@ pub trait IntoResponse {
|
|||
/// [`axum::body::Empty<Bytes>`]: crate::body::Empty
|
||||
/// [`axum::body::Full<Bytes>`]: crate::body::Full
|
||||
/// [`axum::body::BoxBody`]: crate::body::BoxBody
|
||||
type Body: http_body::Body<Data = Bytes, Error = Self::BodyError> + Send + Sync + 'static;
|
||||
type Body: http_body::Body<Data = Bytes, Error = Self::BodyError> + Send + 'static;
|
||||
|
||||
/// The error type `Self::Body` might generate.
|
||||
///
|
||||
|
@ -217,7 +217,7 @@ where
|
|||
|
||||
impl<B> IntoResponse for Response<B>
|
||||
where
|
||||
B: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
||||
B: http_body::Body<Data = Bytes> + Send + 'static,
|
||||
B::Error: Into<BoxError>,
|
||||
{
|
||||
type Body = B;
|
||||
|
@ -257,10 +257,22 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<E> IntoResponse for http_body::combinators::UnsyncBoxBody<Bytes, E>
|
||||
where
|
||||
E: Into<BoxError> + 'static,
|
||||
{
|
||||
type Body = Self;
|
||||
type BodyError = E;
|
||||
|
||||
fn into_response(self) -> Response<Self> {
|
||||
Response::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<B, F> IntoResponse for MapData<B, F>
|
||||
where
|
||||
B: http_body::Body + Send + Sync + 'static,
|
||||
F: FnMut(B::Data) -> Bytes + Send + Sync + 'static,
|
||||
B: http_body::Body + Send + 'static,
|
||||
F: FnMut(B::Data) -> Bytes + Send + 'static,
|
||||
B::Error: Into<BoxError>,
|
||||
{
|
||||
type Body = Self;
|
||||
|
@ -273,8 +285,8 @@ where
|
|||
|
||||
impl<B, F, E> IntoResponse for MapErr<B, F>
|
||||
where
|
||||
B: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
||||
F: FnMut(B::Error) -> E + Send + Sync + 'static,
|
||||
B: http_body::Body<Data = Bytes> + Send + 'static,
|
||||
F: FnMut(B::Error) -> E + Send + 'static,
|
||||
E: Into<BoxError>,
|
||||
{
|
||||
type Body = Self;
|
||||
|
|
|
@ -41,7 +41,7 @@ impl<E> fmt::Debug for MethodNotAllowed<E> {
|
|||
|
||||
impl<B, E> Service<Request<B>> for MethodNotAllowed<E>
|
||||
where
|
||||
B: Send + Sync + 'static,
|
||||
B: Send + 'static,
|
||||
{
|
||||
type Response = Response<BoxBody>;
|
||||
type Error = E;
|
||||
|
|
|
@ -77,7 +77,7 @@ impl<B> Clone for Router<B> {
|
|||
|
||||
impl<B> Default for Router<B>
|
||||
where
|
||||
B: Send + Sync + 'static,
|
||||
B: Send + 'static,
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
|
@ -99,7 +99,7 @@ const NEST_TAIL_PARAM_CAPTURE: &str = "/*axum_nest";
|
|||
|
||||
impl<B> Router<B>
|
||||
where
|
||||
B: Send + Sync + 'static,
|
||||
B: Send + 'static,
|
||||
{
|
||||
/// Create a new `Router`.
|
||||
///
|
||||
|
@ -240,7 +240,7 @@ where
|
|||
+ Send
|
||||
+ 'static,
|
||||
<L::Service as Service<Request<LayeredReqBody>>>::Future: Send + 'static,
|
||||
LayeredResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
||||
LayeredResBody: http_body::Body<Data = Bytes> + Send + 'static,
|
||||
LayeredResBody::Error: Into<BoxError>,
|
||||
{
|
||||
let layer = ServiceBuilder::new()
|
||||
|
@ -361,7 +361,7 @@ where
|
|||
|
||||
impl<B> Service<Request<B>> for Router<B>
|
||||
where
|
||||
B: Send + Sync + 'static,
|
||||
B: Send + 'static,
|
||||
{
|
||||
type Response = Response<BoxBody>;
|
||||
type Error = Infallible;
|
||||
|
|
|
@ -16,7 +16,7 @@ pub(crate) struct NotFound;
|
|||
|
||||
impl<B> Service<Request<B>> for NotFound
|
||||
where
|
||||
B: Send + Sync + 'static,
|
||||
B: Send + 'static,
|
||||
{
|
||||
type Response = Response<BoxBody>;
|
||||
type Error = Infallible;
|
||||
|
|
|
@ -464,7 +464,7 @@ impl<S, F, B> MethodRouter<S, F, B> {
|
|||
impl<S, F, B, ResBody> Service<Request<B>> for MethodRouter<S, F, B>
|
||||
where
|
||||
S: Service<Request<B>, Response = Response<ResBody>> + Clone,
|
||||
ResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
||||
ResBody: http_body::Body<Data = Bytes> + Send + 'static,
|
||||
ResBody::Error: Into<BoxError>,
|
||||
F: Service<Request<B>, Response = Response<BoxBody>, Error = S::Error> + Clone,
|
||||
{
|
||||
|
@ -514,7 +514,7 @@ pin_project! {
|
|||
impl<S, F, B, ResBody> Future for MethodRouterFuture<S, F, B>
|
||||
where
|
||||
S: Service<Request<B>, Response = Response<ResBody>> + Clone,
|
||||
ResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
||||
ResBody: http_body::Body<Data = Bytes> + Send + 'static,
|
||||
ResBody::Error: Into<BoxError>,
|
||||
F: Service<Request<B>, Response = Response<BoxBody>, Error = S::Error>,
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue