Multipart handler not respecting RequestBodyLimitLayer adjustment #1666
-
I have a web service that deploys an SPA as it's primary route and a multipart upload route. I'm new to axum and I've put this together mostly from copying the examples. Even though I'm adjusting the use std::net::SocketAddr;
use axum::extract::Multipart;
use axum::{routing::post, Router};
use axum_extra::routing::SpaRouter;
use tower_http::limit::RequestBodyLimitLayer;
const CONTENT_LENGTH_LIMIT: usize = 20 * 1024 * 1024;
#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();
let index = SpaRouter::new("/", "web/dist").index_file("index.html");
let app: Router = Router::new()
.merge(index)
.layer(RequestBodyLimitLayer::new(CONTENT_LENGTH_LIMIT))
.route("/upload", post(upload));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
tracing::debug!("listening on http://{}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
async fn upload(mut multipart: Multipart) {
while let Some(mut field) = multipart.next_field().await.unwrap() {
let name = field.name().unwrap().to_string();
let data = field.bytes().await.unwrap();
println!("Length of `{}` is {} bytes", name, data.len());
}
} Here's the error I receive when trying to upload a 2.1 MB zip: And here's the http request itself if that's helpful POST http://localhost:3000/upload
Content-Type: multipart/form-data; boundary=boundary
--boundary
Content-Disposition: form-data; name="file"; filename="file.zip"
< ./file.zip How can I adjust the code above so that the upload route will accept files below my custom limit |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 6 replies
-
You need to apply the layer after adding the upload route, not before. |
Beta Was this translation helpful? Give feedback.
-
I was able to get it to respect the let app: Router = Router::new()
.merge(index)
.route("/upload", post(upload))
.layer(DefaultBodyLimit::disable())
.layer(RequestBodyLimitLayer::new(CONTENT_LENGTH_LIMIT)); Is this intended functionality? I didn't see this being a requirement in any examples. Edit: Per @jplatte's suggestion, this works too and is much cleaner: let app: Router = Router::new()
.merge(index)
.route("/upload", post(upload))
.layer(DefaultBodyLimit::max(CONTENT_LENGTH_LIMIT)); |
Beta Was this translation helpful? Give feedback.
I was able to get it to respect the
RequestBodyLimitLayer
by disabling theDefaultBodyLimit
in the layer before, like this:Is this intended functionality? I didn't see this being a requirement in any examples.
Edit:
Per @jplatte's suggestion, this works too and is much cleaner: