-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Open
Labels
triageA bug report being investigatedA bug report being investigated
Description
Rocket Version
0.5.1
Operating System
Ubuntu 22.04.5 LTS
Rust Toolchain Version
rustc 1.86.0
What happened?
Executing the following request: touch test && curl -F file=@test http://localhost:8000/upload
, on the Rocket code provided in the test case on version 0.5.0 works (i.e. the request form is parsed without issue, and 200 OK is returned). On 0.5.1 I get:
POST /upload multipart/form-data:
>> Matched: (upload) POST /upload multipart/form-data
>> Data guard `Form < MyForm < '_ > >` failed: Errors([Error { name: None, value: None, kind: Multipart(failed to lock multipart state), entity: Form }]).
>> Outcome: Error(400 Bad Request)
>> No 400 catcher registered. Using Rocket default.
>> Response succeeded.
Test Case
use rocket::data::Data;
use rocket::form::{DataField, Errors, Form, FromFormField};
use rocket::{FromForm, launch, post, routes};
struct Upload<'r> {
data: Data<'r>,
}
#[rocket::async_trait]
impl<'v> FromFormField<'v> for Upload<'v> {
async fn from_data(f: DataField<'v, '_>) -> Result<Self, Errors<'v>> {
Ok(Upload { data: f.data })
}
}
#[derive(FromForm)]
struct MyForm<'a> {
file: Upload<'a>,
}
#[post("/upload", format = "multipart/form-data", data = "<form>")]
fn upload(form: Form<MyForm<'_>>) {
println!("upload!");
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![upload])
}
Log Output
-- configuration trace information --
>> "address" parameter source: rocket::Config::default()
>> "port" parameter source: rocket::Config::default()
>> "workers" parameter source: rocket::Config::default()
>> "max_blocking" parameter source: rocket::Config::default()
>> "keep_alive" parameter source: rocket::Config::default()
>> "ident" parameter source: rocket::Config::default()
>> "ip_header" parameter source: rocket::Config::default()
>> "limits" parameter source: rocket::Config::default()
>> "temp_dir" parameter source: rocket::Config::default()
>> "log_level" parameter source: `ROCKET_` environment variable(s)
>> "shutdown" parameter source: rocket::Config::default()
>> "cli_colors" parameter source: rocket::Config::default()
🔧 Configured for debug.
>> address: 127.0.0.1
>> port: 8000
>> workers: 12
>> max blocking threads: 512
>> ident: Rocket
>> IP header: X-Real-IP
>> limits: bytes = 8KiB, data-form = 2MiB, file = 1MiB, form = 32KiB, json = 1MiB, msgpack = 1MiB, string = 8KiB
>> temp dir: /tmp
>> http/2: true
>> keep-alive: 5s
>> tls: disabled
>> shutdown: ctrlc = true, force = true, signals = [SIGTERM], grace = 2s, mercy = 3s
>> log level: debug
>> cli colors: true
📬 Routes:
>> (upload) POST /upload multipart/form-data
📡 Fairings:
>> Shield (liftoff, response, singleton)
🛡️ Shield:
>> Permissions-Policy: interest-cohort=()
>> X-Content-Type-Options: nosniff
>> X-Frame-Options: SAMEORIGIN
🚀 Rocket has launched from http://127.0.0.1:8000
--> /home/sejnld/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rocket-0.5.1/src/server.rs:77
received request: Request {
method: POST,
uri: /upload,
version: HTTP/1.1,
headers: {
"host": "localhost:8000",
"user-agent": "curl/7.81.0",
"accept": "*/*",
"content-length": "196",
"content-type": "multipart/form-data; boundary=------------------------954c7e155e174b71",
},
body: Body(
Streaming,
),
}
POST /upload multipart/form-data:
>> Matched: (upload) POST /upload multipart/form-data
>> multipart field: Field { state: Mutex { data: MultipartState { buffer: StreamBuffer, boundary: "------------------------954c7e155e174b71", stage: ReadingFieldData, next_field_idx: 1, curr_field_name: Some("file"), curr_field_size_limit: 2097152, curr_field_size_counter: 0, constraints: Constraints { size_limit: SizeLimit { whole_stream: 2097152, per_field: 2097152, field_map: {} }, allowed_fields: None } }}, done: false, headers: {"content-disposition": "form-data; name=\"file\"; filename=\"test\"", "content-type": "application/octet-stream"}, content_disposition: ContentDisposition { field_name: Some("file"), file_name: Some("test") }, content_type: Some("application/octet-stream"), idx: 0 }
>> Data guard `Form < MyForm < '_ > >` failed: Errors([Error { name: None, value: None, kind: Multipart(failed to lock multipart state), entity: Form }]).
>> Outcome: Error(400 Bad Request)
>> No 400 catcher registered. Using Rocket default.
--> /home/sejnld/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rocket-0.5.1/src/server.rs:166
sending response: Response {
status: 400,
version: HTTP/1.1,
headers: {
"content-type": "text/html; charset=utf-8",
"server": "Rocket",
"permissions-policy": "interest-cohort=()",
"x-content-type-options": "nosniff",
"x-frame-options": "SAMEORIGIN",
"content-length": "471",
},
body: Body(
Streaming,
),
}
>> Response succeeded.
Additional Context
No response
System Checks
- My bug report relates to functionality.
- I have tested against the latest Rocket release or a recent git commit.
- I have tested against the latest stable
rustc
toolchain. - I was unable to find this issue previously reported.
Metadata
Metadata
Assignees
Labels
triageA bug report being investigatedA bug report being investigated