Guessing MIME-Type, setting Content-Type based on file extension

mime_guess MIME Content-Type first unwrap_or

One of the first web "applications" I wrote in Rust was the rustatic a small program that helps me to run a local web server to look at a static web site. A problem recently encountered was that it sent back every file as HTML. This broke the AJAX-using JavaScript code I wrote. It did not know what to do with the JSON file that was sent to the client as text/html.

At first I patched the code mapping the json and js extensions to their repsective MIME-Type so the application will set the Content-Type properly, but then I thougt, surely there is at leas one crate that will do the mapping for me.

That's how I found mime_guess.

Here is a small example I put together for myself:

The dependencies in Cargo.toml

examples/guessing-mime-type/Cargo.toml

[package]
name = "guessing-mime-type"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
mime_guess = "2.0.4"

The source code

examples/guessing-mime-type/src/main.rs

use mime_guess::mime;

fn main() {
    let guess = mime_guess::from_path("some_file.gif");
    assert_eq!(guess.first(), Some(mime::IMAGE_GIF));
    println!("{}", guess.first().unwrap()); // image/gif

    println!("{}", mime_guess::from_path("some.gif").first().unwrap()); // image/gif
    println!("{}", mime_guess::from_path("some.js").first().unwrap()); // application/javascript
    println!("{}", mime_guess::from_path("some.json").first().unwrap()); // application/json
    println!("{}", mime_guess::from_path("some.yaml").first().unwrap()); // text/x-yaml
    println!("{}", mime_guess::from_path("some.yml").first().unwrap()); // text/x-yaml
    println!("{}", mime_guess::from_path("some.html").first().unwrap()); // text/html
    println!("{}", mime_guess::from_path("some.py").first().unwrap()); // text/plain
    println!("{}", mime_guess::from_path("some.rs").first().unwrap()); // text/x-rust

    assert!(mime_guess::from_path("some.qqrq").first().is_none());
    assert!(mime_guess::from_path("some").first().is_none());

    println!(
        "{}",
        mime_guess::from_path("some")
            .first()
            .unwrap_or(mime::TEXT_HTML)
    ); // text/html
}

Explanation

The first method will return an Option.

If the extension is not recognized, or if there is no extension then it will return None.

Otherwise it can be stringified to what needs to be the Content-Type.

In the last example I used unwrap_or to set a default MIME-Type that simplified my code a lot.

mime_guess::from_path("some").first().unwrap_or(mime::TEXT_HTML);

Related Pages

Files - dealing with files in Rust

Author

Gabor Szabo (szabgab)

Gabor Szabo, the author of the Rust Maven web site maintains several Open source projects in Rust and while he still feels he has tons of new things to learn about Rust he already offers training courses in Rust and still teaches Python, Perl, git, GitHub, GitLab, CI, and testing.

Gabor Szabo