Search code examples
rustreqwest

reqwest - dynamically determine file_name for multipart::Part


I am using reqwest to send a jar file to an api using multipart. This is what I have so far:

use std::path::PathBuf;

use anyhow::Result;
use reqwest::{multipart, Body, Client};
use tokio::fs::File;
use tokio_util::codec::{BytesCodec, FramedRead};

pub async fn upload_file(client: &reqwest::Client, fpath: &PathBuf) -> Result<()> {
    let url = "my.url.com/v1";
    let file = File::open(&fpath).await?;
    let stream = FramedRead::new(file, BytesCodec::new());
    let body = Body::wrap_stream(stream);
    let some_file = multipart::Part::stream(body)
        .file_name("asdf.jar") // <- Problem here!
        .mime_str("application/x-java-archive")?;

    let form = multipart::Form::new().part("jarfile", some_file);
    client
        .post(url)
        .multipart(form)
        .send()
        .await?
        .error_for_status()?;
    Ok(())

This code runs as expected and the file is uploaded but is named asdf.jar. I would like to dynamically set the filename based on the fpath: PathBuf variable but I am having problems with the file_name method of multipart::Part. It accepts type Into<Cow<'static, str>> but the lifetime is giving me trouble here. Am I trying to do something the API just does not support or am I missing something?


Solution

  • I realized that I could just use good ol' String. I extracted the filename like this:

    let fname = fpath
        .file_name()
        .unwrap()
        .to_os_string()
        .into_string()
        .ok()
        .unwrap();
    let some_file = multipart::Part::stream(body)
        .file_name(fname) // <- Problem solved!
        .mime_str("application/x-java-archive")?;