module MIME

Overview

This module implements a global MIME registry.

require "mime"

MIME.from_extension(".html")         # => "text/html; charset=utf-8"
MIME.from_filename("path/file.html") # => "text/html; charset=utf-8"

The registry will be populated with some default values (see DEFAULT_TYPES) as well as the operating system's MIME database.

Default initialization can be skipped by calling MIME.init(false) before the first query to the MIME database.

OS-provided MIME database

On a POSIX system, the following files are tried to be read in sequential order, stopping at the first existing file. These values override those from DEFAULT_TYPES.

/etc/mime.types
/etc/httpd/mime.types                    # Mac OS X
/etc/httpd/conf/mime.types               # Apache
/etc/apache/mime.types                   # Apache 1
/etc/apache2/mime.types                  # Apache 2
/usr/local/etc/httpd/conf/mime.types
/usr/local/lib/netscape/mime.types
/usr/local/etc/httpd/conf/mime.types     # Apache 1.2
/usr/local/etc/mime.types                # FreeBSD
/usr/share/misc/mime.types               # OpenBSD

Registering custom MIME types

Applications can register their own MIME types:

require "mime"
MIME.from_extension?(".cr")     # => nil
MIME.extensions("text/crystal") # => Set(String).new

MIME.register(".cr", "text/crystal")
MIME.from_extension?(".cr")     # => "text/crystal"
MIME.extensions("text/crystal") # => Set(String){".cr"}

Loading a custom MIME database

To load a custom MIME database, .load_mime_database can be called with an IO to read the database from.

# Load user-defined MIME types
File.open("~/.mime.types") do |io|
  MIME.load_mime_database(io)
end

Loaded values override previously defined mappings.

The data format must follow the format of mime.types: Each line declares a MIME type followed by a whitespace-separated list of extensions mapped to this type. Everything following a # is considered a comment until the end of line. Empy line are ignored.

text/html html htm

# comment

Defined in:

mime.cr

Constant Summary

DEFAULT_TYPES = {".css" => "text/css; charset=utf-8", ".gif" => "image/gif", ".htm" => "text/html; charset=utf-8", ".html" => "text/html; charset=utf-8", ".jpg" => "image/jpeg", ".jpeg" => "image/jpeg", ".js" => "application/javascript; charset=utf-8", ".json" => "application/json", ".pdf" => "application/pdf", ".png" => "image/png", ".svg" => "image/svg+xml", ".txt" => "text/plain; charset=utf-8", ".xml" => "text/xml; charset=utf-8", ".wasm" => "application/wasm"}

A limited set of default MIME types.

TSPECIAL_CHARACTERS = {'(', ')', '<', '>', '@', ',', ';', ':', '\\', '"', '/', '[', ']', '?', '='}

tspecial as defined by RFC 1521 and RFC 2045

Class Method Summary

Class Method Detail

def self.extensions(type : String) : Set(String) #

Returns all extensions registered for type.


[View source]
def self.from_extension(extension : String, default) : String #

Looks up the MIME type associated with extension.

A case sensitive search is tried first, if this yields no result, it is matched case-insensitive. Returns default if extension is not registered.


[View source]
def self.from_extension(extension : String) : String #

Looks up the MIME type associated with extension.

A case sensitive search is tried first, if this yields no result, it is matched case-insensitive. Raises KeyError if extension is not registered.


[View source]
def self.from_extension(extension : String, &block) #

Looks up the MIME type associated with extension.

A case sensitive search is tried first, if this yields no result, it is matched case-insensitive. Runs the fiven block if extension is not registered.


[View source]
def self.from_extension?(extension : String) : String? #

Looks up the MIME type associated with extension.

A case sensitive search is tried first, if this yields no result, it is matched case-insensitive. Returns nil if extension is not registered.


[View source]
def self.from_filename(filename : String, default) : String #

Looks up the MIME type associated with the extension in filename.

A case sensitive search is tried first, if this yields no result, it is matched case-insensitive. Returns default if extension is not registered.


[View source]
def self.from_filename(filename : String) : String #

Looks up the MIME type associated with the extension in filename.

A case sensitive search is tried first, if this yields no result, it is matched case-insensitive. Raises KeyError if extension is not registered.


[View source]
def self.from_filename(filename : String, &block) #

Looks up the MIME type associated with the extension in filename.

A case sensitive search is tried first, if this yields no result, it is matched case-insensitive. Runs the fiven block if extension is not registered.


[View source]
def self.from_filename?(filename : String) : String? #

Looks up the MIME type associated with the extension in filename.

A case sensitive search is tried first, if this yields no result, it is matched case-insensitive. Returns nil if extension is not registered.


[View source]
def self.init(load_defaults : Bool = true) : Nil #

Initializes the MIME database.

The default behaviour is to load the internal defaults as well as the OS-provided MIME database. This can be disabled with load_defaults set to false.

This method usually doesn't need to be called explicitly when the default behaviour is expected. It will be called implicitly with load_defaults: true when a query method is called and the MIME database has not been initialized before.

Calling this method repeatedly is allowed.


[View source]
def self.init(filename : String) : Nil #

Initializes the MIME database loading contents from a file.

This will neither load the internal defaults nor the OS-provided MIME database, only the database at filename (using .load_mime_database).

Callig this method repeatedly is allowed.


[View source]
def self.load_mime_database(io : IO) : Nil #

Reads MIME type mappings from an IO and registers the extension-to-type relation (see .register).

The format follows that of mime.types: Each line is list of MIME type and zero or more extensions, separated by whitespace.


[View source]
def self.register(extension : String, type : String) : Nil #

Register type for extension.

extension must start with a dot (.) and must not contain any null bytes.


[View source]