8000 Form parsing with data stream regression: Multipart(failed to lock multipart state) · Issue #2941 · rwf2/Rocket · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
8000

Form parsing with data stream regression: Multipart(failed to lock multipart state) #2941

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
4 tasks done
johnli360 opened this issue May 15, 2025 · 0 comments
Open
4 tasks done
Labels
triage A bug report being investigated

Comments

@johnli360
Copy link
johnli360 commented May 15, 2025

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.
@johnli360 johnli360 added the triage A bug report being investigated label May 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage A bug report being investigated
Projects
None yet
Development

No branches or pull requests

1 participant
0