Actix-web Multipart form_data testing

Hi,

I am trying to use the basic example to upload a file and some json value (In the example, there is only one name value, but I intend to add more data in futur).

This is the basic source code : actix_multipart - Rust

So, in mine I have this :


#[derive(Debug, Deserialize)]
struct Metadata {
    name: String,
}

#[derive(Debug, MultipartForm)]
struct UploadForm {
    #[multipart(limit = "200MB")]
    file: TempFile,
    json: MpJson<Metadata>,
}

#[post("/api/test")]
pub async fn handler(MultipartForm(form): MultipartForm<UploadForm>) -> impl Responder {
    format!(
        "name {} , with size: {}",
        form.json.name, form.file.size
    )
}

I would like to test it in order to add other functionnalities after but the curl command does not works... Maybe I make a mistake, but I just copy it and change url, etc...
I would like also to test it with Postman for exemple.
But each time json value is not valid. I think it is not a rust problem, but as I need to test my functionnalities... I do not know what is wrong with my json...

I this as the file body is in file key, I can give the name I want to the file in json...

Did you check this one?

400 (Bad Request) - help - The Rust Programming Language Forum

If that's unhelpful, you may need to include the JS request here.

You're using the text/plain content-type for the JSON payload in Postman. Make sure you use application/json instead.

1 Like

Hi,

With Postman, I already added a content-type, but there is one by default... and it was not working...

And I can only put Test or File as parameter ?

I am trying to create my own integration test to test this...
I read documentation : Form in reqwest::multipart - Rust

I solved my problem one by one... but I got this error...
I have difficulty to see the problem with my json...

An error occurred processing field: json, exception.details: Field { name: "json", source: ContentType }
#[cfg(test)]
mod tests {

    #[test]
    fn test_with_file() {
        let form = reqwest::blocking::multipart::Form::new()
            .text("json", "{\"name\":\"toto\"}")
            .file("file", "Complete_path_until\\FileForTest.tif");

        match form {
            Ok(form) => {
                let boundary = form.boundary();
                let res = reqwest::blocking::Client::new()
                    .post("http://localhost:8080/api/test")
                    .header("content-type", format!("multipart/form-data; boundary={}", boundary))
                    .multipart(form) // exact body to send
                    .send();

                print!("RES : {:#?}", res)
            }
            Err(_) => assert!(false, "Error form"),
        }
        assert!(false);
    }
}

Without the json field, this works for the file...

Finaly, I found a solution to test without postman...
I post if someone has the same problem... :

#[cfg(test)]
mod tests {

    #[test]
    fn test_with_file() {
        let json = serde_json::json!({
            "name": "John Doe"
        });

        let form = reqwest::blocking::multipart::Form::new()
            //  .text("json", json.to_string())
            .file("file", "FileForTest.tif");

        match form {
            Ok(form) => {
                let part = reqwest::blocking::multipart::Part::text(json.to_string()).mime_str("application/json");
                if part.is_err() { assert!(false, "Error, with json part")}
                let part = part.unwrap();

                // Add the custom part to our form...
                let form = form.part("json", part);

                let boundary = form.boundary();
                print!("boundary is {:#?}", boundary);
                let res = reqwest::blocking::Client::new()
                    .post("http://localhost:8080/api/test")
                    .header(
                        "content-type",
                        format!("multipart/form-data; boundary={}", boundary),
                    )
                    .multipart(form) // exact body to send
                    .send();

                print!("RES : {:#?}", res)
            }
            Err(_) => assert!(false, "Erreur form"),
        }
        assert!(false);
    }
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.