-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Open
Description
- I have looked for existing issues (including closed) about this
Bug Report
multipart/form-data parsing failure on limited instead of a "limited" error
Version
jose.duarte@Mac t % cargo tree | grep axum
├── axum v0.8.1
│ ├── axum-core v0.5.0
Platform
Darwin Mac.lan 24.2.0 Darwin Kernel Version 24.2.0: Fri Dec 6 18:51:28 PST 2024; root:xnu-11215.61.5~2/RELEASE_ARM64_T8112 arm64
and
Linux parthenon 6.8.0-52-generic #53-Ubuntu SMP PREEMPT_DYNAMIC Sat Jan 11 00:06:25 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Crates
Description
Reproducer:
Code
use axum::{
extract::{DefaultBodyLimit, FromRequest, MatchedPath, Multipart, Path, Request},
http::StatusCode,
routing::put,
Router,
};
use futures_util::TryStreamExt;
use tokio_util::io::StreamReader;
use tower_http::trace::TraceLayer;
use tracing::level_filters::LevelFilter;
use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
use uuid::Uuid;
#[tracing::instrument]
async fn upload(request: Request) -> Result<(), (StatusCode, String)> {
tracing::debug!("creating multipart");
let mut multipart = Multipart::from_request(request, &())
.await
.map_err(|err| (StatusCode::BAD_REQUEST, err.to_string()))?;
tracing::debug!("creating field");
let Some(reader) = multipart
.next_field()
.await
.map_err(|err| (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()))?
else {
return Err((StatusCode::BAD_REQUEST, "no field available".to_string()));
};
tracing::debug!("creating stream reader");
let mut reader = StreamReader::new(reader.map_err(std::io::Error::other));
tracing::debug!("creating/truncating file");
let mut file = tokio::fs::File::create("/tmp/t/test_file")
.await
.map_err(|err| (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()))?;
tracing::debug!("reading in stream");
tokio::io::copy(&mut reader, &mut file)
.await
.map_err(|err| (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()))?;
Ok(())
}
#[tokio::main]
async fn main() {
tracing_subscriber::registry()
.with(fmt::layer().with_file(true).with_line_number(true))
.with(
EnvFilter::builder()
.with_default_directive(LevelFilter::DEBUG.into())
.from_env()
.unwrap(),
)
.init();
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
.await
.unwrap();
let router = Router::new()
.route(
"/upload",
put(upload), // .layer(DefaultBodyLimit::disable())
)
.layer(
TraceLayer::new_for_http().make_span_with(|request: &Request<_>| {
let matched_path = request
.extensions()
.get::<MatchedPath>()
.map(MatchedPath::as_str);
tracing::info_span!(
"request",
method = ?request.method(),
matched_path,
request_id = %Uuid::new_v4()
)
}),
);
axum::serve(listener, router).await.unwrap()
}Cargo.toml
[package]
name = "t"
version = "0.1.0"
edition = "2021"
[dependencies]
axum = { version = "0.8.1", features = ["multipart"] }
futures-util = "0.3.31"
tokio = { version = "1.43.0", features = ["full"] }
tokio-util = { version = "0.7.13", features = ["io"] }
tower = "0.5.2"
tower-http = { version = "0.6.2", features = ["trace"] }
tracing = "0.1.41"
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
uuid = { version = "1.13.1", features = ["v4"] }I expected to see this happen: when uploading a large file using cURL, I was expecting the "limited" error.
Instead, this happened:
jose.duarte@Mac t % dd if=/dev/urandom of=1GB bs=1G count=1
jose.duarte@Mac t % curl -v -X PUT -F "upload=@1GB" 127.0.0.1:3000/upload
* Trying 127.0.0.1:3000...
* Connected to 127.0.0.1 (127.0.0.1) port 3000
> PUT /upload HTTP/1.1
> Host: 127.0.0.1:3000
> User-Agent: curl/8.7.1
> Accept: */*
> Content-Length: 1073742033
> Content-Type: multipart/form-data; boundary=------------------------VlVd06f5jOjyD4I9oh8pVm
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
<
< HTTP/1.1 500 Internal Server Error
< content-type: text/plain; charset=utf-8
< content-length: 43
< date: Fri, 07 Feb 2025 12:17:19 GMT
<
* HTTP error before end of send, stop sending
* abort upload after having sent 3914268 bytes
* Closing connection
Error parsing `multipart/form-data` request%
Additional notes
I'm available to help fix, I suspect that this error:
https://github.com/tokio-rs/axum/blob/main/axum/src/extract/multipart.rs#L249
Is either not being hit or propagated upwards
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels