mime-types-3.6.0/ 0000755 0000041 0000041 00000000000 14726205276 013654 5 ustar www-data www-data mime-types-3.6.0/Licence.md 0000644 0000041 0000041 00000002236 14726205276 015543 0 ustar www-data www-data # Licence
- Copyright 2003–2019 Austin Ziegler and contributors.
The software in this repository is made available under the MIT license.
## MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
mime-types-3.6.0/Manifest.txt 0000644 0000041 0000041 00000001305 14726205276 016162 0 ustar www-data www-data .standard.yml
Code-of-Conduct.md
Contributing.md
History.md
Licence.md
Manifest.txt
README.rdoc
Rakefile
lib/mime-types.rb
lib/mime/type.rb
lib/mime/type/columnar.rb
lib/mime/types.rb
lib/mime/types/_columnar.rb
lib/mime/types/cache.rb
lib/mime/types/columnar.rb
lib/mime/types/container.rb
lib/mime/types/deprecations.rb
lib/mime/types/full.rb
lib/mime/types/loader.rb
lib/mime/types/logger.rb
lib/mime/types/registry.rb
test/bad-fixtures/malformed
test/fixture/json.json
test/fixture/old-data
test/fixture/yaml.yaml
test/minitest_helper.rb
test/test_mime_type.rb
test/test_mime_types.rb
test/test_mime_types_cache.rb
test/test_mime_types_class.rb
test/test_mime_types_lazy.rb
test/test_mime_types_loader.rb
mime-types-3.6.0/README.rdoc 0000644 0000041 0000041 00000021533 14726205276 015466 0 ustar www-data www-data = mime-types for Ruby
home :: https://github.com/mime-types/ruby-mime-types/
code :: https://github.com/mime-types/ruby-mime-types/
bugs :: https://github.com/mime-types/ruby-mime-types/issues
rdoc :: http://rdoc.info/gems/mime-types/
clog :: https://github.com/mime-types/ruby-mime-types/blob/master/History.md
continuous integration :: {
}[https://github.com/mime-types/ruby-mime-types/actions/workflows/ci.yml]
test coverage :: {
}[https://coveralls.io/github/mime-types/ruby-mime-types?branch=master]
== Description
The mime-types library provides a library and registry for information about
MIME content type definitions. It can be used to determine defined filename
extensions for MIME types, or to use filename extensions to look up the likely
MIME type definitions.
Version 3.0 is a major release that requires Ruby 2.0 compatibility and removes
deprecated functions. The columnar registry format introduced in 2.6 has been
made the primary format; the registry data has been extracted from this library
and put into {mime-types-data}[https://github.com/mime-types/mime-types-data].
Additionally, mime-types is now licensed exclusively under the MIT licence and
there is a code of conduct in effect. There are a number of other smaller
changes described in the History file.
=== About MIME Media Types
MIME content types are used in MIME-compliant communications, as in e-mail or
HTTP traffic, to indicate the type of content which is transmitted. The
mime-types library provides the ability for detailed information about MIME
entities (provided as an enumerable collection of MIME::Type objects) to be
determined and used. There are many types defined by RFCs and vendors, so the
list is long but by definition incomplete; don't hesitate to add additional
type definitions. MIME type definitions found in mime-types are from RFCs, W3C
recommendations, the {IANA Media Types
registry}[https://www.iana.org/assignments/media-types/media-types.xhtml], and
user contributions. It conforms to RFCs 2045 and 2231.
=== mime-types 3.x
Users are encouraged to upgrade to mime-types 3.x as soon as is practical.
mime-types 3.x requires Ruby 2.0 compatibility and a simpler licensing scheme.
== Synopsis
MIME types are used in MIME entities, as in email or HTTP traffic. It is useful
at times to have information available about MIME types (or, inversely, about
files). A MIME::Type stores the known information about one MIME type.
require 'mime/types'
plaintext = MIME::Types['text/plain'] # => [ text/plain ]
text = plaintext.first
puts text.media_type # => 'text'
puts text.sub_type # => 'plain'
puts text.extensions.join(' ') # => 'txt asc c cc h hh cpp hpp dat hlp'
puts text.preferred_extension # => 'txt'
puts text.friendly # => 'Text Document'
puts text.i18n_key # => 'text.plain'
puts text.encoding # => quoted-printable
puts text.default_encoding # => quoted-printable
puts text.binary? # => false
puts text.ascii? # => true
puts text.obsolete? # => false
puts text.registered? # => true
puts text.provisional? # => false
puts text.complete? # => true
puts text # => 'text/plain'
puts text == 'text/plain' # => true
puts 'text/plain' == text # => true
puts text == 'text/x-plain' # => false
puts 'text/x-plain' == text # => false
puts MIME::Type.simplified('x-appl/x-zip') # => 'x-appl/x-zip'
puts MIME::Type.i18n_key('x-appl/x-zip') # => 'x-appl.x-zip'
puts text.like?('text/x-plain') # => true
puts text.like?(MIME::Type.new('x-text/x-plain')) # => true
puts text.xrefs.inspect # => { "rfc" => [ "rfc2046", "rfc3676", "rfc5147" ] }
puts text.xref_urls # => [ "http://www.iana.org/go/rfc2046",
# "http://www.iana.org/go/rfc3676",
# "http://www.iana.org/go/rfc5147" ]
xtext = MIME::Type.new('x-text/x-plain')
puts xtext.media_type # => 'text'
puts xtext.raw_media_type # => 'x-text'
puts xtext.sub_type # => 'plain'
puts xtext.raw_sub_type # => 'x-plain'
puts xtext.complete? # => false
puts MIME::Types.any? { |type| type.content_type == 'text/plain' } # => true
puts MIME::Types.all?(&:registered?) # => false
# Various string representations of MIME types
qcelp = MIME::Types['audio/QCELP'].first # => audio/QCELP
puts qcelp.content_type # => 'audio/QCELP'
puts qcelp.simplified # => 'audio/qcelp'
xwingz = MIME::Types['application/x-Wingz'].first # => application/x-Wingz
puts xwingz.content_type # => 'application/x-Wingz'
puts xwingz.simplified # => 'application/x-wingz'
=== Columnar Store
mime-types uses as its primary registry storage format a columnar storage
format reducing the default memory footprint. This is done by selectively
loading the data on a per-attribute basis. When the registry is first loaded
from the columnar store, only the canonical MIME content type and known
extensions and the MIME type will be connected to its loading registry. When
other data about the type is required (including +preferred_extension+,
obsolete?, and registered?) that data is loaded from its own
column file for all types in the registry.
The load of any column data is performed with a Mutex to ensure that types are
updated safely in a multithreaded environment. Benchmarks show that while
columnar data loading is slower than the JSON store, it cuts the memory use by
a third over the JSON store.
If you prefer to load all the data at once, this can be specified in your
application Gemfile as:
gem 'mime-types', require: 'mime/types/full'
Projects that do not use Bundler should +require+ the same:
require 'mime/types/full'
Libraries that use mime-types are discouraged from choosing the JSON store.
For applications and clients that used mime-types 2.6 when the columnar store
was introduced, the require used previously will still work through at least
{version
4}[https://github.com/mime-types/ruby-mime-types/pull/96#issuecomment-100725400]
and possibly beyond; it is effectively an empty operation. You are recommended
to change your Gemfile as soon as is practical.
require 'mime/types/columnar'
Note that MIME::Type::Columnar and MIME::Types::Columnar are considered private
variant implementations of MIME::Type and MIME::Types and the specific
implementation should not be relied upon by consumers of the mime-types
library. Instead, depend on the public implementations (MIME::Type and
MIME::Types) only.
=== Cached Storage
mime-types supports a cache of MIME types using Marshal.dump. The
cache is invalidated for each version of the mime-types-data gem so that data
version 3.2015.1201 will not be reused with data version 3.2016.0101. If the
environment variable +RUBY_MIME_TYPES_CACHE+ is set to a cache file, mime-types
will attempt to load the MIME type registry from the cache file. If it cannot,
it will load the types normally and then saves the registry to the cache file.
The caching works with both full stores and columnar stores. Only the data that
has been loaded prior to saving the cache will be stored.
== mime-types Modified Semantic Versioning
The mime-types library has one version number, but this single version number
tracks both API changes and registry data changes; this is not wholly
compatible with all aspects of {Semantic Versioning}[http://semver.org/];
removing a MIME type from the registry *could* be considered a breaking change
under some interpretations of semantic versioning (as lookups for that
particular type would no longer work by default).
mime-types uses a modified semantic versioning scheme. Given the version
MAJOR.MINOR:
1. If an incompatible API (code) change is made, the MAJOR version will be
incremented, MINOR will be set to zero, and PATCH will be reset to the
implied zero.
2. If an API (code) feature is added that does not break compatibility, the
MINOR version will be incremented and PATCH will be reset to the implied zero.
3. If there is a bugfix to a feature added in the most recent MAJOR.MINOR
release, the implied PATCH value will be incremented resulting in
MAJOR.MINOR.PATCH.
In practical terms, there will be fewer releases of mime-types focussing on
features because of the existence of the
{mime-types-data}[https://github.com/mime-types/mime-types-data] gem, and if
features are marked deprecated in the course of mime-types 3.x, they will not
be removed until mime-types 4.x or possibly later.
{Code of Conduct}[Code-of-Conduct_md.html]
{Contributing}[Contributing_md.html]
{Licence}[Licence_md.html]
mime-types-3.6.0/.standard.yml 0000644 0000041 0000041 00000000102 14726205276 016246 0 ustar www-data www-data parallel: true
ruby_version: 2.3
ignore:
- 'mime-types.gemspec'
mime-types-3.6.0/lib/ 0000755 0000041 0000041 00000000000 14726205276 014422 5 ustar www-data www-data mime-types-3.6.0/lib/mime-types.rb 0000644 0000041 0000041 00000000064 14726205276 017040 0 ustar www-data www-data # frozen_string_literal: true
require "mime/types"
mime-types-3.6.0/lib/mime/ 0000755 0000041 0000041 00000000000 14726205276 015351 5 ustar www-data www-data mime-types-3.6.0/lib/mime/type/ 0000755 0000041 0000041 00000000000 14726205276 016332 5 ustar www-data www-data mime-types-3.6.0/lib/mime/type/columnar.rb 0000644 0000041 0000041 00000003213 14726205276 020476 0 ustar www-data www-data # frozen_string_literal: true
require "mime/type"
# A version of MIME::Type that works hand-in-hand with a MIME::Types::Columnar
# container to load data by columns.
#
# When a field is has not yet been loaded, that data will be loaded for all
# types in the container before forwarding the message to MIME::Type.
#
# More information can be found in MIME::Types::Columnar.
#
# MIME::Type::Columnar is *not* intended to be created except by
# MIME::Types::Columnar containers.
class MIME::Type::Columnar < MIME::Type
def initialize(container, content_type, extensions) # :nodoc:
@container = container
self.content_type = content_type
self.extensions = extensions
end
def self.column(*methods, file: nil) # :nodoc:
file ||= methods.first
file_method = :"load_#{file}"
methods.each do |m|
define_method m do |*args|
@container.send(file_method)
super(*args)
end
end
end
column :friendly
column :encoding, :encoding=
column :docs, :docs=
column :preferred_extension, :preferred_extension=
column :obsolete, :obsolete=, :obsolete?, :registered, :registered=, :registered?, :signature, :signature=,
:signature?, :provisional, :provisional=, :provisional?, file: "flags"
column :xrefs, :xrefs=, :xref_urls
column :use_instead, :use_instead=
def encode_with(coder) # :nodoc:
@container.send(:load_friendly)
@container.send(:load_encoding)
@container.send(:load_docs)
@container.send(:load_flags)
@container.send(:load_use_instead)
@container.send(:load_xrefs)
@container.send(:load_preferred_extension)
super
end
class << self
undef column
end
end
mime-types-3.6.0/lib/mime/types/ 0000755 0000041 0000041 00000000000 14726205276 016515 5 ustar www-data www-data mime-types-3.6.0/lib/mime/types/logger.rb 0000644 0000041 0000041 00000001353 14726205276 020323 0 ustar www-data www-data # frozen_string_literal: true
require "logger"
##
module MIME
##
class Types
class << self
# Configure the MIME::Types logger. This defaults to an instance of a
# logger that passes messages (unformatted) through to Kernel#warn.
attr_accessor :logger
end
class WarnLogger < ::Logger # :nodoc:
class WarnLogDevice < ::Logger::LogDevice # :nodoc:
def initialize(*)
end
def write(m)
Kernel.warn(m)
end
def close
end
end
def initialize(_one, _two = nil, _three = nil)
super(nil)
@logdev = WarnLogDevice.new
@formatter = ->(_s, _d, _p, m) { m }
end
end
self.logger = WarnLogger.new(nil)
end
end
mime-types-3.6.0/lib/mime/types/container.rb 0000644 0000041 0000041 00000003423 14726205276 021026 0 ustar www-data www-data # frozen_string_literal: true
require "set"
require "forwardable"
# MIME::Types requires a serializable keyed container that returns an empty Set
# on a key miss. Hash#default_value cannot be used because, while it traverses
# the Marshal format correctly, it will not survive any other serialization
# format (plus, a default of a mutable object resuls in a shared mess).
# Hash#default_proc cannot be used without a wrapper because it prevents
# Marshal serialization (and does not survive the round-trip).
class MIME::Types::Container # :nodoc:
extend Forwardable
def initialize(hash = {})
@container = {}
merge!(hash)
end
def [](key)
container[key] || EMPTY_SET
end
def []=(key, value)
container[key] =
case value
when Set
value
else
Set[*value]
end
end
def merge(other)
self.class.new(other)
end
def merge!(other)
tap {
other = other.is_a?(MIME::Types::Container) ? other.container : other
container.merge!(other)
normalize
}
end
def to_hash
container
end
def_delegators :@container,
:==,
:count,
:each,
:each_value,
:empty?,
:flat_map,
:keys,
:select,
:values
def add(key, value)
(container[key] ||= Set.new).add(value)
end
def marshal_dump
{}.merge(container)
end
def marshal_load(hash)
@container = hash
end
def encode_with(coder)
container.each { |k, v| coder[k] = v.to_a }
end
def init_with(coder)
@container = {}
coder.map.each { |k, v| container[k] = Set[*v] }
end
protected
attr_accessor :container
def normalize
container.each do |k, v|
next if v.is_a?(Set)
container[k] = Set[*v]
end
end
EMPTY_SET = Set.new.freeze
private_constant :EMPTY_SET
end
mime-types-3.6.0/lib/mime/types/deprecations.rb 0000644 0000041 0000041 00000002515 14726205276 021525 0 ustar www-data www-data # frozen_string_literal: true
require "mime/types/logger"
class << MIME::Types
# Used to mark a method as deprecated in the mime-types interface.
def deprecated(options = {}, &block) # :nodoc:
message =
if options[:message]
options[:message]
else
klass = options.fetch(:class)
msep = case klass
when Class, Module
"."
else
klass = klass.class
"#"
end
method = "#{klass}#{msep}#{options.fetch(:method)}"
pre = " #{options[:pre]}" if options[:pre]
post = case options[:next]
when :private, :protected
" and will be made #{options[:next]}"
when :removed
" and will be removed"
when nil, ""
nil
else
" #{options[:next]}"
end
<<-WARNING.chomp.strip
#{caller(2..2).first}: #{klass}#{msep}#{method}#{pre} is deprecated#{post}.
WARNING
end
if !__deprecation_logged?(message, options[:once])
MIME::Types.logger.__send__(options[:level] || :debug, message)
end
return unless block
block.call
end
private
def __deprecation_logged?(message, once)
return false unless once
@__deprecations_logged = {} unless defined?(@__deprecations_logged)
@__deprecations_logged.key?(message)
end
end
mime-types-3.6.0/lib/mime/types/full.rb 0000644 0000041 0000041 00000000405 14726205276 020003 0 ustar www-data www-data # frozen_string_literal: true
##
module MIME
##
class Types
unless private_method_defined?(:load_mode)
class << self
private
def load_mode
{columnar: false}
end
end
end
end
end
require "mime/types"
mime-types-3.6.0/lib/mime/types/columnar.rb 0000644 0000041 0000041 00000000064 14726205276 020662 0 ustar www-data www-data # frozen_string_literal: true
require "mime/types"
mime-types-3.6.0/lib/mime/types/loader.rb 0000644 0000041 0000041 00000011050 14726205276 020305 0 ustar www-data www-data # frozen_string_literal: true
##
module MIME; end
##
class MIME::Types; end
require "mime/types/data"
# This class is responsible for initializing the MIME::Types registry from
# the data files supplied with the mime-types library.
#
# The Loader will use one of the following paths:
# 1. The +path+ provided in its constructor argument;
# 2. The value of ENV["RUBY_MIME_TYPES_DATA"]; or
# 3. The value of MIME::Types::Data::PATH.
#
# When #load is called, the +path+ will be searched recursively for all YAML
# (.yml or .yaml) files. By convention, there is one file for each media
# type (application.yml, audio.yml, etc.), but this is not required.
class MIME::Types::Loader
# The path that will be read for the MIME::Types files.
attr_reader :path
# The MIME::Types container instance that will be loaded. If not provided
# at initialization, a new MIME::Types instance will be constructed.
attr_reader :container
# Creates a Loader object that can be used to load MIME::Types registries
# into memory, using YAML, JSON, or Columnar registry format loaders.
def initialize(path = nil, container = nil)
path = path || ENV["RUBY_MIME_TYPES_DATA"] || MIME::Types::Data::PATH
@container = container || MIME::Types.new
@path = File.expand_path(path)
end
# Loads a MIME::Types registry from YAML files (*.yml or
# *.yaml) recursively found in +path+.
#
# It is expected that the YAML objects contained within the registry array
# will be tagged as !ruby/object:MIME::Type.
#
# Note that the YAML format is about 2½ times *slower* than the JSON format.
#
# NOTE: The purpose of this format is purely for maintenance reasons.
def load_yaml
Dir[yaml_path].sort.each do |f|
container.add(*self.class.load_from_yaml(f), :silent)
end
container
end
# Loads a MIME::Types registry from JSON files (*.json)
# recursively found in +path+.
#
# It is expected that the JSON objects will be an array of hash objects.
# The JSON format is the registry format for the MIME types registry
# shipped with the mime-types library.
def load_json
Dir[json_path].sort.each do |f|
types = self.class.load_from_json(f)
container.add(*types, :silent)
end
container
end
# Loads a MIME::Types registry from columnar files recursively found in
# +path+.
def load_columnar
require "mime/types/columnar" unless defined?(MIME::Types::Columnar)
container.extend(MIME::Types::Columnar)
container.load_base_data(path)
container
end
# Loads a MIME::Types registry. Loads from JSON files by default
# (#load_json).
#
# This will load from columnar files (#load_columnar) if columnar:
# true is provided in +options+ and there are columnar files in +path+.
def load(options = {columnar: false})
if options[:columnar] && !Dir[columnar_path].empty?
load_columnar
else
load_json
end
end
class << self
# Loads the default MIME::Type registry.
def load(options = {columnar: false})
new.load(options)
end
# Loads MIME::Types from a single YAML file.
#
# It is expected that the YAML objects contained within the registry
# array will be tagged as !ruby/object:MIME::Type.
#
# Note that the YAML format is about 2½ times *slower* than the JSON
# format.
#
# NOTE: The purpose of this format is purely for maintenance reasons.
def load_from_yaml(filename)
begin
require "psych"
rescue LoadError
nil
end
require "yaml"
if old_yaml?
YAML.safe_load(read_file(filename), [MIME::Type])
else
YAML.safe_load(read_file(filename), permitted_classes: [MIME::Type])
end
end
# Loads MIME::Types from a single JSON file.
#
# It is expected that the JSON objects will be an array of hash objects.
# The JSON format is the registry format for the MIME types registry
# shipped with the mime-types library.
def load_from_json(filename)
require "json"
JSON.parse(read_file(filename)).map { |type| MIME::Type.new(type) }
end
private
def read_file(filename)
File.open(filename, "r:UTF-8:-", &:read)
end
def old_yaml?
@old_yaml ||=
begin
require "rubygems/version"
Gem::Version.new(YAML::VERSION) < Gem::Version.new("3.1")
end
end
end
private
def yaml_path
File.join(path, "*.y{,a}ml")
end
def json_path
File.join(path, "*.json")
end
def columnar_path
File.join(path, "*.column")
end
end
mime-types-3.6.0/lib/mime/types/registry.rb 0000644 0000041 0000041 00000003627 14726205276 020722 0 ustar www-data www-data # frozen_string_literal: true
require "mime/types/deprecations"
class << MIME::Types
include Enumerable
##
def new(*) # :nodoc:
super.tap do |types|
__instances__.add types
end
end
# MIME::Types#[] against the default MIME::Types registry.
def [](type_id, complete: false, registered: false)
__types__[type_id, complete: complete, registered: registered]
end
# MIME::Types#count against the default MIME::Types registry.
def count
__types__.count
end
# MIME::Types#each against the default MIME::Types registry.
def each
if block_given?
__types__.each { |t| yield t }
else
enum_for(:each)
end
end
# MIME::Types#type_for against the default MIME::Types registry.
def type_for(filename)
__types__.type_for(filename)
end
alias_method :of, :type_for
# MIME::Types#add against the default MIME::Types registry.
def add(*types)
__types__.add(*types)
end
private
def lazy_load?
return unless ENV.key?("RUBY_MIME_TYPES_LAZY_LOAD")
deprecated(
message: "Lazy loading ($RUBY_MIME_TYPES_LAZY_LOAD) is deprecated and will be removed."
)
ENV["RUBY_MIME_TYPES_LAZY_LOAD"] != "false"
end
def __types__
(defined?(@__types__) && @__types__) || load_default_mime_types
end
unless private_method_defined?(:load_mode)
def load_mode
{columnar: true}
end
end
def load_default_mime_types(mode = load_mode)
if (@__types__ = MIME::Types::Cache.load)
__instances__.add(@__types__)
else
@__types__ = MIME::Types::Loader.load(mode)
MIME::Types::Cache.save(@__types__)
end
@__types__
end
def __instances__
@__instances__ ||= Set.new
end
def reindex_extensions(type)
__instances__.each do |instance|
instance.send(:reindex_extensions!, type)
end
true
end
end
##
class MIME::Types
load_default_mime_types(load_mode) unless lazy_load?
end
mime-types-3.6.0/lib/mime/types/cache.rb 0000644 0000041 0000041 00000004023 14726205276 020104 0 ustar www-data www-data # frozen_string_literal: true
MIME::Types::Cache = Struct.new(:version, :data) # :nodoc:
# Caching of MIME::Types registries is advisable if you will be loading
# the default registry relatively frequently. With the class methods on
# MIME::Types::Cache, any MIME::Types registry can be marshaled quickly
# and easily.
#
# The cache is invalidated on a per-data-version basis; a cache file for
# version 3.2015.1118 will not be reused with version 3.2015.1201.
class << MIME::Types::Cache
# Attempts to load the cache from the file provided as a parameter or in
# the environment variable +RUBY_MIME_TYPES_CACHE+. Returns +nil+ if the
# file does not exist, if the file cannot be loaded, or if the data in
# the cache version is different than this version.
def load(cache_file = nil)
cache_file ||= ENV["RUBY_MIME_TYPES_CACHE"]
return nil unless cache_file && File.exist?(cache_file)
cache = Marshal.load(File.binread(cache_file))
if cache.version == MIME::Types::Data::VERSION
Marshal.load(cache.data)
else
MIME::Types.logger.error <<-WARNING.chomp.strip
Could not load MIME::Types cache: invalid version
WARNING
nil
end
rescue => e
MIME::Types.logger.error <<-WARNING.chomp.strip
Could not load MIME::Types cache: #{e}
WARNING
nil
end
# Attempts to save the types provided to the cache file provided.
#
# If +types+ is not provided or is +nil+, the cache will contain the
# current MIME::Types default registry.
#
# If +cache_file+ is not provided or is +nil+, the cache will be written
# to the file specified in the environment variable
# +RUBY_MIME_TYPES_CACHE+. If there is no cache file specified either
# directly or through the environment, this method will return +nil+
def save(types = nil, cache_file = nil)
cache_file ||= ENV["RUBY_MIME_TYPES_CACHE"]
return nil unless cache_file
types ||= MIME::Types.send(:__types__)
File.binwrite(cache_file, Marshal.dump(new(MIME::Types::Data::VERSION, Marshal.dump(types))))
end
end
mime-types-3.6.0/lib/mime/types/_columnar.rb 0000644 0000041 0000041 00000006262 14726205276 021027 0 ustar www-data www-data # frozen_string_literal: true
require "mime/type/columnar"
# MIME::Types::Columnar is used to extend a MIME::Types container to load data
# by columns instead of from JSON or YAML. Column loads of MIME types loaded
# through the columnar store are synchronized with a Mutex.
#
# MIME::Types::Columnar is not intended to be used directly, but will be added
# to an instance of MIME::Types when it is loaded with
# MIME::Types::Loader#load_columnar.
module MIME::Types::Columnar
LOAD_MUTEX = Mutex.new # :nodoc:
def self.extended(obj) # :nodoc:
super
obj.instance_variable_set(:@__mime_data__, [])
obj.instance_variable_set(:@__files__, Set.new)
end
# Load the first column data file (type and extensions).
def load_base_data(path) # :nodoc:
@__root__ = path
each_file_line("content_type", false) do |line|
line = line.split
content_type = line.shift
extensions = line
# content_type, *extensions = line.split
type = MIME::Type::Columnar.new(self, content_type, extensions)
@__mime_data__ << type
add(type)
end
self
end
private
def each_file_line(name, lookup = true)
LOAD_MUTEX.synchronize do
next if @__files__.include?(name)
i = -1
column = File.join(@__root__, "mime.#{name}.column")
IO.readlines(column, encoding: "UTF-8").each do |line|
line.chomp!
if lookup
(type = @__mime_data__[i += 1]) || next
yield type, line
else
yield line
end
end
@__files__ << name
end
end
def load_encoding
each_file_line("encoding") do |type, line|
pool ||= {}
type.instance_variable_set(:@encoding, (pool[line] ||= line))
end
end
def load_docs
each_file_line("docs") do |type, line|
type.instance_variable_set(:@docs, opt(line))
end
end
def load_preferred_extension
each_file_line("pext") do |type, line|
type.instance_variable_set(:@preferred_extension, opt(line))
end
end
def load_flags
each_file_line("flags") do |type, line|
line = line.split
type.instance_variable_set(:@obsolete, flag(line.shift))
type.instance_variable_set(:@registered, flag(line.shift))
type.instance_variable_set(:@signature, flag(line.shift))
type.instance_variable_set(:@provisional, flag(line.shift))
end
end
def load_xrefs
each_file_line("xrefs") { |type, line|
type.instance_variable_set(:@xrefs, dict(line, array: true))
}
end
def load_friendly
each_file_line("friendly") { |type, line|
type.instance_variable_set(:@friendly, dict(line))
}
end
def load_use_instead
each_file_line("use_instead") do |type, line|
type.instance_variable_set(:@use_instead, opt(line))
end
end
def dict(line, array: false)
if line == "-"
{}
else
line.split("|").each_with_object({}) { |l, h|
k, v = l.split("^")
v = nil if v.empty?
h[k] = array ? Array(v) : v
}
end
end
def arr(line)
if line == "-"
[]
else
line.split("|").flatten.compact.uniq
end
end
def opt(line)
line unless line == "-"
end
def flag(line)
line == "1"
end
end
mime-types-3.6.0/lib/mime/types.rb 0000644 0000041 0000041 00000017477 14726205276 017062 0 ustar www-data www-data # frozen_string_literal: true
##
module MIME
##
class Types
end
end
require "mime/type"
# MIME::Types is a registry of MIME types. It is both a class (created with
# MIME::Types.new) and a default registry (loaded automatically or through
# interactions with MIME::Types.[] and MIME::Types.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.provisional? # => false
# puts plaintext == 'text/plain' # => true
# puts MIME::Type.simplified('x-appl/x-zip') # => 'appl/zip'
#
class MIME::Types
# The release version of Ruby MIME::Types
VERSION = MIME::Type::VERSION
include Enumerable
# Creates a new MIME::Types registry.
def initialize
@type_variants = Container.new
@extension_index = Container.new
end
# Returns the number of known type variants.
def count
@type_variants.values.inject(0) { |a, e| a + e.size }
end
def inspect # :nodoc:
"#<#{self.class}: #{count} variants, #{@extension_index.count} extensions>"
end
# Iterates through the type variants.
def each
if block_given?
@type_variants.each_value { |tv| tv.each { |t| yield t } }
else
enum_for(:each)
end
end
@__types__ = nil
# 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. Current definitions sort before obsolete ones;
# 4. Obsolete definitions with use-instead clauses sort before those
# without;
# 5. Obsolete definitions use-instead clauses are compared.
# 6. Sort on name.
def [](type_id, complete: false, registered: false)
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, complete, registered).sort { |a, b|
a.priority_compare(b)
}
end
# 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]
def type_for(filename)
Array(filename).flat_map { |fn|
@extension_index[fn.chomp.downcase[/\.?([^.]*?)\z/m, 1]]
}.compact.inject(Set.new, :+).sort { |a, b|
a.priority_compare(b)
}
end
alias_method :of, :type_for
# 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.
def add(*types)
quiet = (types.last == :silent) || (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.inject(Set.new, :+).to_a, quiet)
when Array
add(*mime_type, quiet)
else
add_type(mime_type, quiet)
end
end
end
# 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.
def add_type(type, quiet = false)
if !quiet && @type_variants[type.simplified].include?(type)
MIME::Types.logger.debug <<-WARNING.chomp.strip
Type #{type} is already registered as a variant of #{type.simplified}.
WARNING
end
add_type_variant!(type)
index_extensions!(type)
end
private
def add_type_variant!(mime_type)
@type_variants.add(mime_type.simplified, mime_type)
end
def reindex_extensions!(mime_type)
return unless @type_variants[mime_type.simplified].include?(mime_type)
index_extensions!(mime_type)
end
def index_extensions!(mime_type)
mime_type.extensions.each { |ext| @extension_index.add(ext, mime_type) }
end
def prune_matches(matches, complete, registered)
matches.delete_if { |e| !e.complete? } if complete
matches.delete_if { |e| !e.registered? } if registered
matches
end
def match(pattern)
@type_variants.select { |k, _|
k =~ pattern
}.values.inject(Set.new, :+)
end
end
require "mime/types/cache"
require "mime/types/container"
require "mime/types/loader"
require "mime/types/logger"
require "mime/types/_columnar"
require "mime/types/registry"
mime-types-3.6.0/lib/mime/type.rb 0000644 0000041 0000041 00000052400 14726205276 016660 0 ustar www-data www-data # frozen_string_literal: true
##
module MIME
end
require "mime/types/deprecations"
# The definition of one MIME content-type.
#
# == Usage
# require "mime/types"
#
# plaintext = MIME::Types["text/plain"] # => [ text/plain ]
# text = plaintext.first
# puts text.media_type # => "text"
# puts text.sub_type # => "plain"
#
# puts text.extensions.join(" ") # => "txt asc c cc h hh cpp hpp dat hlp"
# puts text.preferred_extension # => "txt"
# puts text.friendly # => "Text Document"
# puts text.i18n_key # => "text.plain"
#
# puts text.encoding # => quoted-printable
# puts text.default_encoding # => quoted-printable
# puts text.binary? # => false
# puts text.ascii? # => true
# puts text.obsolete? # => false
# puts text.registered? # => true
# puts text.provisional? # => false
# puts text.complete? # => true
#
# puts text # => "text/plain"
#
# puts text == "text/plain" # => true
# puts "text/plain" == text # => true
# puts text == "text/x-plain" # => false
# puts "text/x-plain" == text # => false
#
# puts MIME::Type.simplified("x-appl/x-zip") # => "x-appl/x-zip"
# puts MIME::Type.i18n_key("x-appl/x-zip") # => "x-appl.x-zip"
#
# puts text.like?("text/x-plain") # => true
# puts text.like?(MIME::Type.new("content-type" => "x-text/x-plain")) # => true
#
# puts text.xrefs.inspect # => { "rfc" => [ "rfc2046", "rfc3676", "rfc5147" ] }
# puts text.xref_urls # => [ "http://www.iana.org/go/rfc2046",
# # "http://www.iana.org/go/rfc3676",
# # "http://www.iana.org/go/rfc5147" ]
#
# xtext = MIME::Type.new("x-text/x-plain")
# puts xtext.media_type # => "text"
# puts xtext.raw_media_type # => "x-text"
# puts xtext.sub_type # => "plain"
# puts xtext.raw_sub_type # => "x-plain"
# puts xtext.complete? # => false
#
# puts MIME::Types.any? { |type| type.content_type == "text/plain" } # => true
# puts MIME::Types.all?(&:registered?) # => false
#
# # Various string representations of MIME types
# qcelp = MIME::Types["audio/QCELP"].first # => audio/QCELP
# puts qcelp.content_type # => "audio/QCELP"
# puts qcelp.simplified # => "audio/qcelp"
#
# xwingz = MIME::Types["application/x-Wingz"].first # => application/x-Wingz
# puts xwingz.content_type # => "application/x-Wingz"
# puts xwingz.simplified # => "application/x-wingz"
class MIME::Type
# Reflects a MIME content-type specification that is not correctly
# formatted (it is not +type+/+subtype+).
class InvalidContentType < ArgumentError
# :stopdoc:
def initialize(type_string)
@type_string = type_string
end
def to_s
"Invalid Content-Type #{@type_string.inspect}"
end
# :startdoc:
end
# Reflects an unsupported MIME encoding.
class InvalidEncoding < ArgumentError
# :stopdoc:
def initialize(encoding)
@encoding = encoding
end
def to_s
"Invalid Encoding #{@encoding.inspect}"
end
# :startdoc:
end
# The released version of the mime-types library.
VERSION = "3.6.0"
include Comparable
# :stopdoc:
# Full conformance with RFC 6838 §4.2 (the recommendation for < 64 characters is not
# enforced or reported because MIME::Types mostly deals with registered data). RFC 4288
# §4.2 does not restrict the first character to alphanumeric, but the total length of
# each part is limited to 127 characters. RFCC 2045 §5.1 does not restrict the character
# composition except for whitespace, but MIME::Type was always more strict than this.
restricted_name_first = "[0-9a-zA-Z]"
restricted_name_chars = "[-!#{$&}^_.+0-9a-zA-Z]{0,126}"
restricted_name = "#{restricted_name_first}#{restricted_name_chars}"
MEDIA_TYPE_RE = %r{(#{restricted_name})/(#{restricted_name})}.freeze
I18N_RE = /[^[:alnum:]]/.freeze
BINARY_ENCODINGS = %w[base64 8bit].freeze
ASCII_ENCODINGS = %w[7bit quoted-printable].freeze
# :startdoc:
private_constant :MEDIA_TYPE_RE, :I18N_RE, :BINARY_ENCODINGS,
:ASCII_ENCODINGS
# Builds a MIME::Type object from the +content_type+, a MIME Content Type
# value (e.g., "text/plain" or "application/x-eruby"). The constructed object
# is yielded to an optional block for additional configuration, such as
# associating extensions and encoding information.
#
# * When provided a Hash or a MIME::Type, the MIME::Type will be
# constructed with #init_with.
#
# There are two deprecated initialization forms:
#
# * When provided an Array, the MIME::Type will be constructed using
# the first element as the content type and the remaining flattened
# elements as extensions.
# * Otherwise, the content_type will be used as a string.
#
# Yields the newly constructed +self+ object.
def initialize(content_type) # :yields: self
@friendly = {}
@obsolete = @registered = @provisional = false
@preferred_extension = @docs = @use_instead = nil
self.extensions = []
case content_type
when Hash
init_with(content_type)
when Array
MIME::Types.deprecated(
class: MIME::Type,
method: :new,
pre: "when called with an Array",
once: true
)
self.content_type = content_type.shift
self.extensions = content_type.flatten
when MIME::Type
init_with(content_type.to_h)
else
MIME::Types.deprecated(
class: MIME::Type,
method: :new,
pre: "when called with a String",
once: true
)
self.content_type = content_type
end
self.encoding ||= :default
self.xrefs ||= {}
yield self if block_given?
end
# Indicates that a MIME type is like another type. This differs from
# == because x- prefixes are removed for this comparison.
def like?(other)
other =
if other.respond_to?(:simplified)
MIME::Type.simplified(other.simplified, remove_x_prefix: true)
else
MIME::Type.simplified(other.to_s, remove_x_prefix: true)
end
MIME::Type.simplified(simplified, remove_x_prefix: true) == other
end
# Compares the +other+ MIME::Type against the exact content type or the
# simplified type (the simplified type will be used if comparing against
# something that can be treated as a String with #to_s). In comparisons, this
# is done against the lowercase version of the MIME::Type.
def <=>(other)
if other.nil?
-1
elsif other.respond_to?(:simplified)
simplified <=> other.simplified
else
filtered = "silent" if other == :silent
filtered ||= "true" if other == true
filtered ||= other.to_s
simplified <=> MIME::Type.simplified(filtered)
end
end
# Compares the +other+ MIME::Type based on how reliable it is before doing a
# normal <=> comparison. Used by MIME::Types#[] to sort types. The
# comparisons involved are:
#
# 1. self.simplified <=> other.simplified (ensures that we
# do not try to compare different types)
# 2. IANA-registered definitions < other definitions.
# 3. Complete definitions < incomplete definitions.
# 4. Current definitions < obsolete definitions.
# 5. Obselete with use-instead names < obsolete without.
# 6. Obsolete use-instead definitions are compared.
#
# While this method is public, its use is strongly discouraged by consumers
# of mime-types. In mime-types 3, this method is likely to see substantial
# revision and simplification to ensure current registered content types sort
# before unregistered or obsolete content types.
def priority_compare(other)
pc = simplified <=> other.simplified
if pc.zero? || !(extensions & other.extensions).empty?
pc =
if (reg = registered?) != other.registered?
reg ? -1 : 1 # registered < unregistered
elsif (comp = complete?) != other.complete?
comp ? -1 : 1 # complete < incomplete
elsif (obs = obsolete?) != other.obsolete?
obs ? 1 : -1 # current < obsolete
elsif obs && ((ui = use_instead) != (oui = other.use_instead))
if ui.nil?
1
elsif oui.nil?
-1
else
ui <=> oui
end
else
0
end
end
pc
end
# Returns +true+ if the +other+ object is a MIME::Type and the content types
# match.
def eql?(other)
other.is_a?(MIME::Type) && (self == other)
end
# Returns a hash based on the #simplified value.
#
# This maintains the invariant that two #eql? instances must have the same
# #hash (although having the same #hash does *not* imply that the objects are
# #eql?).
#
# To see why, suppose a MIME::Type instance +a+ is compared to another object
# +b+, and that a.eql?(b)
is true. By the definition of #eql?,
# we know the following:
#
# 1. +b+ is a MIME::Type instance itself.
# 2. a == b
is true.
#
# Due to the first point, we know that +b+ should respond to the #simplified
# method. Thus, per the definition of #<=>, we know that +a.simplified+ must
# be equal to +b.simplified+, as compared by the <=> method corresponding to
# +a.simplified+.
#
# Presumably, if a.simplified <=> b.simplified
is +0+, then
# +a.simplified+ has the same hash as +b.simplified+. So we assume it is
# suitable for #hash to delegate to #simplified in service of the #eql?
# invariant.
def hash
simplified.hash
end
# Returns the whole MIME content-type string.
#
# The content type is a presentation value from the MIME type registry and
# should not be used for comparison. The case of the content type is
# preserved, and extension markers (x-) are kept.
#
# text/plain => text/plain
# x-chemical/x-pdb => x-chemical/x-pdb
# audio/QCELP => audio/QCELP
attr_reader :content_type
# A simplified form of the MIME content-type string, suitable for
# case-insensitive comparison, with the content_type converted to lowercase.
#
# text/plain => text/plain
# x-chemical/x-pdb => x-chemical/x-pdb
# audio/QCELP => audio/qcelp
attr_reader :simplified
# Returns the media type of the simplified MIME::Type.
#
# text/plain => text
# x-chemical/x-pdb => x-chemical
# audio/QCELP => audio
attr_reader :media_type
# Returns the media type of the unmodified MIME::Type.
#
# text/plain => text
# x-chemical/x-pdb => x-chemical
# audio/QCELP => audio
attr_reader :raw_media_type
# Returns the sub-type of the simplified MIME::Type.
#
# text/plain => plain
# x-chemical/x-pdb => pdb
# audio/QCELP => QCELP
attr_reader :sub_type
# Returns the media type of the unmodified MIME::Type.
#
# text/plain => plain
# x-chemical/x-pdb => x-pdb
# audio/QCELP => qcelp
attr_reader :raw_sub_type
##
# The list of extensions which are known to be used for this MIME::Type.
# Non-array values will be coerced into an array with #to_a. Array values
# will be flattened, +nil+ values removed, and made unique.
#
# :attr_accessor: extensions
def extensions
@extensions.to_a
end
##
def extensions=(value) # :nodoc:
@extensions = Set[*Array(value).flatten.compact].freeze
MIME::Types.send(:reindex_extensions, self)
end
# Merge the +extensions+ provided into this MIME::Type. The extensions added
# will be merged uniquely.
def add_extensions(*extensions)
self.extensions += extensions
end
##
# The preferred extension for this MIME type. If one is not set and there are
# exceptions defined, the first extension will be used.
#
# When setting #preferred_extensions, if #extensions does not contain this
# extension, this will be added to #extensions.
#
# :attr_accessor: preferred_extension
##
def preferred_extension
@preferred_extension || extensions.first
end
##
def preferred_extension=(value) # :nodoc:
if value
add_extensions(value)
end
@preferred_extension = value
end
##
# The encoding (+7bit+, +8bit+, quoted-printable, or +base64+)
# required to transport the data of this content type safely across a
# network, which roughly corresponds to Content-Transfer-Encoding. A value of
# +nil+ or :default will reset the #encoding to the
# #default_encoding for the MIME::Type. Raises ArgumentError if the encoding
# provided is invalid.
#
# If the encoding is not provided on construction, this will be either
# "quoted-printable" (for text/* media types) and "base64" for eveything
# else.
#
# :attr_accessor: encoding
##
attr_reader :encoding
##
def encoding=(enc) # :nodoc:
if enc.nil? || (enc == :default)
@encoding = default_encoding
elsif BINARY_ENCODINGS.include?(enc) || ASCII_ENCODINGS.include?(enc)
@encoding = enc
else
fail InvalidEncoding, enc
end
end
# Returns the default encoding for the MIME::Type based on the media type.
def default_encoding
(@media_type == "text") ? "quoted-printable" : "base64"
end
##
# Returns the media type or types that should be used instead of this media
# type, if it is obsolete. If there is no replacement media type, or it is
# not obsolete, +nil+ will be returned.
#
# :attr_accessor: use_instead
##
def use_instead
obsolete? ? @use_instead : nil
end
##
attr_writer :use_instead
# Returns +true+ if the media type is obsolete.
attr_accessor :obsolete
alias_method :obsolete?, :obsolete
# The documentation for this MIME::Type.
attr_accessor :docs
# A friendly short description for this MIME::Type.
#
# call-seq:
# text_plain.friendly # => "Text File"
# text_plain.friendly("en") # => "Text File"
def friendly(lang = "en")
@friendly ||= {}
case lang
when String, Symbol
@friendly[lang.to_s]
when Array
@friendly.update(Hash[*lang])
when Hash
@friendly.update(lang)
else
fail ArgumentError,
"Expected a language or translation set, not #{lang.inspect}"
end
end
# A key suitable for use as a lookup key for translations, such as with
# the I18n library.
#
# call-seq:
# text_plain.i18n_key # => "text.plain"
# 3gpp_xml.i18n_key # => "application.vnd-3gpp-bsf-xml"
# # from application/vnd.3gpp.bsf+xml
# x_msword.i18n_key # => "application.word"
# # from application/x-msword
attr_reader :i18n_key
##
# The cross-references list for this MIME::Type.
#
# :attr_accessor: xrefs
##
attr_reader :xrefs
##
def xrefs=(xrefs) # :nodoc:
@xrefs = MIME::Types::Container.new(xrefs)
end
# The decoded cross-reference URL list for this MIME::Type.
def xref_urls
xrefs.flat_map { |type, values|
name = :"xref_url_for_#{type.tr("-", "_")}"
respond_to?(name, true) && xref_map(values, name) || values.to_a
}
end
# Indicates whether the MIME type has been registered with IANA.
attr_accessor :registered
alias_method :registered?, :registered
# Indicates whether the MIME type's registration with IANA is provisional.
attr_accessor :provisional
# Indicates whether the MIME type's registration with IANA is provisional.
def provisional?
registered? && @provisional
end
# MIME types can be specified to be sent across a network in particular
# formats. This method returns +true+ when the MIME::Type encoding is set
# to base64.
def binary?
BINARY_ENCODINGS.include?(encoding)
end
# MIME types can be specified to be sent across a network in particular
# formats. This method returns +false+ when the MIME::Type encoding is
# set to base64.
def ascii?
ASCII_ENCODINGS.include?(encoding)
end
# Indicateswhether the MIME type is declared as a signature type.
attr_accessor :signature
alias_method :signature?, :signature
# Returns +true+ if the MIME::Type specifies an extension list,
# indicating that it is a complete MIME::Type.
def complete?
!@extensions.empty?
end
# Returns the MIME::Type as a string.
def to_s
content_type
end
# Returns the MIME::Type as a string for implicit conversions. This allows
# MIME::Type objects to appear on either side of a comparison.
#
# "text/plain" == MIME::Type.new("content-type" => "text/plain")
def to_str
content_type
end
# Converts the MIME::Type to a JSON string.
def to_json(*args)
require "json"
to_h.to_json(*args)
end
# Converts the MIME::Type to a hash. The output of this method can also be
# used to initialize a MIME::Type.
def to_h
encode_with({})
end
# Populates the +coder+ with attributes about this record for
# serialization. The structure of +coder+ should match the structure used
# with #init_with.
#
# This method should be considered a private implementation detail.
def encode_with(coder)
coder["content-type"] = @content_type
coder["docs"] = @docs unless @docs.nil? || @docs.empty?
coder["friendly"] = @friendly unless @friendly.nil? || @friendly.empty?
coder["encoding"] = @encoding
coder["extensions"] = @extensions.to_a unless @extensions.empty?
coder["preferred-extension"] = @preferred_extension if @preferred_extension
if obsolete?
coder["obsolete"] = obsolete?
coder["use-instead"] = use_instead if use_instead
end
unless xrefs.empty?
{}.tap do |hash|
xrefs.each do |k, v|
hash[k] = v.to_a.sort
end
coder["xrefs"] = hash
end
end
coder["registered"] = registered?
coder["provisional"] = provisional? if provisional?
coder["signature"] = signature? if signature?
coder
end
# Initialize an empty object from +coder+, which must contain the
# attributes necessary for initializing an empty object.
#
# This method should be considered a private implementation detail.
def init_with(coder)
self.content_type = coder["content-type"]
self.docs = coder["docs"] || ""
self.encoding = coder["encoding"]
self.extensions = coder["extensions"] || []
self.preferred_extension = coder["preferred-extension"]
self.obsolete = coder["obsolete"] || false
self.registered = coder["registered"] || false
self.provisional = coder["provisional"] || false
self.signature = coder["signature"]
self.xrefs = coder["xrefs"] || {}
self.use_instead = coder["use-instead"]
friendly(coder["friendly"] || {})
end
def inspect # :nodoc:
# We are intentionally lying here because MIME::Type::Columnar is an
# implementation detail.
"#"
end
class << self
# MIME media types are case-insensitive, but are typically presented in a
# case-preserving format in the type registry. This method converts
# +content_type+ to lowercase.
#
# In previous versions of mime-types, this would also remove any extension
# prefix (x-). This is no longer default behaviour, but may be
# provided by providing a truth value to +remove_x_prefix+.
def simplified(content_type, remove_x_prefix: false)
simplify_matchdata(match(content_type), remove_x_prefix)
end
# Converts a provided +content_type+ into a translation key suitable for
# use with the I18n library.
def i18n_key(content_type)
simplify_matchdata(match(content_type), joiner: ".") { |e|
e.gsub!(I18N_RE, "-")
}
end
# Return a +MatchData+ object of the +content_type+ against pattern of
# media types.
def match(content_type)
case content_type
when MatchData
content_type
else
MEDIA_TYPE_RE.match(content_type)
end
end
private
def simplify_matchdata(matchdata, remove_x = false, joiner: "/")
return nil unless matchdata
matchdata.captures.map { |e|
e.downcase!
e.sub!(/^x-/, "") if remove_x
yield e if block_given?
e
}.join(joiner)
end
end
private
def content_type=(type_string)
match = MEDIA_TYPE_RE.match(type_string)
fail InvalidContentType, type_string if match.nil?
@content_type = intern_string(type_string)
@raw_media_type, @raw_sub_type = match.captures
@simplified = intern_string(MIME::Type.simplified(match))
@i18n_key = intern_string(MIME::Type.i18n_key(match))
@media_type, @sub_type = MEDIA_TYPE_RE.match(@simplified).captures
@raw_media_type = intern_string(@raw_media_type)
@raw_sub_type = intern_string(@raw_sub_type)
@media_type = intern_string(@media_type)
@sub_type = intern_string(@sub_type)
end
if String.method_defined?(:-@)
def intern_string(string)
-string
end
else
# MRI 2.2 and older do not have a method for string interning,
# so we simply freeze them for keeping a similar interface
def intern_string(string)
string.freeze
end
end
def xref_map(values, helper)
values.map { |value| send(helper, value) }
end
def xref_url_for_rfc(value)
"http://www.iana.org/go/%s" % value
end
def xref_url_for_draft(value)
"http://www.iana.org/go/%s" % value.sub(/\ARFC/, "draft")
end
def xref_url_for_rfc_errata(value)
"http://www.rfc-editor.org/errata_search.php?eid=%s" % value
end
def xref_url_for_person(value)
"http://www.iana.org/assignments/media-types/media-types.xhtml#%s" % value
end
def xref_url_for_template(value)
"http://www.iana.org/assignments/media-types/%s" % value
end
end
mime-types-3.6.0/test/ 0000755 0000041 0000041 00000000000 14726205276 014633 5 ustar www-data www-data mime-types-3.6.0/test/minitest_helper.rb 0000644 0000041 0000041 00000000263 14726205276 020354 0 ustar www-data www-data # frozen_string_literal: true
require "mime/type"
require "fileutils"
gem "minitest"
require "minitest/focus"
require "minitest/hooks"
ENV["RUBY_MIME_TYPES_LAZY_LOAD"] = "yes"
mime-types-3.6.0/test/test_mime_types_loader.rb 0000644 0000041 0000041 00000001644 14726205276 021725 0 ustar www-data www-data # frozen_string_literal: true
require "mime/types"
require "minitest_helper"
describe MIME::Types::Loader do
def setup
@path = File.expand_path("../fixture", __FILE__)
@loader = MIME::Types::Loader.new(@path)
@bad_path = File.expand_path("../bad-fixtures", __FILE__)
end
def assert_correctly_loaded(types)
assert_includes(types, "application/1d-interleaved-parityfec")
assert_equal(%w[webm], types["audio/webm"].first.extensions)
refute(types["audio/webm"].first.registered?)
assert_equal("Fixes a bug with IE6 and progressive JPEGs",
types["image/pjpeg"].first.docs)
assert(types["audio/vnd.qcelp"].first.obsolete?)
assert_equal("audio/QCELP", types["audio/vnd.qcelp"].first.use_instead)
end
it "loads YAML files correctly" do
assert_correctly_loaded @loader.load_yaml
end
it "loads JSON files correctly" do
assert_correctly_loaded @loader.load_json
end
end
mime-types-3.6.0/test/test_mime_types.rb 0000644 0000041 0000041 00000012724 14726205276 020400 0 ustar www-data www-data # frozen_string_literal: true
require "mime/types"
require "minitest_helper"
describe MIME::Types do
def mime_types
@mime_types ||= MIME::Types.new.tap { |mt|
mt.add(
MIME::Type.new("content-type" => "text/plain", "extensions" => %w[txt]),
MIME::Type.new("content-type" => "image/jpeg", "extensions" => %w[jpg jpeg]),
MIME::Type.new("content-type" => "application/x-wordperfect6.1"),
MIME::Type.new("content-type" => "application/x-www-form-urlencoded", "registered" => true),
MIME::Type.new("content-type" => "application/x-gzip", "extensions" => %w[gz]),
MIME::Type.new("content-type" => "application/gzip", "extensions" => "gz", "registered" => true)
)
}
end
describe "is enumerable" do
it "correctly uses an Enumerable method like #any?" do
assert(mime_types.any? { |type| type.content_type == "text/plain" })
end
it "implements each with no parameters to return an Enumerator" do
assert_kind_of Enumerator, mime_types.each
assert_kind_of Enumerator, mime_types.map
end
it "will create a lazy enumerator" do
assert_kind_of Enumerator::Lazy, mime_types.lazy
assert_kind_of Enumerator::Lazy, mime_types.map.lazy
end
it "is countable with an enumerator" do
assert_equal 6, mime_types.each.count
assert_equal 6, mime_types.lazy.count
end
end
describe "#[]" do
it "can be searched with a MIME::Type" do
text_plain = MIME::Type.new("content-type" => "text/plain")
assert_includes mime_types[text_plain], "text/plain"
assert_equal 1, mime_types[text_plain].size
end
it "can be searched with a regular expression" do
assert_includes mime_types[/plain$/], "text/plain"
assert_equal 1, mime_types[/plain$/].size
end
it "sorts by priority with multiple matches" do
assert_equal %w[application/gzip application/x-gzip], mime_types[/gzip$/]
assert_equal 2, mime_types[/gzip$/].size
end
it "can be searched with a string" do
assert_includes mime_types["text/plain"], "text/plain"
assert_equal 1, mime_types["text/plain"].size
end
it "can be searched with the complete flag" do
assert_empty mime_types[
"application/x-www-form-urlencoded",
complete: true
]
assert_includes mime_types["text/plain", complete: true], "text/plain"
assert_equal 1, mime_types["text/plain", complete: true].size
end
it "can be searched with the registered flag" do
assert_empty mime_types["application/x-wordperfect6.1", registered: true]
refute_empty mime_types[
"application/x-www-form-urlencoded",
registered: true
]
refute_empty mime_types[/gzip/, registered: true]
refute_equal mime_types[/gzip/], mime_types[/gzip/, registered: true]
end
it "properly returns an empty result on a regular expression miss" do
assert_empty mime_types[/^foo/]
assert_empty mime_types[/^foo/, registered: true]
assert_empty mime_types[/^foo/, complete: true]
end
end
describe "#add" do
let(:eruby) { MIME::Type.new("content-type" => "application/x-eruby") }
let(:jinja) { MIME::Type.new("content-type" => "application/jinja2") }
it "successfully adds a new type" do
mime_types.add(eruby)
assert_equal mime_types["application/x-eruby"], [eruby]
end
it "complains about adding a duplicate type" do
mime_types.add(eruby)
assert_output "", /is already registered as a variant/ do
mime_types.add(eruby)
end
assert_equal mime_types["application/x-eruby"], [eruby]
end
it "does not complain about adding a duplicate type when quiet" do
mime_types.add(eruby)
assert_output "", "" do
mime_types.add(eruby, :silent)
end
assert_equal mime_types["application/x-eruby"], [eruby]
end
it "successfully adds from an array" do
mime_types.add([eruby, jinja])
assert_equal mime_types["application/x-eruby"], [eruby]
assert_equal mime_types["application/jinja2"], [jinja]
end
it "successfully adds from another MIME::Types" do
mt = MIME::Types.new
mt.add(mime_types)
assert_equal mime_types.count, mt.count
mime_types.each do |type|
assert_equal mt[type.content_type], [type]
end
end
end
describe "#type_for" do
it "finds all types for a given extension" do
assert_equal %w[application/gzip application/x-gzip],
mime_types.type_for("gz")
end
it "separates the extension from filenames" do
assert_equal %w[image/jpeg], mime_types.of(["foo.jpeg", "bar.jpeg"])
end
it "finds multiple extensions" do
assert_equal %w[image/jpeg text/plain],
mime_types.type_for(%w[foo.txt foo.jpeg])
end
it "does not find unknown extensions" do
keys = mime_types.instance_variable_get(:@extension_index).keys
assert_empty mime_types.type_for("zzz")
assert_equal keys, mime_types.instance_variable_get(:@extension_index).keys
end
it "modifying type extensions causes reindexing" do
plain_text = mime_types["text/plain"].first
plain_text.add_extensions("xtxt")
assert_includes mime_types.type_for("xtxt"), "text/plain"
end
it "handles newline characters correctly" do
assert_includes mime_types.type_for("test.pdf\n.txt"), "text/plain"
end
end
describe "#count" do
it "can count the number of types inside" do
assert_equal 6, mime_types.count
end
end
end
mime-types-3.6.0/test/bad-fixtures/ 0000755 0000041 0000041 00000000000 14726205276 017230 5 ustar www-data www-data mime-types-3.6.0/test/bad-fixtures/malformed 0000644 0000041 0000041 00000000744 14726205276 021126 0 ustar www-data www-data !application.smil @smi,smil :8bit 'IANA,RFC4536 =use-instead:application/smil+xml
!audio/vnd.qcelp @qcp 'IANA,RFC3625 =use-instead:audio/QCELP
*!image/bmp @bmp =use-instead:image/x-bmp
*application/acad 'LTSW
*audio/webm @webm '{WebM=http://www.webmproject.org/code/specs/container/}
*image/pjpeg :base64 =Fixes a bug with IE6 and progressive JPEGs
application/1d-interleaved-parityfec 'IANA,RFC6015
audio/1d-interleaved-parityfec 'IANA,RFC6015
mac:application/x-apple-diskimage @dmg
mime-types-3.6.0/test/test_mime_types_lazy.rb 0000644 0000041 0000041 00000002530 14726205276 021431 0 ustar www-data www-data # frozen_string_literal: true
require "mime/types"
require "minitest_helper"
describe MIME::Types, "lazy loading" do
def setup
ENV["RUBY_MIME_TYPES_LAZY_LOAD"] = "true"
end
def teardown
reset_mime_types
ENV.delete("RUBY_MIME_TYPES_LAZY_LOAD")
end
def reset_mime_types
MIME::Types.instance_variable_set(:@__types__, nil)
MIME::Types.send(:load_default_mime_types)
end
describe ".lazy_load?" do
it "is true when RUBY_MIME_TYPES_LAZY_LOAD is set" do
assert_output "", /RUBY_MIME_TYPES_LAZY_LOAD/ do
assert_equal true, MIME::Types.send(:lazy_load?)
end
end
it "is nil when RUBY_MIME_TYPES_LAZY_LOAD is unset" do
ENV["RUBY_MIME_TYPES_LAZY_LOAD"] = nil
assert_output "", "" do
assert_nil MIME::Types.send(:lazy_load?)
end
end
it "is false when RUBY_MIME_TYPES_LAZY_LOAD is false" do
ENV["RUBY_MIME_TYPES_LAZY_LOAD"] = "false"
assert_output "", /RUBY_MIME_TYPES_LAZY_LOAD/ do
assert_equal false, MIME::Types.send(:lazy_load?)
end
end
end
it "loads lazily when RUBY_MIME_TYPES_LAZY_LOAD is set" do
MIME::Types.instance_variable_set(:@__types__, nil)
assert_nil MIME::Types.instance_variable_get(:@__types__)
refute_nil MIME::Types["text/html"].first
refute_nil MIME::Types.instance_variable_get(:@__types__)
end
end
mime-types-3.6.0/test/test_mime_types_cache.rb 0000644 0000041 0000041 00000006377 14726205276 021532 0 ustar www-data www-data # frozen_string_literal: true
require "mime/types"
require "minitest_helper"
MUTEX = Mutex.new
describe MIME::Types::Cache do
include Minitest::Hooks
def around
require "fileutils"
MUTEX.synchronize do
@cache_file = File.expand_path("../cache.tst", __FILE__)
ENV["RUBY_MIME_TYPES_CACHE"] = @cache_file
clear_cache_file
super
clear_cache_file
ENV.delete("RUBY_MIME_TYPES_CACHE")
end
end
def reset_mime_types
MIME::Types.instance_variable_set(:@__types__, nil)
MIME::Types.send(:load_default_mime_types)
end
def clear_cache_file
FileUtils.rm @cache_file if File.exist? @cache_file
end
describe ".load" do
it "does not use cache when RUBY_MIME_TYPES_CACHE is unset" do
ENV.delete("RUBY_MIME_TYPES_CACHE")
assert_nil MIME::Types::Cache.load
end
it "does not use cache when missing" do
assert_nil MIME::Types::Cache.load
end
it "registers the data to be updated by #add_extensions" do
MIME::Types::Cache.save
reset_mime_types
assert_equal([], MIME::Types.type_for("foo.additional"))
html = MIME::Types["text/html"][0]
html.add_extensions("additional")
assert_equal([html], MIME::Types.type_for("foo.additional"))
end
it "outputs an error when there is an invalid version" do
v = MIME::Types::Data::VERSION
MIME::Types::Data.send(:remove_const, :VERSION)
MIME::Types::Data.const_set(:VERSION, "0.0")
MIME::Types::Cache.save
MIME::Types::Data.send(:remove_const, :VERSION)
MIME::Types::Data.const_set(:VERSION, v)
MIME::Types.instance_variable_set(:@__types__, nil)
assert_output "", /MIME::Types cache: invalid version/ do
MIME::Types["text/html"]
end
end
it "outputs an error when there is a marshal file incompatibility" do
MIME::Types::Cache.save
data = File.binread(@cache_file).reverse
File.binwrite(@cache_file, data)
MIME::Types.instance_variable_set(:@__types__, nil)
assert_output "", /incompatible marshal file format/ do
MIME::Types["text/html"]
end
end
end
describe ".save" do
it "does not create cache when RUBY_MIME_TYPES_CACHE is unset" do
ENV.delete("RUBY_MIME_TYPES_CACHE")
assert_nil MIME::Types::Cache.save
end
it "creates the cache " do
assert_equal(false, File.exist?(@cache_file))
MIME::Types::Cache.save
assert_equal(true, File.exist?(@cache_file))
end
it "uses the cache" do
MIME::Types["text/html"].first.add_extensions("hex")
MIME::Types::Cache.save
MIME::Types.instance_variable_set(:@__types__, nil)
assert_includes MIME::Types["text/html"].first.extensions, "hex"
reset_mime_types
end
end
end
describe MIME::Types::Container do
it "marshals and unmarshals correctly" do
container = MIME::Types::Container.new
container.add("xyz", "abc")
# default proc should return Set[]
assert_equal(Set[], container["abc"])
assert_equal(Set["abc"], container["xyz"])
marshalled = Marshal.dump(container)
loaded_container = Marshal.load(marshalled)
# default proc should still return Set[]
assert_equal(Set[], loaded_container["abc"])
assert_equal(Set["abc"], container["xyz"])
end
end
mime-types-3.6.0/test/test_mime_types_class.rb 0000644 0000041 0000041 00000012033 14726205276 021556 0 ustar www-data www-data # frozen_string_literal: true
require "mime/types"
require "minitest_helper"
describe MIME::Types, "registry" do
def setup
MIME::Types.send(:load_default_mime_types)
end
describe "is enumerable" do
it "correctly uses an Enumerable method like #any?" do
assert(MIME::Types.any? { |type| type.content_type == "text/plain" })
end
it "implements each with no parameters to return an Enumerator" do
assert_kind_of Enumerator, MIME::Types.each
assert_kind_of Enumerator, MIME::Types.map
end
it "will create a lazy enumerator" do
assert_kind_of Enumerator::Lazy, MIME::Types.lazy
assert_kind_of Enumerator::Lazy, MIME::Types.map.lazy
end
it "is countable with an enumerator" do
assert MIME::Types.each.count > 999
assert MIME::Types.lazy.count > 999
end
end
describe ".[]" do
it "can be searched with a MIME::Type" do
text_plain = MIME::Type.new("content-type" => "text/plain")
assert_includes MIME::Types[text_plain], "text/plain"
assert_equal 1, MIME::Types[text_plain].size
end
it "can be searched with a regular expression" do
assert_includes MIME::Types[/plain$/], "text/plain"
assert_equal 1, MIME::Types[/plain$/].size
end
it "sorts by priority with multiple matches" do
types = MIME::Types[/gzip$/].select { |t|
%w[application/gzip application/x-gzip multipart/x-gzip].include?(t)
}
# This is this way because of a new type ending with gzip that only
# appears in some data files.
assert_equal %w[application/gzip application/x-gzip multipart/x-gzip], types
assert_equal 3, types.size
end
it "can be searched with a string" do
assert_includes MIME::Types["text/plain"], "text/plain"
assert_equal 1, MIME::Types["text/plain"].size
end
it "can be searched with the complete flag" do
assert_empty MIME::Types[
"application/x-www-form-urlencoded",
complete: true
]
assert_includes MIME::Types["text/plain", complete: true], "text/plain"
assert_equal 1, MIME::Types["text/plain", complete: true].size
end
it "can be searched with the registered flag" do
assert_empty MIME::Types["application/x-wordperfect6.1", registered: true]
refute_empty MIME::Types[
"application/x-www-form-urlencoded",
registered: true
]
refute_empty MIME::Types[/gzip/, registered: true]
refute_equal MIME::Types[/gzip/], MIME::Types[/gzip/, registered: true]
end
end
describe ".type_for" do
it "finds all types for a given extension" do
assert_equal %w[application/gzip application/x-gzip],
MIME::Types.type_for("gz")
end
it "separates the extension from filenames" do
assert_equal %w[image/jpeg], MIME::Types.of(["foo.jpeg", "bar.jpeg"])
end
it "finds multiple extensions" do
assert_equal %w[image/jpeg text/plain],
MIME::Types.type_for(%w[foo.txt foo.jpeg])
end
it "does not find unknown extensions" do
assert_empty MIME::Types.type_for("zzz")
end
it "modifying type extensions causes reindexing" do
plain_text = MIME::Types["text/plain"].first
plain_text.add_extensions("xtxt")
assert_includes MIME::Types.type_for("xtxt"), "text/plain"
end
it "handles newline characters correctly" do
assert_includes MIME::Types.type_for("test.pdf\n.txt"), "text/plain"
assert_includes MIME::Types.type_for("test.txt\n.pdf"), "application/pdf"
end
end
describe ".count" do
it "can count the number of types inside" do
assert MIME::Types.count > 999
end
end
describe ".add" do
def setup
MIME::Types.instance_variable_set(:@__types__, nil)
MIME::Types.send(:load_default_mime_types)
end
let(:eruby) { MIME::Type.new("content-type" => "application/x-eruby") }
let(:jinja) { MIME::Type.new("content-type" => "application/jinja2") }
it "successfully adds a new type" do
MIME::Types.add(eruby)
assert_equal MIME::Types["application/x-eruby"], [eruby]
end
it "complains about adding a duplicate type" do
MIME::Types.add(eruby)
assert_output "", /is already registered as a variant/ do
MIME::Types.add(eruby)
end
assert_equal MIME::Types["application/x-eruby"], [eruby]
end
it "does not complain about adding a duplicate type when quiet" do
MIME::Types.add(eruby)
assert_silent do
MIME::Types.add(eruby, :silent)
end
assert_equal MIME::Types["application/x-eruby"], [eruby]
end
it "successfully adds from an array" do
MIME::Types.add([eruby, jinja])
assert_equal MIME::Types["application/x-eruby"], [eruby]
assert_equal MIME::Types["application/jinja2"], [jinja]
end
it "successfully adds from another MIME::Types" do
old_count = MIME::Types.count
mt = MIME::Types.new
mt.add(eruby)
MIME::Types.add(mt)
assert_equal old_count + 1, MIME::Types.count
assert_equal MIME::Types[eruby.content_type], [eruby]
end
end
end
mime-types-3.6.0/test/fixture/ 0000755 0000041 0000041 00000000000 14726205276 016321 5 ustar www-data www-data mime-types-3.6.0/test/fixture/old-data 0000644 0000041 0000041 00000000744 14726205276 017736 0 ustar www-data www-data !application/smil @smi,smil :8bit 'IANA,RFC4536 =use-instead:application/smil+xml
!audio/vnd.qcelp @qcp 'IANA,RFC3625 =use-instead:audio/QCELP
*!image/bmp @bmp =use-instead:image/x-bmp
*application/acad 'LTSW
*audio/webm @webm '{WebM=http://www.webmproject.org/code/specs/container/}
*image/pjpeg :base64 =Fixes a bug with IE6 and progressive JPEGs
application/1d-interleaved-parityfec 'IANA,RFC6015
audio/1d-interleaved-parityfec 'IANA,RFC6015
mac:application/x-apple-diskimage @dmg
mime-types-3.6.0/test/fixture/json.json 0000644 0000041 0000041 00000001755 14726205276 020175 0 ustar www-data www-data [{"content-type":"application/smil","encoding":"8bit","extensions":["smi","smil"],"obsolete":true,"use-instead":"application/smil+xml","registered":true},{"content-type":"audio/vnd.qcelp","encoding":"base64","extensions":["qcp"],"obsolete":true,"use-instead":"audio/QCELP","registered":true},{"content-type":"image/bmp","encoding":"base64","extensions":["bmp"],"obsolete":true,"use-instead":"image/x-bmp","registered":false},{"content-type":"application/acad","encoding":"base64","registered":false},{"content-type":"audio/webm","encoding":"base64","extensions":["webm"],"registered":false},{"content-type":"image/pjpeg","docs":"Fixes a bug with IE6 and progressive JPEGs","encoding":"base64","registered":false},{"content-type":"application/1d-interleaved-parityfec","encoding":"base64","registered":true},{"content-type":"audio/1d-interleaved-parityfec","encoding":"base64","registered":true},{"content-type":"application/x-apple-diskimage","encoding":"base64","extensions":["dmg"],"registered":false}]
mime-types-3.6.0/test/fixture/yaml.yaml 0000644 0000041 0000041 00000002304 14726205276 020146 0 ustar www-data www-data ---
- !ruby/object:MIME::Type
content-type: application/smil
encoding: 8bit
extensions:
- smi
- smil
obsolete: true
use-instead: application/smil+xml
registered: true
- !ruby/object:MIME::Type
content-type: audio/vnd.qcelp
encoding: base64
extensions:
- qcp
obsolete: true
use-instead: audio/QCELP
registered: true
- !ruby/object:MIME::Type
content-type: image/bmp
encoding: base64
extensions:
- bmp
obsolete: true
use-instead: image/x-bmp
registered: false
- !ruby/object:MIME::Type
content-type: application/acad
encoding: base64
registered: false
- !ruby/object:MIME::Type
content-type: audio/webm
encoding: base64
extensions:
- webm
registered: false
- !ruby/object:MIME::Type
content-type: image/pjpeg
docs: Fixes a bug with IE6 and progressive JPEGs
encoding: base64
registered: false
- !ruby/object:MIME::Type
content-type: application/1d-interleaved-parityfec
encoding: base64
registered: true
- !ruby/object:MIME::Type
content-type: audio/1d-interleaved-parityfec
encoding: base64
registered: true
- !ruby/object:MIME::Type
content-type: application/x-apple-diskimage
encoding: base64
extensions:
- dmg
registered: false
mime-types-3.6.0/test/test_mime_type.rb 0000644 0000041 0000041 00000046305 14726205276 020217 0 ustar www-data www-data # frozen_string_literal: true
require "mime/types"
require "minitest_helper"
describe MIME::Type do
def mime_type(content_type)
MIME::Type.new(content_type) { |mt| yield mt if block_given? }
end
let(:x_appl_x_zip) {
mime_type("content-type" => "x-appl/x-zip") { |t| t.extensions = %w[zip zp] }
}
let(:text_plain) { mime_type("content-type" => "text/plain") }
let(:text_html) { mime_type("content-type" => "text/html") }
let(:image_jpeg) { mime_type("content-type" => "image/jpeg") }
let(:application_javascript) {
mime_type("content-type" => "application/javascript") do |js|
js.friendly("en" => "JavaScript")
js.xrefs = {
"rfc" => %w[rfc4239 rfc4239],
"template" => %w[application/javascript]
}
js.encoding = "8bit"
js.extensions = %w[js sj]
js.registered = true
end
}
let(:text_x_yaml) {
mime_type("content-type" => "text/x-yaml") do |yaml|
yaml.extensions = %w[yaml yml]
yaml.encoding = "8bit"
yaml.friendly("en" => "YAML Structured Document")
end
}
let(:text_x_yaml_with_docs) {
text_x_yaml.dup.tap do |yaml|
yaml.docs = "Test YAML"
end
}
describe ".simplified" do
it "leaves normal types alone" do
assert_equal "text/plain", MIME::Type.simplified("text/plain")
end
it "does not remove x- prefixes by default" do
assert_equal "application/x-msword",
MIME::Type.simplified("application/x-msword")
assert_equal "x-xyz/abc", MIME::Type.simplified("x-xyz/abc")
end
it "removes x- prefixes when requested" do
assert_equal "application/msword",
MIME::Type.simplified("application/x-msword", remove_x_prefix: true)
assert_equal "xyz/abc",
MIME::Type.simplified("x-xyz/abc", remove_x_prefix: true)
end
it "lowercases mixed-case types" do
assert_equal "text/vcard", MIME::Type.simplified("text/vCard")
end
it "returns nil when the value provided is not a valid content type" do
assert_nil MIME::Type.simplified("text")
end
end
describe ".i18n_key" do
it "converts text/plain to text.plain" do
assert_equal "text.plain", MIME::Type.i18n_key("text/plain")
end
it "does not remove x-prefixes" do
assert_equal "application.x-msword",
MIME::Type.i18n_key("application/x-msword")
end
it "converts text/vCard to text.vcard" do
assert_equal "text.vcard", MIME::Type.i18n_key("text/vCard")
end
it "returns nil when the value provided is not a valid content type" do
assert_nil MIME::Type.i18n_key("text")
end
end
describe ".new" do
it "fails if an invalid content type is provided" do
exception = assert_raises MIME::Type::InvalidContentType do
MIME::Type.new("content-type" => "apps")
end
assert_equal 'Invalid Content-Type "apps"', exception.to_s
end
it "creates a valid content type just from a string" do
assert_output "", /MIME::Type.new when called with a String is deprecated\./ do
type = MIME::Type.new("text/x-yaml")
assert_instance_of MIME::Type, type
assert_equal "text/x-yaml", type.content_type
end
end
it "yields the content type in a block" do
MIME::Type.new("content-type" => "text/x-yaml") do |type|
assert_instance_of MIME::Type, type
assert_equal "text/x-yaml", type.content_type
end
end
it "creates a valid content type from a hash" do
type = MIME::Type.new(
"content-type" => "text/x-yaml",
"obsolete" => true
)
assert_instance_of MIME::Type, type
assert_equal "text/x-yaml", type.content_type
assert type.obsolete?
end
it "creates a valid content type from an array" do
assert_output "", /MIME::Type.new when called with an Array is deprecated\./ do
type = MIME::Type.new(%w[text/x-yaml yaml yml yz])
assert_instance_of MIME::Type, type
assert_equal "text/x-yaml", type.content_type
assert_equal %w[yaml yml yz], type.extensions
end
end
end
describe "#like?" do
it "compares two MIME::Types on #simplified values without x- prefixes" do
assert text_plain.like?(text_plain)
refute text_plain.like?(text_html)
end
it "compares MIME::Type against string without x- prefixes" do
assert text_plain.like?(text_plain.to_s)
refute text_plain.like?(text_html.to_s)
end
end
describe "#<=>" do
it "correctly compares identical types" do
assert_equal text_plain, text_plain
end
it "correctly compares equivalent types" do
right = mime_type("content-type" => "text/Plain")
refute_same text_plain, right
assert_equal text_plain, right
end
it "correctly compares types that sort earlier" do
refute_equal text_html, text_plain
assert_operator text_html, :<, text_plain
end
it "correctly compares types that sort later" do
refute_equal text_plain, text_html
assert_operator text_plain, :>, text_html
end
it "correctly compares types against equivalent strings" do
assert_equal text_plain, "text/plain"
end
it "correctly compares types against strings that sort earlier" do
refute_equal text_html, "text/plain"
assert_operator text_html, :<, "text/plain"
end
it "correctly compares types against strings that sort later" do
refute_equal text_plain, "text/html"
assert_operator text_plain, :>, "text/html"
end
it "correctly compares against nil" do
refute_equal text_html, nil
assert_operator text_plain, :<, nil
end
end
describe "#ascii?" do
it "defaults to true for text/* types" do
assert text_plain.ascii?
end
it "defaults to false for non-text/* types" do
refute image_jpeg.ascii?
end
end
describe "#binary?" do
it "defaults to false for text/* types" do
refute text_plain.binary?
end
it "defaults to true for non-text/* types" do
assert image_jpeg.binary?
end
end
describe "#complete?" do
it "is true when there are extensions" do
assert text_x_yaml.complete?
end
it "is false when there are no extensions" do
refute mime_type("content-type" => "text/plain").complete?
end
end
describe "#content_type" do
it "preserves the original case" do
assert_equal "text/plain", text_plain.content_type
assert_equal "text/vCard", mime_type("content-type" => "text/vCard").content_type
end
it "does not remove x- prefixes" do
assert_equal "x-appl/x-zip", x_appl_x_zip.content_type
end
end
describe "#default_encoding" do
it "is quoted-printable for text/* types" do
assert_equal "quoted-printable", text_plain.default_encoding
end
it "is base64 for non-text/* types" do
assert_equal "base64", image_jpeg.default_encoding
end
end
describe "#encoding, #encoding=" do
it "returns #default_encoding if not set explicitly" do
assert_equal "quoted-printable", text_plain.encoding
assert_equal "base64", image_jpeg.encoding
end
it "returns the set value when set" do
text_plain.encoding = "8bit"
assert_equal "8bit", text_plain.encoding
end
it "resets to the default encoding when set to nil or :default" do
text_plain.encoding = "8bit"
text_plain.encoding = nil
assert_equal text_plain.default_encoding, text_plain.encoding
text_plain.encoding = :default
assert_equal text_plain.default_encoding, text_plain.encoding
end
it "raises a MIME::Type::InvalidEncoding for an invalid encoding" do
exception = assert_raises MIME::Type::InvalidEncoding do
text_plain.encoding = "binary"
end
assert_equal 'Invalid Encoding "binary"', exception.to_s
end
end
describe "#eql?" do
it "is not true for a non-MIME::Type" do
refute text_plain.eql?("text/plain")
end
it "is not true for a different MIME::Type" do
refute text_plain.eql?(image_jpeg)
end
it "is true for an equivalent MIME::Type" do
assert text_plain.eql?(mime_type("content-type" => "text/Plain"))
end
it "is true for an equivalent subclass of MIME::Type" do
subclass = Class.new(MIME::Type)
assert text_plain.eql?(subclass.new("content-type" => "text/plain"))
end
end
describe "#hash" do
it "is the same between #eql? MIME::Type instances" do
assert_equal text_plain.hash, mime_type("content-type" => "text/plain").hash
end
it "is the same between #eql? MIME::Type instances of different classes" do
subclass = Class.new(MIME::Type)
assert_equal text_plain.hash, subclass.new("content-type" => "text/plain").hash
end
it "uses the #simplified value" do
assert_equal text_plain.hash, mime_type("content-type" => "text/Plain").hash
end
end
describe "#extensions, #extensions=" do
it "returns an array of extensions" do
assert_equal %w[yaml yml], text_x_yaml.extensions
assert_equal %w[zip zp], x_appl_x_zip.extensions
end
it "sets a single extension when provided a single value" do
text_x_yaml.extensions = "yaml"
assert_equal %w[yaml], text_x_yaml.extensions
end
it "deduplicates extensions" do
text_x_yaml.extensions = %w[yaml yaml]
assert_equal %w[yaml], text_x_yaml.extensions
end
end
describe "#add_extensions" do
it "does not modify extensions when provided nil" do
text_x_yaml.add_extensions(nil)
assert_equal %w[yaml yml], text_x_yaml.extensions
end
it "remains deduplicated with duplicate values" do
text_x_yaml.add_extensions("yaml")
assert_equal %w[yaml yml], text_x_yaml.extensions
text_x_yaml.add_extensions(%w[yaml yz])
assert_equal %w[yaml yml yz], text_x_yaml.extensions
end
end
describe "#priority_compare" do
def assert_priority_less(left, right)
assert_equal(-1, left.priority_compare(right))
end
def assert_priority_same(left, right)
assert_equal 0, left.priority_compare(right)
end
def assert_priority_more(left, right)
assert_equal 1, left.priority_compare(right)
end
def assert_priority(left, middle, right)
assert_priority_less left, right
assert_priority_same left, middle
assert_priority_more right, left
end
let(:text_1) { mime_type("content-type" => "text/1") }
let(:text_1p) { mime_type("content-type" => "text/1") }
let(:text_2) { mime_type("content-type" => "text/2") }
it "sorts (1) based on the simplified type" do
assert_priority text_1, text_1p, text_2
end
it "sorts (2) based on extensions" do
text_1.extensions = ["foo", "bar"]
text_2.extensions = ["foo"]
assert_priority_same text_1, text_2
text_2.registered = true
assert_priority_more text_1, text_2
end
it "sorts (3) based on the registration state" do
text_1.registered = text_1p.registered = true
text_1b = mime_type(text_1) { |t| t.registered = false }
assert_priority text_1, text_1p, text_1b
end
it "sorts (4) based on the completeness" do
text_1.extensions = text_1p.extensions = "1"
text_1b = mime_type(text_1) { |t| t.extensions = nil }
assert_priority text_1, text_1p, text_1b
end
it "sorts (5) based on obsolete status" do
text_1.obsolete = text_1p.obsolete = false
text_1b = mime_type(text_1) { |t| t.obsolete = true }
assert_priority text_1, text_1p, text_1b
end
it "sorts (5) based on the use-instead value" do
text_1.obsolete = text_1p.obsolete = true
text_1.use_instead = text_1p.use_instead = "abc/xyz"
text_1b = mime_type(text_1) { |t| t.use_instead = nil }
assert_priority text_1, text_1p, text_1b
text_1b.use_instead = "abc/zzz"
assert_priority text_1, text_1p, text_1b
end
end
describe "#raw_media_type" do
it "extracts the media type as case-preserved" do
assert_equal "Text", mime_type("content-type" => "Text/plain").raw_media_type
end
it "does not remove x- prefixes" do
assert_equal("x-appl", x_appl_x_zip.raw_media_type)
end
end
describe "#media_type" do
it "extracts the media type as lowercase" do
assert_equal "text", text_plain.media_type
end
it "does not remove x- prefixes" do
assert_equal("x-appl", x_appl_x_zip.media_type)
end
end
describe "#raw_media_type" do
it "extracts the media type as case-preserved" do
assert_equal "Text", mime_type("content-type" => "Text/plain").raw_media_type
end
it "does not remove x- prefixes" do
assert_equal("x-appl", x_appl_x_zip.raw_media_type)
end
end
describe "#sub_type" do
it "extracts the sub type as lowercase" do
assert_equal "plain", text_plain.sub_type
end
it "does not remove x- prefixes" do
assert_equal("x-zip", x_appl_x_zip.sub_type)
end
end
describe "#raw_sub_type" do
it "extracts the sub type as case-preserved" do
assert_equal "Plain", mime_type("content-type" => "text/Plain").raw_sub_type
end
it "does not remove x- prefixes" do
assert_equal("x-zip", x_appl_x_zip.raw_sub_type)
end
end
describe "#to_h" do
let(:t) { mime_type("content-type" => "a/b") }
def assert_has_keys(wanted_keys, actual, msg = nil)
wanted_keys = Array(wanted_keys).uniq.sort
actual_keys = if actual.is_a?(Hash)
actual.keys
else
actual.to_h.keys
end
missing = wanted_keys - actual_keys
pretty_wanted_keys = (wanted_keys + actual_keys).uniq.sort
msg = message(msg) {
"#{mu_pp(actual)} is missing attribute values\n#{diff(pretty_wanted_keys, actual_keys)}"
}
assert missing.empty?, msg
end
it "has the required keys (content-type, registered, encoding)" do
assert_has_keys %w[content-type registered encoding], t
end
it "has the docs key if there are documents" do
assert_has_keys "docs", mime_type(t) { |v| v.docs = "a" }
end
it "has the extensions key if set" do
assert_has_keys "extensions", mime_type(t) { |v| v.extensions = "a" }
end
it "has the preferred-extension key if set" do
assert_has_keys "preferred-extension", mime_type(t) { |v| v.preferred_extension = "a" }
end
it "has the obsolete key if set" do
assert_has_keys "obsolete", mime_type(t) { |v| v.obsolete = true }
end
it "has the obsolete and use-instead keys if set" do
assert_has_keys %w[obsolete use-instead], mime_type(t) { |v|
v.obsolete = true
v.use_instead = "c/d"
}
end
it "has the signature key if set" do
assert_has_keys "signature", mime_type(t) { |v| v.signature = true }
end
end
describe "#to_json" do
let(:expected_1) {
'{"content-type":"a/b","encoding":"base64","registered":false}'
}
let(:expected_2) {
'{"content-type":"a/b","encoding":"base64","registered":true,"provisional":true}'
}
it "converts to JSON when requested" do
assert_equal expected_1, mime_type("content-type" => "a/b").to_json
end
it "converts to JSON with provisional when requested" do
type = mime_type("content-type" => "a/b") do |t|
t.registered = true
t.provisional = true
end
assert_equal expected_2, type.to_json
end
end
describe "#to_s, #to_str" do
it "represents itself as a string of the canonical content_type" do
assert_equal "text/plain", text_plain.to_s
end
it "acts like a string of the canonical content_type for comparison" do
assert_equal text_plain, "text/plain"
end
it "acts like a string for other purposes" do
assert_equal "stringy", "text/plain".sub(text_plain, "stringy")
end
end
describe "#xrefs, #xrefs=" do
let(:expected) {
MIME::Types::Container.new("rfc" => Set["rfc1234", "rfc5678"])
}
it "returns the expected results" do
application_javascript.xrefs = {
"rfc" => %w[rfc5678 rfc1234 rfc1234]
}
assert_equal expected, application_javascript.xrefs
end
end
describe "#xref_urls" do
let(:expected) {
[
"http://www.iana.org/go/draft1",
"http://www.iana.org/assignments/media-types/a/b",
"http://www.iana.org/assignments/media-types/media-types.xhtml#p-1",
"http://www.iana.org/go/rfc-1",
"http://www.rfc-editor.org/errata_search.php?eid=err-1",
"http://example.org",
"text"
]
}
let(:type) {
mime_type("content-type" => "a/b").tap do |t|
t.xrefs = {
"draft" => ["RFC1"],
"template" => ["a/b"],
"person" => ["p-1"],
"rfc" => ["rfc-1"],
"rfc-errata" => ["err-1"],
"uri" => ["http://example.org"],
"text" => ["text"]
}
end
}
it "translates according to given rules" do
assert_equal expected, type.xref_urls
end
end
describe "#use_instead" do
it "is nil unless the type is obsolete" do
assert_nil text_plain.use_instead
end
it "is nil if not set and the type is obsolete" do
text_plain.obsolete = true
assert_nil text_plain.use_instead
end
it "is a different type if set and the type is obsolete" do
text_plain.obsolete = true
text_plain.use_instead = "text/html"
assert_equal "text/html", text_plain.use_instead
end
end
describe "#preferred_extension, #preferred_extension=" do
it "is nil when not set and there are no extensions" do
assert_nil text_plain.preferred_extension
end
it "is the first extension when not set but there are extensions" do
assert_equal "yaml", text_x_yaml.preferred_extension
end
it "is the extension provided when set" do
text_x_yaml.preferred_extension = "yml"
assert_equal "yml", text_x_yaml.preferred_extension
end
it "is adds the preferred extension if it does not exist" do
text_x_yaml.preferred_extension = "yz"
assert_equal "yz", text_x_yaml.preferred_extension
assert_includes text_x_yaml.extensions, "yz"
end
end
describe "#friendly" do
it "returns English by default" do
assert_equal "YAML Structured Document", text_x_yaml.friendly
end
it "returns English when requested" do
assert_equal "YAML Structured Document", text_x_yaml.friendly("en")
assert_equal "YAML Structured Document", text_x_yaml.friendly(:en)
end
it "returns nothing for an unknown language" do
assert_nil text_x_yaml.friendly("zz")
end
it "merges new values from an array parameter" do
expected = {"en" => "Text files"}
assert_equal expected, text_plain.friendly(["en", "Text files"])
expected.update("fr" => "des fichiers texte")
assert_equal expected,
text_plain.friendly(["fr", "des fichiers texte"])
end
it "merges new values from a hash parameter" do
expected = {"en" => "Text files"}
assert_equal expected, text_plain.friendly(expected)
french = {"fr" => "des fichiers texte"}
expected.update(french)
assert_equal expected, text_plain.friendly(french)
end
it "raises an ArgumentError if an unknown value is provided" do
exception = assert_raises ArgumentError do
text_plain.friendly(1)
end
assert_equal "Expected a language or translation set, not 1",
exception.message
end
end
end
mime-types-3.6.0/Rakefile 0000644 0000041 0000041 00000013376 14726205276 015333 0 ustar www-data www-data require "rubygems"
require "hoe"
require "rake/clean"
Hoe.plugin :cov
Hoe.plugin :doofus
Hoe.plugin :gemspec2
Hoe.plugin :git2
Hoe.plugin :minitest
Hoe.plugin :rubygems
spec = Hoe.spec "mime-types" do
developer("Austin Ziegler", "halostatue@gmail.com")
self.history_file = "History.md"
self.readme_file = "README.rdoc"
license "MIT"
require_ruby_version ">= 2.0"
spec_extras[:metadata] = ->(val) { val["rubygems_mfa_required"] = "true" }
extra_deps << ["mime-types-data", "~> 3.2015"]
extra_deps << ["logger", ">= 0"]
extra_dev_deps << ["hoe", ">= 3.0", "< 5"]
extra_dev_deps << ["hoe-doofus", "~> 1.0"]
extra_dev_deps << ["hoe-gemspec2", "~> 1.1"]
extra_dev_deps << ["hoe-git2", "~> 1.7"]
extra_dev_deps << ["hoe-rubygems", "~> 1.0"]
extra_dev_deps << ["minitest", "~> 5.0"]
extra_dev_deps << ["minitest-autotest", "~> 1.0"]
extra_dev_deps << ["minitest-focus", "~> 1.0"]
extra_dev_deps << ["minitest-hooks", "~> 1.4"]
extra_dev_deps << ["rake", ">= 10.0", "< 14.0"]
extra_dev_deps << ["standard", "~> 1.0"]
end
namespace :benchmark do
task :support do
%w[lib support].each { |path|
$LOAD_PATH.unshift(File.join(Rake.application.original_dir, path))
}
end
desc "Benchmark Load Times"
task :load, [:repeats] => "benchmark:support" do |_, args|
require "benchmarks/load"
Benchmarks::Load.report(
File.join(Rake.application.original_dir, "lib"),
args.repeats
)
end
desc "Allocation counts"
task :allocations, [:top_x, :mime_types_only] => "benchmark:support" do |_, args|
require "benchmarks/load_allocations"
Benchmarks::LoadAllocations.report(
top_x: args.top_x,
mime_types_only: args.mime_types_only
)
end
desc "Columnar allocation counts"
task "allocations:columnar", [:top_x, :mime_types_only] => "benchmark:support" do |_, args|
require "benchmarks/load_allocations"
Benchmarks::LoadAllocations.report(
columnar: true,
top_x: args.top_x,
mime_types_only: args.mime_types_only
)
end
desc "Columnar allocation counts (full load)"
task "allocations:columnar:full", [:top_x, :mime_types_only] => "benchmark:support" do |_, args|
require "benchmarks/load_allocations"
Benchmarks::LoadAllocations.report(
columnar: true,
top_x: args.top_x,
mime_types_only: args.mime_types_only,
full: true
)
end
desc "Memory profiler"
task :memory, [:top_x, :mime_types_only] => "benchmark:support" do |_, args|
require "benchmarks/memory_profiler"
Benchmarks::ProfileMemory.report(
mime_types_only: args.mime_types_only,
top_x: args.top_x
)
end
desc "Columnar memory profiler"
task "memory:columnar", [:top_x, :mime_types_only] => "benchmark:support" do |_, args|
require "benchmarks/memory_profiler"
Benchmarks::ProfileMemory.report(
columnar: true,
mime_types_only: args.mime_types_only,
top_x: args.top_x
)
end
desc "Columnar allocation counts (full load)"
task "memory:columnar:full", [:top_x, :mime_types_only] => "benchmark:support" do |_, args|
require "benchmarks/memory_profiler"
Benchmarks::ProfileMemory.report(
columnar: true,
full: true,
top_x: args.top_x,
mime_types_only: args.mime_types_only
)
end
desc "Object counts"
task objects: "benchmark:support" do
require "benchmarks/object_counts"
Benchmarks::ObjectCounts.report
end
desc "Columnar object counts"
task "objects:columnar" => "benchmark:support" do
require "benchmarks/object_counts"
Benchmarks::ObjectCounts.report(columnar: true)
end
desc "Columnar object counts (full load)"
task "objects:columnar:full" => "benchmark:support" do
require "benchmarks/object_counts"
Benchmarks::ObjectCounts.report(columnar: true, full: true)
end
end
namespace :profile do
directory "tmp/profile"
CLEAN.add "tmp"
def ruby_prof(script)
require "pathname"
output = Pathname("tmp/profile").join(script)
output.mkpath
script = Pathname("support/profile").join("#{script}.rb")
args = [
"-W0",
"-Ilib",
"-S", "ruby-prof",
"-R", "mime/types",
"-s", "self",
"-p", "multi",
"-f", output.to_s,
script.to_s
]
ruby args.join(" ")
end
task full: "tmp/profile" do
ruby_prof "full"
end
task columnar: :support do
ruby_prof "columnar"
end
task "columnar:full" => :support do
ruby_prof "columnar_full"
end
end
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.0")
namespace :test do
desc "Run test coverage"
task :coverage do
spec.test_prelude = [
'require "simplecov"',
'SimpleCov.start("test_frameworks") { command_name "Minitest" }',
'gem "minitest"'
].join("; ")
Rake::Task["test"].execute
end
end
end
namespace :convert do
namespace :docs do
task :setup do
gem "rdoc"
require "rdoc/rdoc"
@doc_converter ||= RDoc::Markup::ToMarkdown.new
end
FileList["*.rdoc"].each do |name|
rdoc = name
mark = "#{File.basename(name, ".rdoc")}.md"
file mark => [rdoc, :setup] do |t|
puts "#{rdoc} => #{mark}"
File.binwrite(t.name, @doc_converter.convert(IO.read(t.prerequisites.first)))
end
CLEAN.add mark
task run: [mark]
end
end
desc "Convert documentation from RDoc to Markdown"
task docs: "convert:docs:run"
end
namespace :deps do
task :top, [:number] => "benchmark:support" do |_, args|
require "deps"
Deps.run(args)
end
end
task :console do
arguments = %w[irb]
arguments.push(*spec.spec.require_paths.map { |dir| "-I#{dir}" })
arguments.push("-r#{spec.spec.name.gsub("-", File::SEPARATOR)}")
unless system(*arguments)
error "Command failed: #{show_command}"
abort
end
end
# vim: syntax=ruby
mime-types-3.6.0/Code-of-Conduct.md 0000644 0000041 0000041 00000012226 14726205276 017052 0 ustar www-data www-data # Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
- Focusing on what is best not just for us as individuals, but for the overall
community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or advances of
any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email address,
without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official email address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at [INSERT CONTACT
METHOD]. All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of
actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the
community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
.
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
. Translations are available at
.
[homepage]: https://www.contributor-covenant.org
[Mozilla CoC]: https://github.com/mozilla/diversity
mime-types-3.6.0/Contributing.md 0000644 0000041 0000041 00000010161 14726205276 016644 0 ustar www-data www-data # Contributing
I value any contribution to mime-types you can provide: a bug report, a feature
request, or code contributions.
There are a few guidelines for contributing to mime-types:
- Code changes _will_ _not_ be accepted without tests. The test suite is
written with [minitest][].
- Match my coding style.
- Use a thoughtfully-named topic branch that contains your change. Rebase your
commits into logical chunks as necessary.
- Use [quality commit messages][].
- Do not change the version number; when your patch is accepted and a release
is made, the version will be updated at that point.
- Submit a GitHub pull request with your changes.
- New or changed behaviours require new or updated documentation.
## Adding or Modifying MIME Types
The mime-types registry is no longer contained in mime-types, but in
[mime-types-data][]. Please see that project for contributions there.
### Test Dependencies
mime-types uses Ryan Davis’s [Hoe][] to manage the release process, and it adds
a number of rake tasks. You will mostly be interested in `rake`, which runs the
tests the same way that `rake test` will do.
To assist with the installation of the development dependencies for
mime-types, I have provided the simplest possible Gemfile pointing to the
(generated) `mime-types.gemspec` file. This will permit you to do `bundle install` to get the development dependencies. If you already have `hoe`
installed, you can accomplish the same thing with `rake newb`.
This task will install any missing dependencies, run the tests/specs, and
generate the RDoc.
You can run tests with code coverage analysis by running `rake test:coverage`.
## Benchmarks
mime-types offers several benchmark tasks to measure different measures of
performance.
There is a repeated load test, measuring how long it takes to start and load
mime-types with its full registry. By default, it runs fifty loops and uses the
built-in benchmark library:
- `rake benchmark:load`
There are two allocation tracing benchmarks (for normal and columnar loads).
These can only be run on Ruby 2.1 or better and requires the
[allocation\_tracer][] gem (not installed by default).
- `rake benchmark:allocations`
- `rake benchmark:allocations:columnar`
There are two loaded object count benchmarks (for normal and columnar loads).
These use `ObjectSpace.count_objects`.
- `rake benchmark:objects`
- `rake benchmark:objects:columnar`
## Workflow
Here's the most direct way to get your work merged into the project:
- Fork the project.
- Clone down your fork (`git clone git://github.com//ruby-mime-types.git`).
- Create a topic branch to contain your change (`git checkout -b my_awesome_feature`).
- Hack away, add tests. Not necessarily in that order.
- Make sure everything still passes by running `rake`.
- If necessary, rebase your commits into logical chunks, without errors.
- Push the branch up (`git push origin my_awesome_feature`).
- Create a pull request against mime-types/ruby-mime-types and describe what
your change does and the why you think it should be merged.
## Contributors
- Austin Ziegler created mime-types.
Thanks to everyone else who has contributed to mime-types over the years:
- Aaron Patterson
- Aggelos Avgerinos
- Al Snow
- Alex Vondrak
- Andre Pankratz
- Andy Brody
- Arnaud Meuret
- Brandon Galbraith
- Burke Libbey
- Chris Gat
- David Genord
- Dillon Welch
- Edward Betts
- Eric Marden
- Garret Alfert
- Godfrey Chan
- Greg Brockman
- Hans de Graaff
- Henrik Hodne
- Igor Victor
- Janko Marohnić
- Jean Boussier
- Jeremy Evans
- Juanito Fatas
- Jun Aruga
- Keerthi Siva
- Ken Ip
- Kevin Menard
- Koichi ITO
- Łukasz Śliwa
- Martin d'Allens
- Masato Nakamura
- Mauricio Linhares
- Nicholas La Roux
- Nicolas Leger
- nycvotes-dev
- Olle Jonsson
- Postmodern
- Richard Hirner
- Richard Hurt
- Richard Schneeman
- Robb Shecter
- Tibor Szolár
- Todd Carrico
[minitest]: https://github.com/seattlerb/minitest
[quality commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
[mime-types-data]: https://github.com/mime-types/mime-types-data
[hoe]: https://github.com/seattlerb/hoe
[allocation\_tracer]: https://github.com/ko1/allocation_tracer
mime-types-3.6.0/mime-types.gemspec 0000644 0000041 0000041 00000012451 14726205276 017315 0 ustar www-data www-data #########################################################
# This file has been automatically generated by gem2tgz #
#########################################################
# -*- encoding: utf-8 -*-
# stub: mime-types 3.6.0 ruby lib
Gem::Specification.new do |s|
s.name = "mime-types".freeze
s.version = "3.6.0"
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
s.metadata = { "bug_tracker_uri" => "https://github.com/mime-types/ruby-mime-types/issues", "changelog_uri" => "https://github.com/mime-types/ruby-mime-types/blob/master/History.md", "homepage_uri" => "https://github.com/mime-types/ruby-mime-types/", "rubygems_mfa_required" => "true", "source_code_uri" => "https://github.com/mime-types/ruby-mime-types/" } if s.respond_to? :metadata=
s.require_paths = ["lib".freeze]
s.authors = ["Austin Ziegler".freeze]
s.date = "2024-10-02"
s.description = "The mime-types library provides a library and registry for information about\nMIME content type definitions. It can be used to determine defined filename\nextensions for MIME types, or to use filename extensions to look up the likely\nMIME type definitions.\n\nVersion 3.0 is a major release that requires Ruby 2.0 compatibility and removes\ndeprecated functions. The columnar registry format introduced in 2.6 has been\nmade the primary format; the registry data has been extracted from this library\nand put into {mime-types-data}[https://github.com/mime-types/mime-types-data].\nAdditionally, mime-types is now licensed exclusively under the MIT licence and\nthere is a code of conduct in effect. There are a number of other smaller\nchanges described in the History file.".freeze
s.email = ["halostatue@gmail.com".freeze]
s.extra_rdoc_files = ["Code-of-Conduct.md".freeze, "Contributing.md".freeze, "History.md".freeze, "Licence.md".freeze, "Manifest.txt".freeze, "README.rdoc".freeze]
s.files = [".standard.yml".freeze, "Code-of-Conduct.md".freeze, "Contributing.md".freeze, "History.md".freeze, "Licence.md".freeze, "Manifest.txt".freeze, "README.rdoc".freeze, "Rakefile".freeze, "lib/mime-types.rb".freeze, "lib/mime/type.rb".freeze, "lib/mime/type/columnar.rb".freeze, "lib/mime/types.rb".freeze, "lib/mime/types/_columnar.rb".freeze, "lib/mime/types/cache.rb".freeze, "lib/mime/types/columnar.rb".freeze, "lib/mime/types/container.rb".freeze, "lib/mime/types/deprecations.rb".freeze, "lib/mime/types/full.rb".freeze, "lib/mime/types/loader.rb".freeze, "lib/mime/types/logger.rb".freeze, "lib/mime/types/registry.rb".freeze, "test/bad-fixtures/malformed".freeze, "test/fixture/json.json".freeze, "test/fixture/old-data".freeze, "test/fixture/yaml.yaml".freeze, "test/minitest_helper.rb".freeze, "test/test_mime_type.rb".freeze, "test/test_mime_types.rb".freeze, "test/test_mime_types_cache.rb".freeze, "test/test_mime_types_class.rb".freeze, "test/test_mime_types_lazy.rb".freeze, "test/test_mime_types_loader.rb".freeze]
s.homepage = "https://github.com/mime-types/ruby-mime-types/".freeze
s.licenses = ["MIT".freeze]
s.rdoc_options = ["--main".freeze, "README.rdoc".freeze]
s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze)
s.rubygems_version = "3.3.15".freeze
s.summary = "The mime-types library provides a library and registry for information about MIME content type definitions".freeze
if s.respond_to? :specification_version then
s.specification_version = 4
end
if s.respond_to? :add_runtime_dependency then
s.add_development_dependency(%q.freeze, [">= 3.0", "< 5"])
s.add_development_dependency(%q.freeze, ["~> 1.0"])
s.add_development_dependency(%q.freeze, ["~> 1.1"])
s.add_development_dependency(%q.freeze, ["~> 1.7"])
s.add_development_dependency(%q.freeze, ["~> 1.0"])
s.add_runtime_dependency(%q.freeze, [">= 0"])
s.add_runtime_dependency(%q.freeze, ["~> 3.2015"])
s.add_development_dependency(%q.freeze, ["~> 5.25"])
s.add_development_dependency(%q.freeze, ["~> 1.0"])
s.add_development_dependency(%q.freeze, ["~> 1.0"])
s.add_development_dependency(%q.freeze, ["~> 1.4"])
s.add_development_dependency(%q.freeze, [">= 10.0", "< 14.0"])
s.add_development_dependency(%q.freeze, [">= 4.0", "< 7"])
s.add_development_dependency(%q.freeze, ["~> 0.21"])
s.add_development_dependency(%q.freeze, ["~> 1.0"])
else
s.add_dependency(%q.freeze, [">= 3.0", "< 5"])
s.add_dependency(%q.freeze, ["~> 1.0"])
s.add_dependency(%q.freeze, ["~> 1.1"])
s.add_dependency(%q.freeze, ["~> 1.7"])
s.add_dependency(%q.freeze, ["~> 1.0"])
s.add_dependency(%q.freeze, [">= 0"])
s.add_dependency(%q.freeze, ["~> 3.2015"])
s.add_dependency(%q.freeze, ["~> 5.25"])
s.add_dependency(%q.freeze, ["~> 1.0"])
s.add_dependency(%q.freeze, ["~> 1.0"])
s.add_dependency(%q.freeze, ["~> 1.4"])
s.add_dependency(%q.freeze, [">= 10.0", "< 14.0"])
s.add_dependency(%q.freeze, [">= 4.0", "< 7"])
s.add_dependency(%q.freeze, ["~> 0.21"])
s.add_dependency(%q.freeze, ["~> 1.0"])
end
end
mime-types-3.6.0/History.md 0000644 0000041 0000041 00000032463 14726205276 015647 0 ustar www-data www-data # Changelog
## 3.6.0 / 2024-10-02
- 2 deprecations:
- Array-based MIME::Type initialization
- String-based MIME::Type initialization
Use of these these will result in deprecation warnings.
- Added `logger` to the gemspec to suppress a bundled gem warning with Ruby
3.3.5. This warning should not be showing up until Ruby 3.4.0 is released and
will be suppressed in Ruby 3.3.6.
- Reworked the deprecation message code to be somewhat more flexible and allow
for outputting certain warnings once. Because there will be at least one other
release after 3.6, we do not need to make the type initialization deprecations
frequent with this release.
## 3.5.2 / 2024-01-02
There are no primary code changes, but we are releasing this as an update as
there are some validation changes and updated code with formatting.
- Dependency and CI updates:
- Masato Nakamura added Ruby 3.3 to the CI workflow in [#179][].
- Fixed regressions in standard formatting in [#180][].
- Removed `minitest-bonus-assertions` because of a bundler resolution issue.
Created a better replacement in-line.
## 3.5.1 / 2023-08-21
- 1 bug fix:
- Better handle possible line-termination strings (legal in Unix filenames)
such as `\n` in `MIME::Types.type_for`. Reported by ooooooo-q in [#177][],
resolved in [#178][].
## 3.5.0 / 2023-08-07
- 1 minor enhancement:
- Robb Shecter changed the default log level for duplicate type variant from
`warn` to `debug` in [#170][]. This works because `MIME::Types.logger` is
intended to fit the `::Logger` interface, and the default logger
(`WarnLogger`) is a subclass of `::Logger` that passes through to
`Kernel.warn`.
- Further consideration has changed cache load messages from `warn` to
`error` and deprecation messages from `warn` to `debug`.
- 1 bug fix:
- Added a definition of `MIME::Type#hash`. Contributed by Alex Vondrak in
[#167][], fixing [#166][].
- Dependency and CI updates:
- Update the .github/workflows/ci.yml workflow to test Ruby 3.2 and more
reliably test certain combinations rather than depending on exclusions.
- Change `.standard.yml` configuration to format for Ruby 2.3 as certain files
are not properly detected with Ruby 2.0.
- Change from `hoe-git` to `hoe-git2` to support Hoe version 4.
- Apply `standardrb --fix`.
- The above changes have resulted in the Soft deprecation of Ruby versions
below 2.6. Any errors reported for Ruby versions 2.0, 2.1, 2.2, 2.3, 2.4,
and 2.5 will be resolved, but maintaining CI for these versions is
unsustainable.
## 3.4.1 / 2021-11-16
- 1 bug fix:
- Fixed a Ruby < 2.3 incompatibility introduced by the use of standardrb,
where `<<-` heredocs were converted to `<<~` heredocs. These have been
reverted back to `<<-` with the indentation kept and a `.strip` call
to prevent excess whitespace.
## 3.4.0 / 2021-11-15
- 1 minor enhancement:
- Added a new field to `MIME::Type` for checking provisional registrations
from IANA. [#157]
- Documentation:
- Kevin Menard synced the documentation so that all examples are correct.
[#153]
- Administrivia:
- Added Ruby 3.0 to the CI test matrix. Added `windows/jruby` to the
CI exclusion list; it refuses to run successfully.
- Removed the Travis CI configuration and changed it to Github Workflows
[#150][]. Removed Coveralls configuration.
- Igor Victor added TruffleRuby to the Travis CI configuration. [#149]
- Koichi ITO loosened an excessively tight dependency. [#147]
- Started using `standardrb` for Ruby formatting and validation.
- Moved `deps:top` functionality to a support file.
## 3.3.1 / 2019-12-26
- 1 minor bug fix:
- Al Snow fixed a warning with MIME::Types::Logger producing a warning
because Ruby 2.7 introduces numbered block parameters. Because of the way
that the MIME::Types::Logger works for deprecation messages, the
initializer parameters had been named `_1`, `_2`, and `_3`. This has now
been resolved. [#146]
- Administrivia:
- Olle Jonsson removed an outdated Travis configuration option. [#142][]
## 3.3 / 2019-09-04
- 1 minor enhancement
- Jean Boussier reduced memory usage for Ruby versions 2.3 or higher by
interning various string values in each type. This is done with a
backwards-compatible call that _freezes_ the strings on older versions of
Ruby. [#141]
- Administrivia:
- Nicholas La Roux updated Travis build configurations. [#139]
## 3.2.2 / 2018-08-12
- Hiroto Fukui removed a stray `debugger` statement that I had used in
producing v3.2.1. [#137]
## 3.2.1 / 2018-08-12
- A few bugs related to MIME::Types::Container and its use in the
mime-types-data helper tools reared their head because I released 3.2
before verifying against mime-types-data.
## 3.2 / 2018-08-12
- 2 minor enhancements
- Janko Marohnić contributed a change to `MIME::Type#priority_order` that
should improve on strict sorting when dealing with MIME types that appear
to be in the same family even if strict sorting would cause an
unregistered type to be sorted first. [#132]
- Dillon Welch contributed a change that added `frozen_string_literal: true`
to files so that modern Rubies can automatically reduce duplicate string
allocations. [#135]
- 2 bug fixes
- Burke Libbey fixed a problem with cached data loading. [#126]
- Resolved an issue where Enumerable#inject returns `nil` when provided an
empty enumerable and a default value has not been provided. This is
because when Enumerable#inject isn't provided a starting value, the first
value is used as the default value. In every case where this error was
happening, the result was supposed to be an array containing Set objects
so they can be reduced to a single Set. [#117][], [#127][], [#134][]
- Fixed an uncontrolled growth bug in MIME::Types::Container where a key
miss would create a new entry with an empty Set in the container. This
was working as designed (this particular feature was heavily used during
MIME::Type registry construction), but the design was flawed in that it
did not have any way of determining the difference between construction
and querying. This would mean that, if you have a function in your web
app that queries the MIME::Types registry by extension, the extension
registry would grow uncontrollably. [#136]
- Deprecations:
- Lazy loading (`$RUBY_MIME_TYPES_LAZY_LOAD`) has been deprecated.
- Documentation Changes:
- Supporting files are now Markdown instead of rdoc, except for the README.
- The history file has been modified to remove all history prior to 3.0.
This history can be found in previous commits.
- A spelling error was corrected by Edward Betts ([#129][]).
- Administrivia:
- CI configuration for more modern versions of Ruby were added by Nicolas
Leger ([#130][]), Jun Aruga ([#125][]), and Austin Ziegler. Removed
ruby-head-clang and rbx (Rubinius) from CI.
- Fixed tests which were asserting equality against nil, which will become
an error in Minitest 6.
## 3.1 / 2016-05-22
- 1 documentation change:
- Tim Smith (@tas50) updated the build badges to be SVGs to improve
readability on high-density (retina) screens with pull request [#112][].
- 3 bug fixes
- A test for `MIME::Types::Cache` fails under Ruby 2.3 because of frozen
strings, [#118][]. This has been fixed.
- The JSON data has been incorrectly encoded since the release of
mime-types 3 on the `xrefs` field, because of the switch to using a Set
to store cross-reference information. This has been fixed.
- A tentative fix for [#117][] has been applied, removing the only circular
require dependencies that exist (and for which there was code to prevent,
but the current fix is simpler). I have no way to verify this fix and
depending on how things are loaded by `delayed_job`, this fix may not be
sufficient.
- 1 governance change
- Updated to Contributor Covenant 1.4.
## 3.0 / 2015-11-21
- 2 governance changes
- This project and the related mime-types-data project are now exclusively
MIT licensed. Resolves [#95][].
- All projects under the mime-types organization now have a standard code
of conduct adapted from the [Contributor Covenant][]. This text can be
found in the [Code-of-Conduct.md][] file.
- 3 major changes
- All methods deprecated in mime-types 2.x have been removed.
- mime-types now requires Ruby 2.0 compatibility or later. Resolves
[#97][].
- The registry data has been removed from mime-types and put into
mime-types-data, maintained and released separately. It can be found at
[mime-types-data][].
- 17 minor changes:
- `MIME::Type` changes:
- Changed the way that simplified types representations are created to
reflect the fact that `x-` prefixes are no longer considered special
according to IANA. A simplified MIME type is case-folded to lowercase.
A new keyword parameter, `remove_x_prefix`, can be provided to remove
`x-` prefixes.
- Improved initialization with an Array works so that extensions do not
need to be wrapped in another array. This means that
`%w(text/yaml yaml yml)` works in the same way that
`['text/yaml', %w(yaml yml)]` did (and still does).
- Changed `priority_compare` to conform with attributes that no longer
exist.
- Changed the internal implementation of extensions to use a frozen Set.
- When extensions are set or modified with `add_extensions`, the primary
registry will be informed of a need to re-index extensions. Resolves
[#84][].
- The preferred extension can be set explicitly. If not set, it will be
the first extension. If the preferred extension is not in the extension
list, it will be added.
- Improved how xref URLs are generated.
- Converted `obsolete`, `registered` and `signature` to `attr_accessors`.
- `MIME::Types` changes:
- Modified `MIME::Types.new` to track instances of `MIME::Types` so that
they can be told to reindex the extensions as necessary.
- Removed `data_version` attribute.
- Changed `#[]` so that the `complete` and `registered` flags are
keywords instead of a generic options parameter.
- Extracted the class methods to a separate file.
- Changed the container implementation to use a Set instead of an Array
to prevent data duplication. Resolves [#79][].
- `MIME::Types::Cache` changes:
- Caching is now based on the data gem version instead of the mime-types
version.
- Caching is compatible with columnar registry stores.
- `MIME::Types::Loader` changes:
- `MIME::Types::Loader::PATH` has been removed and replaced with
`MIME::Types::Data::PATH` from the mime-types-data gem. The environment
variable `RUBY_MIME_TYPES_DATA` is still used.
- Support for the long-deprecated mime-types v1 format has been removed.
- The registry is default loaded from the columnar store by default. The
internal format of the columnar store has changed; many of the boolean
flags are now loaded from a single file. Resolves [#85][].
[#79]: https://github.com/mime-types/ruby-mime-types/pull/79
[#84]: https://github.com/mime-types/ruby-mime-types/pull/84
[#85]: https://github.com/mime-types/ruby-mime-types/pull/85
[#95]: https://github.com/mime-types/ruby-mime-types/pull/95
[#97]: https://github.com/mime-types/ruby-mime-types/pull/97
[#112]: https://github.com/mime-types/ruby-mime-types/pull/112
[#117]: https://github.com/mime-types/ruby-mime-types/issues/117
[#118]: https://github.com/mime-types/ruby-mime-types/pull/118
[#125]: https://github.com/mime-types/ruby-mime-types/pull/125
[#126]: https://github.com/mime-types/ruby-mime-types/pull/126
[#127]: https://github.com/mime-types/ruby-mime-types/issues/127
[#129]: https://github.com/mime-types/ruby-mime-types/pull/129
[#130]: https://github.com/mime-types/ruby-mime-types/pull/130
[#127]: https://github.com/mime-types/ruby-mime-types/issues/127
[#132]: https://github.com/mime-types/ruby-mime-types/pull/132
[#134]: https://github.com/mime-types/ruby-mime-types/issues/134
[#135]: https://github.com/mime-types/ruby-mime-types/pull/135
[#136]: https://github.com/mime-types/ruby-mime-types/issues/136
[#137]: https://github.com/mime-types/ruby-mime-types/pull/137
[#139]: https://github.com/mime-types/ruby-mime-types/pull/139
[#141]: https://github.com/mime-types/ruby-mime-types/pull/141
[#142]: https://github.com/mime-types/ruby-mime-types/pull/142
[#146]: https://github.com/mime-types/ruby-mime-types/pull/146
[#147]: https://github.com/mime-types/ruby-mime-types/pull/147
[#149]: https://github.com/mime-types/ruby-mime-types/pull/149
[#150]: https://github.com/mime-types/ruby-mime-types/pull/150
[#153]: https://github.com/mime-types/ruby-mime-types/pull/153
[#166]: https://github.com/mime-types/ruby-mime-types/issues/166
[#167]: https://github.com/mime-types/ruby-mime-types/pull/167
[#170]: https://github.com/mime-types/ruby-mime-types/pull/170
[#177]: https://github.com/mime-types/ruby-mime-types/issues/177
[#178]: https://github.com/mime-types/ruby-mime-types/pull/178
[#179]: https://github.com/mime-types/ruby-mime-types/pull/179
[#180]: https://github.com/mime-types/ruby-mime-types/pull/180
[code-of-conduct.md]: Code-of-Conduct_md.html
[contributor covenant]: http://contributor-covenant.org
[mime-types-data]: https://github.com/mime-types/mime-types-data