# class MIME::Types

MIME::Types is a registry of MIME types. It is both a class (created with ::new) and a default registry (loaded automatically or through interactions with #[] and #type_for).

## The Default mime-types Registry¶ ↑

The default mime-types registry is loaded automatically when the library is required (`require 'mime/types'`), but it may be lazily loaded (loaded on first use) with the use of the environment variable `RUBY_MIME_TYPES_LAZY_LOAD` having any value other than `false`. The initial startup is about 14× faster (~10 ms vs ~140 ms), but the registry will be loaded at some point in the future.

The default mime-types registry can also be loaded from a Marshal cache file specific to the version of MIME::Types being loaded. This will be handled automatically with the use of a file referred to in the environment variable `RUBY_MIME_TYPES_CACHE`. MIME::Types will attempt to load the registry from this cache file (MIME::Type::Cache.load); if it cannot be loaded (because the file does not exist, there is an error, or the data is for a different version of mime-types), the default registry will be loaded from the normal JSON version and then the cache file will be written to the location indicated by `RUBY_MIME_TYPES_CACHE`. Cache file loads just over 4½× faster (~30 ms vs ~140 ms). loads.

Notes:

- The loading of the default registry is not atomic; when using a multi-threaded environment, it is recommended that lazy loading is not used and mime-types is loaded as early as possible.

- Cache files should be specified per application in a multiprocess environment and should be initialized during deployment or before forking to minimize the chance that the multiple processes will be trying to write to the same cache file at the same time, or that two applications that are on different versions of mime-types would be thrashing the cache.

- Unless cache files are preinitialized, the application using the mime-types cache file must have read/write permission to the cache file.

## Usage¶ ↑

    require 'mime/types'

    plaintext = MIME::Types['text/plain']
    print plaintext.media_type           # => 'text'
    print plaintext.sub_type             # => 'plain'

    puts plaintext.extensions.join(" ")  # => 'asc txt c cc h hh cpp'

    puts plaintext.encoding              # => 8bit
    puts plaintext.binary?               # => false
    puts plaintext.ascii?                # => true
    puts plaintext.obsolete?             # => false
    puts plaintext.registered?           # => true
    puts plaintext == 'text/plain'       # => true
    puts MIME::Type.simplified('x-appl/x-zip') # => 'appl/zip'

### Constants

VERSION

  The release version of Ruby MIME::Types

### Attributes

logger[RW]

Configure the MIME::Types logger. This defaults to an instance of a logger that passes messages (unformatted) through to Kernel#warn.

data_version[R]

The data version.

### Public Class Methods

[](type_id, flags = {}) click to toggle source

#[] against the default MIME::Types registry.

    # File lib/mime/types.rb, line 236
    def [](type_id, flags = {})
      __types__[type_id, flags]
    end

add(*types) click to toggle source

#add against the default MIME::Types registry.

    # File lib/mime/types.rb, line 261
    def add(*types)
      __types__.add(*types)
    end

cache_file() click to toggle source

Returns the currently defined cache file, if any.

This method has been deprecated and will be removed in mime-types 3.0.

    # File lib/mime/types.rb, line 268
    def cache_file
      MIME::Types.deprecated(self, __method__)
      ENV['RUBY_MIME_TYPES_CACHE']
    end

count() click to toggle source

#count against the default MIME::Types registry.

    # File lib/mime/types.rb, line 241
    def count
      __types__.count
    end

each() { |t| ... } click to toggle source

#each against the default MIME::Types registry.

    # File lib/mime/types.rb, line 246
    def each
      if block_given?
        __types__.each { |t| yield t }
      else
        enum_for(:each)
      end
    end

load_from_file(filename) click to toggle source

Load MIME::Types from a v1 file registry.

This method has been deprecated and will be removed in mime-types 3.0.

    # File lib/mime/types.rb, line 230
    def load_from_file(filename)
      MIME::Types.deprecated(self, __method__)
      MIME::Types::Loader.load_from_v1(filename)
    end

new() click to toggle source

Creates a new MIME::Types registry.

    # File lib/mime/types.rb, line 72
    def initialize
      @type_variants    = Container.new
      @extension_index  = Container.new
      @data_version     = VERSION.dup.freeze
    end

of(filename, platform = false)
Alias for: type_for
type_for(filename, platform = false) click to toggle source

#type_for against the default MIME::Types registry.

    # File lib/mime/types.rb, line 255
    def type_for(filename, platform = false)
      __types__.type_for(filename, platform)
    end

Also aliased as: of

### Private Class Methods

__types__() click to toggle source

    # File lib/mime/types.rb, line 287
    def __types__
      (defined?(@__types__) and @__types__) or load_default_mime_types
    end

lazy_load?() click to toggle source

    # File lib/mime/types.rb, line 283
    def lazy_load?
      (lazy = ENV['RUBY_MIME_TYPES_LAZY_LOAD']) && (lazy != 'false')
    end

load_default_mime_types(mode = load_mode()) click to toggle source

    # File lib/mime/types.rb, line 297
    def load_default_mime_types(mode = load_mode())
      @__types__ = MIME::Types::Cache.load
      unless @__types__
        @__types__ = MIME::Types::Loader.load(mode)
        MIME::Types::Cache.save(@__types__)
      end
      @__types__
    end

load_mode() click to toggle source

    # File lib/mime/types.rb, line 292
    def load_mode
      {}
    end

### Public Instance Methods

[](type_id, flags = {}) click to toggle source

Returns a list of MIME::Type objects, which may be empty. The optional flag parameters are `:complete` (finds only complete MIME::Type objects) and `:registered` (finds only MIME::Types that are registered). It is possible for multiple matches to be returned for either type (in the example below, 'text/plain' returns two values – one for the general case, and one for VMS systems).

    puts "\nMIME::Types['text/plain']"
    MIME::Types['text/plain'].each { |t| puts t.to_a.join(", ") }

    puts "\nMIME::Types[/^image/, complete: true]"
    MIME::Types[/^image/, :complete => true].each do |t|
      puts t.to_a.join(", ")
    end

If multiple type definitions are returned, returns them sorted as follows:

    1. Complete definitions sort before incomplete ones;
    2. IANA-registered definitions sort before LTSW-recorded
       definitions.
    3. Generic definitions sort before platform-specific ones;
    4. Current definitions sort before obsolete ones;
    5. Obsolete definitions with use-instead clauses sort before those
       without;
    6. Obsolete definitions use-instead clauses are compared.
    7. Sort on name.

An additional flag of :platform (finds only MIME::Types for the current platform) is currently supported but deprecated.

    # File lib/mime/types.rb, line 141
    def [](type_id, flags = {})
      if flags[:platform]
        MIME::Types.deprecated(self, __method__, 'using the :platform flag')
      end

      matches = case type_id
                when MIME::Type
                  @type_variants[type_id.simplified]
                when Regexp
                  match(type_id)
                else
                  @type_variants[MIME::Type.simplified(type_id)]
                end

      prune_matches(matches, flags).sort { |a, b| a.priority_compare(b) }
    end

add(*types) click to toggle source

Add one or more MIME::Type objects to the set of known types. If the type is already known, a warning will be displayed.

The last parameter may be the value `:silent` or `true` which will suppress duplicate MIME type warnings.

    # File lib/mime/types.rb, line 192
    def add(*types)
      quiet = ((types.last == :silent) or (types.last == true))

      types.each do |mime_type|
        case mime_type
        when true, false, nil, Symbol
          nil
        when MIME::Types
          variants = mime_type.instance_variable_get(:@type_variants)
          add(*variants.values.flatten, quiet)
        when Array
          add(*mime_type, quiet)
        else
          add_type(mime_type, quiet)
        end
      end
    end

add_type(type, quiet = false) click to toggle source

Add a single MIME::Type object to the set of known types. If the `type` is already known, a warning will be displayed. The `quiet` parameter may be a truthy value to suppress that warning.

    # File lib/mime/types.rb, line 213
      def add_type(type, quiet = false)
        if !quiet and @type_variants[type.simplified].include?(type)
          MIME::Types.logger.warn <<-warning
    Type #{type} is already registered as a variant of #{type.simplified}.
          warning
        end

        add_type_variant!(type)
        index_extensions!(type)
      end

count() click to toggle source

Returns the number of known type variants.

    # File lib/mime/types.rb, line 97
    def count
      @type_variants.values.reduce(0) { |m, o| m + o.size }
    end

each() { |t| ... } click to toggle source

Iterates through the type variants.

    # File lib/mime/types.rb, line 102
    def each
      if block_given?
        @type_variants.each_value { |tv| tv.each { |t| yield t } }
      else
        enum_for(:each)
      end
    end

of(filename, platform = false)
Alias for: type_for
type_for(filename, platform = false) click to toggle source

Return the list of MIME::Types which belongs to the file based on its filename extension. If there is no extension, the filename will be used as the matching criteria on its own.

This will always return a merged, flatten, priority sorted, unique array.

    puts MIME::Types.type_for('citydesk.xml')
      => [application/xml, text/xml]
    puts MIME::Types.type_for('citydesk.gif')
      => [image/gif]
    puts MIME::Types.type_for(%w(citydesk.xml citydesk.gif))
      => [application/xml, image/gif, text/xml]

If `platform` is `true`, then only file types that are specific to the current platform will be returned. This parameter has been deprecated.

    # File lib/mime/types.rb, line 173
    def type_for(filename, platform = false)
      types = Array(filename).flat_map { |fn|
        @extension_index[fn.chomp.downcase[/\.?([^.]*?)$/, 1]]
      }.compact.sort { |a, b| a.priority_compare(b) }.uniq

      if platform
        MIME::Types.deprecated(self, __method__, 'using the platform parameter')
        types.select(&:platform?)
      else
        types
      end
    end

Also aliased as: of

### Private Instance Methods

add_type_variant!(mime_type) click to toggle source

    # File lib/mime/types.rb, line 309
    def add_type_variant!(mime_type)
      @type_variants[mime_type.simplified] << mime_type
    end

index_extensions!(mime_type) click to toggle source

    # File lib/mime/types.rb, line 313
    def index_extensions!(mime_type)
      mime_type.extensions.each { |ext| @extension_index[ext] << mime_type }
    end

match(pattern) click to toggle source

    # File lib/mime/types.rb, line 324
    def match(pattern)
      @type_variants.select { |k, _| k =~ pattern }.values.flatten
    end

prune_matches(matches, flags) click to toggle source

    # File lib/mime/types.rb, line 317
    def prune_matches(matches, flags)
      matches.delete_if { |e| !e.complete? } if flags[:complete]
      matches.delete_if { |e| !e.platform? } if flags[:platform]
      matches.delete_if { |e| !e.registered? } if flags[:registered]
      matches
    end