Skip to content
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

http POST: missing boundary with content-type "multipart/form-data" #2118

Closed
ghost opened this issue Jun 29, 2021 · 4 comments
Closed

http POST: missing boundary with content-type "multipart/form-data" #2118

ghost opened this issue Jun 29, 2021 · 4 comments
Labels
scope: api.js The @tauri-apps/api npm package type: bug

Comments

@ghost
Copy link

ghost commented Jun 29, 2021

Currently it is not possible to use "multipart/form-data" as content-type posting form-data with the http module due to missing boundary.

Example using the JS-API setting content-type by hand resulting in missing boundary:

return await http.fetch(url, {
    method: "POST",
    headers: {
        "Content-Type": "multipart/form-data",
    },
    responseType: 1,
    body: http.Body.form({
        name: "test"
    })
});

This might be an issue with attohttpc, leaving the content type blank the content-type defaults to "application/x-www-form-urlencoded".

I am using the latest version of tauri (1.0.0-beta.4).

@ghost ghost added the type: bug label Jun 29, 2021
@nothingismagick
Copy link
Sponsor Member

This is a great finding, thankyou! I see a couple options here:

  1. You create a custom command and use something like reqwest
  2. We create an advanced plugin using something like reqwest
  3. We replace our current client with something like reqwest

@lucasfernog
Copy link
Member

The issue is that we need to use the dedicated multipart APIs to support this:
https://docs.rs/reqwest/0.11.4/reqwest/struct.RequestBuilder.html#method.multipart
https://docs.rs/attohttpc/0.17.0/attohttpc/struct.MultipartBuilder.html

But the crate's design for multipart is filled with references, so it's tricky to implement it without introducing a breaking change.

@mgedgaudas
Copy link

mgedgaudas commented Nov 9, 2021

This is a great finding, thankyou! I see a couple options here:

  1. You create a custom command and use something like reqwest
  2. We create an advanced plugin using something like reqwest
  3. We replace our current client with something like reqwest

Would be nice if someone could provide an example how a custom command would look like for sending multipart form with files if this feature is not going to natively supported any time soon.

@FabianLars
Copy link
Sponsor Member

@mgedgaudas
Kinda ugly cause i'm lazy, but that should provide the basics:

#[tauri::command]
async fn upload_file(file: std::path::PathBuf) -> Result<(), String> {
                  // ^We expect the frontend to send a file path.

    let client = reqwest::Client::new();

    let file_name = file.file_name().unwrap().to_string_lossy().to_string();
    let file_content = tokio::fs::read(file).await.map_err(|err| err.to_string())?;
    let part = reqwest::multipart::Part::bytes(file_content).file_name(file_name);
    let form = reqwest::multipart::Form::new().part("file", part);

    client
        .post("URL_HERE")
        .multipart(form)
        .send()
        .await
        .map_err(|err| err.to_string())?;

    Ok(())
}

You need to enable the multipart feature for reqwest.
And while you're at it you probably want to add the reqwest-client feature flag to tauri in Cargo.toml so that you don't bundle 2 different http libs into the binary (the default one is attohttpc)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
scope: api.js The @tauri-apps/api npm package type: bug
Projects
None yet
Development

No branches or pull requests

5 participants