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

Part::content_type only returns the media type, not the subtype #1042

Closed
Pikrass opened this issue May 17, 2023 · 1 comment · Fixed by #1046
Closed

Part::content_type only returns the media type, not the subtype #1042

Pikrass opened this issue May 17, 2023 · 1 comment · Fixed by #1046
Labels
easy Good for newcomers feature New feature or request

Comments

@Pikrass
Copy link

Pikrass commented May 17, 2023

Version
0.3.5

Platform
Linux 6.1.0-6-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.15-1 (2023-03-05) x86_64 GNU/Linux
(but not relevant here)

Description
I'm using the warp::multipart::form filter.
When parsing the returned FormData, the part's content_type method only returns the media type (that is for instance "image" instead of "image/jpeg").

Snippet of my code:

pub async fn parse_multipart(mut form: FormData) -> Result<(), Rejection> {
    let rej = || warp::reject::custom(crate::endpoints::BadRequest);

    while let Some(Ok(part)) = form.next().await {
        let name = String::from(part.name());
        let content_type = part.content_type().map(|s| String::from(s));

        let data: Vec<u8> = part
            .stream()
            .map_err(|_| ())
            .map_ok(|buf|
                stream::iter(
                    buf.reader().bytes().map(|b| Result::<u8, ()>::Ok(b.unwrap()))
                )
            )
            .try_flatten()
            .try_collect()
            .await
            .or(Err(rej()))?;

        // [Do something with name, content_type and data]
    }

    Ok(()) // Return actual data instead
}

The content_type variable on line 6 gets set to eg "image" instead of "image/jpeg".

Relevant code in warp:

/// Get the content-type of this part, if present.
pub fn content_type(&self) -> Option<&str> {
let content_type = self.part.content_type();
content_type.map(|t| t.type_().as_str())
}

Here self.part is a multer::Field. It content_type method returns a Mime. The Mime::type_ method only returns the "toplevel media type".

We need a new method to return the whole Mime struct.
Also the current Part::content_type should probably be changed to return t.to_string() instead (or t.essence_str()).

Workaround
For now, I just deduce the full MIME type from the filename instead.

@Pikrass Pikrass added the bug Something isn't working label May 17, 2023
@seanmonstar seanmonstar added feature New feature or request easy Good for newcomers and removed bug Something isn't working labels May 17, 2023
@seanmonstar
Copy link
Owner

Oh good catch. I agree, that should be changed to just return the full mime.as_ref().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
easy Good for newcomers feature New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants