diff --git a/axum/src/extract/content_length_limit.rs b/axum/src/extract/content_length_limit.rs index a3d1f711c9..6e53af7b40 100644 --- a/axum/src/extract/content_length_limit.rs +++ b/axum/src/extract/content_length_limit.rs @@ -9,6 +9,15 @@ use std::ops::Deref; /// `GET`, `HEAD`, and `OPTIONS` requests are rejected if they have a `Content-Length` header, /// otherwise they're accepted without the body being checked. /// +/// Note: `ContentLengthLimit` can wrap types that extract the body (for example, [`Form`] or [`Json`]) +/// if that is the case, the inner type will consume the request's body, which means the +/// `ContentLengthLimit` must come *last* if the handler uses several extractors. See +/// ["the order of extractors"][order-of-extractors] +/// +/// [order-of-extractors]: crate::extract#the-order-of-extractors +/// [`Form`]: crate::form::Form +/// [`Json`]: crate::json::Json +/// /// # Example /// /// ```rust,no_run diff --git a/axum/src/extract/multipart.rs b/axum/src/extract/multipart.rs index af0fe20236..70b1620746 100644 --- a/axum/src/extract/multipart.rs +++ b/axum/src/extract/multipart.rs @@ -17,6 +17,12 @@ use std::{ /// Extractor that parses `multipart/form-data` requests (commonly used with file uploads). /// +/// Since extracting multipart form data from the request requires consuming the body, the +/// `Multipart` extractor must be *last* if there are multiple extractors in a handler. +/// See ["the order of extractors"][order-of-extractors] +/// +/// [order-of-extractors]: crate::extract#the-order-of-extractors +/// /// # Example /// /// ```rust,no_run diff --git a/axum/src/extract/request_parts.rs b/axum/src/extract/request_parts.rs index eff77a2b34..933e7a71b2 100644 --- a/axum/src/extract/request_parts.rs +++ b/axum/src/extract/request_parts.rs @@ -103,6 +103,12 @@ where /// Extractor that extracts the request body as a [`Stream`]. /// +/// Since extracting the request body requires consuming it, the `BodyStream` extractor must be +/// *last* if there are multiple extractors in a handler. +/// See ["the order of extractors"][order-of-extractors] +/// +/// [order-of-extractors]: crate::extract#the-order-of-extractors +/// /// # Example /// /// ```rust,no_run @@ -173,6 +179,11 @@ fn body_stream_traits() { /// Extractor that extracts the raw request body. /// +/// Since extracting the raw request body requires consuming it, the `RawBody` extractor must be +/// *last* if there are multiple extractors in a handler. See ["the order of extractors"][order-of-extractors] +/// +/// [order-of-extractors]: crate::extract#the-order-of-extractors +/// /// # Example /// /// ```rust,no_run diff --git a/axum/src/extract/state.rs b/axum/src/extract/state.rs index 784709550c..aabeb000f9 100644 --- a/axum/src/extract/state.rs +++ b/axum/src/extract/state.rs @@ -11,7 +11,7 @@ use std::{ /// Note this extractor is not available to middleware. See ["Accessing state in /// middleware"][state-from-middleware] for how to access state in middleware. /// -/// [state-from-middleware]: ../middleware/index.html#accessing-state-in-middleware +/// [state-from-middleware]: crate::middleware#accessing-state-in-middleware /// /// # With `Router` /// @@ -22,6 +22,7 @@ use std::{ /// // /// // here you can put configuration, database connection pools, or whatever /// // state you need +/// // Note: the application state *must* derive `Clone` (or be wrapped in e.g. `Arc`) /// #[derive(Clone)] /// struct AppState {} /// diff --git a/axum/src/form.rs b/axum/src/form.rs index 414e1fd527..43bddfc299 100644 --- a/axum/src/form.rs +++ b/axum/src/form.rs @@ -16,6 +16,11 @@ use std::ops::Deref; /// If used as an extractor `Form` will deserialize `application/x-www-form-urlencoded` request /// bodies into some target type via [`serde::Deserialize`]. /// +/// Since parsing form data requires consuming the request body, the `Form` extractor must be +/// *last* if there are multiple extractors in a handler. See ["the order of extractors"][order-of-extractors] +/// +/// [order-of-extractors]: crate::extract#the-order-of-extractors +/// /// ```rust /// use axum::Form; /// use serde::Deserialize; diff --git a/axum/src/json.rs b/axum/src/json.rs index d49630fa54..472668727b 100644 --- a/axum/src/json.rs +++ b/axum/src/json.rs @@ -25,6 +25,12 @@ use std::ops::{Deref, DerefMut}; /// type. /// - Buffering the request body fails. /// +/// Since parsing JSON requires consuming the request body, the `Json` extractor must be +/// *last* if there are multiple extractors in a handler. +/// See ["the order of extractors"][order-of-extractors] +/// +/// [order-of-extractors]: crate::extract#the-order-of-extractors +/// /// See [`JsonRejection`] for more details. /// /// # Extractor example