mime-types-3.5.2/0000755000004100000410000000000014571066020013643 5ustar www-datawww-datamime-types-3.5.2/Licence.md0000644000004100000410000000223614571066020015532 0ustar www-datawww-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.5.2/Manifest.txt0000644000004100000410000000130514571066020016151 0ustar www-datawww-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.5.2/README.rdoc0000644000004100000410000002145614571066020015461 0ustar www-datawww-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 :: {Build Status}[https://github.com/mime-types/ruby-mime-types/actions/workflows/ci.yml] test coverage :: {Coverage Status}[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][] 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.5.2/.standard.yml0000644000004100000410000000010214571066020016235 0ustar www-datawww-dataparallel: true ruby_version: 2.3 ignore: - 'mime-types.gemspec' mime-types-3.5.2/lib/0000755000004100000410000000000014571066020014411 5ustar www-datawww-datamime-types-3.5.2/lib/mime-types.rb0000644000004100000410000000006414571066020017027 0ustar www-datawww-data# frozen_string_literal: true require "mime/types" mime-types-3.5.2/lib/mime/0000755000004100000410000000000014571066020015340 5ustar www-datawww-datamime-types-3.5.2/lib/mime/type/0000755000004100000410000000000014571066020016321 5ustar www-datawww-datamime-types-3.5.2/lib/mime/type/columnar.rb0000644000004100000410000000321314571066020020465 0ustar www-datawww-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.5.2/lib/mime/types/0000755000004100000410000000000014571066020016504 5ustar www-datawww-datamime-types-3.5.2/lib/mime/types/logger.rb0000644000004100000410000000135314571066020020312 0ustar www-datawww-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.5.2/lib/mime/types/container.rb0000644000004100000410000000341714571066020021020 0ustar www-datawww-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 won't 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 doesn't 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.5.2/lib/mime/types/deprecations.rb0000644000004100000410000000151314571066020021511 0ustar www-datawww-data# frozen_string_literal: true require "mime/types/logger" # The namespace for MIME applications, tools, and libraries. module MIME ## class Types # Used to mark a method as deprecated in the mime-types interface. def self.deprecated(klass, sym, message = nil, &block) # :nodoc: level = case klass when Class, Module "." else klass = klass.class "#" end message = case message when :private, :protected "and will be #{message}" when nil "and will be removed" else message end MIME::Types.logger.debug <<-WARNING.chomp.strip #{caller(2..2).first}: #{klass}#{level}#{sym} is deprecated #{message}. WARNING return unless block block.call end end end mime-types-3.5.2/lib/mime/types/full.rb0000644000004100000410000000040514571066020017772 0ustar www-datawww-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.5.2/lib/mime/types/columnar.rb0000644000004100000410000000006414571066020020651 0ustar www-datawww-data# frozen_string_literal: true require "mime/types" mime-types-3.5.2/lib/mime/types/loader.rb0000644000004100000410000001105014571066020020274 0ustar www-datawww-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.5.2/lib/mime/types/registry.rb0000644000004100000410000000364614571066020020712 0ustar www-datawww-data# frozen_string_literal: true 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") MIME::Types.logger.debug <<-WARNING.chomp.strip Lazy loading ($RUBY_MIME_TYPES_LAZY_LOAD) is deprecated and will be removed. WARNING (lazy = ENV["RUBY_MIME_TYPES_LAZY_LOAD"]) && (lazy != "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.5.2/lib/mime/types/cache.rb0000644000004100000410000000402314571066020020073 0ustar www-datawww-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.5.2/lib/mime/types/_columnar.rb0000644000004100000410000000626214571066020021016 0ustar www-datawww-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.5.2/lib/mime/types.rb0000644000004100000410000001747714571066020017051 0ustar www-datawww-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.5.2/lib/mime/type.rb0000644000004100000410000005045214571066020016654 0ustar www-datawww-data# frozen_string_literal: true ## module MIME end # 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('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 isn't +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.5.2" include Comparable # :stopdoc: # TODO verify mime-type character restrictions; I am pretty sure that this is # too wide open. MEDIA_TYPE_RE = %r{([-\w.+]+)/([-\w.+]*)}.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. # * 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 self.content_type = content_type.shift self.extensions = content_type.flatten when MIME::Type init_with(content_type.to_h) else 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 # don't 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's # 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 #xtensions. # # :attr_accessor: preferred_extension ## def preferred_extension @preferred_extension || extensions.first end ## def preferred_extension=(value) # :nodoc: add_extensions(value) if value @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('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 don't 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.5.2/test/0000755000004100000410000000000014571066020014622 5ustar www-datawww-datamime-types-3.5.2/test/minitest_helper.rb0000644000004100000410000000026314571066020020343 0ustar www-datawww-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.5.2/test/test_mime_types_loader.rb0000644000004100000410000000164414571066020021714 0ustar www-datawww-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.5.2/test/test_mime_types.rb0000644000004100000410000001254114571066020020364 0ustar www-datawww-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(["text/plain", %w[txt]]), MIME::Type.new(["image/jpeg", %w[jpg jpeg]]), MIME::Type.new("application/x-wordperfect6.1"), MIME::Type.new( "content-type" => "application/x-www-form-urlencoded", "registered" => true ), MIME::Type.new(["application/x-gzip", %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("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("application/x-eruby") } let(:jinja) { MIME::Type.new("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.5.2/test/bad-fixtures/0000755000004100000410000000000014571066020017217 5ustar www-datawww-datamime-types-3.5.2/test/bad-fixtures/malformed0000644000004100000410000000074414571066020021115 0ustar www-datawww-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.5.2/test/test_mime_types_lazy.rb0000644000004100000410000000253014571066020021420 0ustar www-datawww-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.5.2/test/test_mime_types_cache.rb0000644000004100000410000000637714571066020021521 0ustar www-datawww-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.5.2/test/test_mime_types_class.rb0000644000004100000410000001174514571066020021556 0ustar www-datawww-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("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("application/x-eruby") } let(:jinja) { MIME::Type.new("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.5.2/test/fixture/0000755000004100000410000000000014571066020016310 5ustar www-datawww-datamime-types-3.5.2/test/fixture/old-data0000644000004100000410000000074414571066020017725 0ustar www-datawww-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.5.2/test/fixture/json.json0000644000004100000410000000175514571066020020164 0ustar www-datawww-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.5.2/test/fixture/yaml.yaml0000644000004100000410000000230414571066020020135 0ustar www-datawww-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.5.2/test/test_mime_type.rb0000644000004100000410000004504314571066020020204 0ustar www-datawww-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("x-appl/x-zip") { |t| t.extensions = %w[zip zp] } } let(:text_plain) { mime_type("text/plain") } let(:text_html) { mime_type("text/html") } let(:image_jpeg) { mime_type("image/jpeg") } let(:application_javascript) { mime_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("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("apps") end assert_equal 'Invalid Content-Type "apps"', exception.to_s end it "creates a valid content type just from a string" do type = MIME::Type.new("text/x-yaml") assert_instance_of MIME::Type, type assert_equal "text/x-yaml", type.content_type end it "yields the content type in a block" do MIME::Type.new("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 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 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("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("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("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("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("text/plain")) end end describe "#hash" do it "is the same between #eql? MIME::Type instances" do assert_equal text_plain.hash, mime_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("text/plain").hash end it "uses the #simplified value" do assert_equal text_plain.hash, mime_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("text/1") } let(:text_1p) { mime_type("text/1") } let(:text_2) { mime_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("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("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("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("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("a/b").to_json end it "converts to JSON with provisional when requested" do type = mime_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("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.5.2/Rakefile0000644000004100000410000001333314571066020015313 0ustar www-datawww-datarequire "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_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.5.2/Code-of-Conduct.md0000644000004100000410000000626314571066020017045 0ustar www-datawww-data# Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: - Using welcoming and inclusive language - Being respectful of differing viewpoints and experiences - Gracefully accepting constructive criticism - Focusing on what is best for the community - Showing empathy towards other community members Examples of unacceptable behavior by participants include: - The use of sexualized language or imagery and unwelcome sexual attention or advances - Trolling, insulting/derogatory comments, and personal or political attacks - Public or private harassment - Publishing others' private information, such as a physical or electronic address, without explicit permission - Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers 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, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [INSERT EMAIL ADDRESS]. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html [homepage]: https://www.contributor-covenant.org mime-types-3.5.2/Contributing.md0000644000004100000410000001016114571066020016633 0ustar www-datawww-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.5.2/mime-types.gemspec0000644000004100000410000001227514571066020017310 0ustar www-datawww-data######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: mime-types 3.5.2 ruby lib Gem::Specification.new do |s| s.name = "mime-types".freeze s.version = "3.5.2" 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-01-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, ["~> 3.2015"]) s.add_development_dependency(%q.freeze, ["~> 5.20"]) 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, ["~> 3.2015"]) s.add_dependency(%q.freeze, ["~> 5.20"]) 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.5.2/History.md0000644000004100000410000003124714571066020015635 0ustar www-datawww-data# Changelog ## 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