mime-types 1.25.1 → 2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +8 -8
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.autotest +5 -0
  5. data/.minitest.rb +2 -0
  6. data/.travis.yml +0 -4
  7. data/Contributing.rdoc +13 -14
  8. data/Gemfile +1 -0
  9. data/History.rdoc +100 -7
  10. data/Licence.rdoc +1 -1
  11. data/Manifest.txt +17 -24
  12. data/README.rdoc +26 -47
  13. data/Rakefile +42 -185
  14. data/data/mime-types.json +1 -0
  15. data/docs/COPYING.txt +339 -339
  16. data/docs/artistic.txt +127 -127
  17. data/lib/mime.rb +50 -0
  18. data/lib/mime/type.rb +634 -0
  19. data/lib/mime/types.rb +254 -912
  20. data/lib/mime/types/cache.rb +73 -0
  21. data/lib/mime/types/loader.rb +248 -0
  22. data/lib/mime/types/loader_path.rb +16 -0
  23. data/support/benchmarker.rb +55 -0
  24. data/support/convert.rb +130 -0
  25. data/support/iana_downloader.rb +201 -0
  26. data/test/fixture/json.json +1 -0
  27. data/test/fixture/old-data +9 -0
  28. data/test/fixture/yaml.yaml +75 -0
  29. data/test/minitest_helper.rb +22 -0
  30. data/test/test_mime_type.rb +337 -143
  31. data/test/test_mime_types.rb +75 -84
  32. data/test/test_mime_types_cache.rb +30 -29
  33. data/test/test_mime_types_class.rb +135 -0
  34. data/test/test_mime_types_lazy.rb +3 -2
  35. data/test/test_mime_types_loader.rb +42 -0
  36. metadata +61 -90
  37. metadata.gz.sig +0 -0
  38. data/lib/mime/types/application +0 -1010
  39. data/lib/mime/types/application.mac +0 -3
  40. data/lib/mime/types/application.nonstandard +0 -132
  41. data/lib/mime/types/application.obsolete +0 -41
  42. data/lib/mime/types/audio +0 -138
  43. data/lib/mime/types/audio.nonstandard +0 -11
  44. data/lib/mime/types/audio.obsolete +0 -1
  45. data/lib/mime/types/image +0 -46
  46. data/lib/mime/types/image.nonstandard +0 -20
  47. data/lib/mime/types/image.obsolete +0 -5
  48. data/lib/mime/types/message +0 -18
  49. data/lib/mime/types/message.obsolete +0 -2
  50. data/lib/mime/types/model +0 -15
  51. data/lib/mime/types/multipart +0 -14
  52. data/lib/mime/types/multipart.nonstandard +0 -1
  53. data/lib/mime/types/multipart.obsolete +0 -7
  54. data/lib/mime/types/other.nonstandard +0 -8
  55. data/lib/mime/types/text +0 -61
  56. data/lib/mime/types/text.nonstandard +0 -7
  57. data/lib/mime/types/text.obsolete +0 -8
  58. data/lib/mime/types/text.vms +0 -1
  59. data/lib/mime/types/video +0 -75
  60. data/lib/mime/types/video.nonstandard +0 -16
  61. data/lib/mime/types/video.obsolete +0 -3
@@ -1,968 +1,310 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
2
 
3
- # The namespace for MIME applications, tools, and libraries.
4
- module MIME
5
- # Reflects a MIME Content-Type which is in invalid format (e.g., it isn't
6
- # in the form of type/subtype).
7
- class InvalidContentType < RuntimeError; end
8
-
9
- # The definition of one MIME content-type.
10
- #
11
- # == Usage
12
- # require 'mime/types'
13
- #
14
- # plaintext = MIME::Types['text/plain'].first
15
- # # returns [text/plain, text/plain]
16
- # text = plaintext.first
17
- # print text.media_type # => 'text'
18
- # print text.sub_type # => 'plain'
19
- #
20
- # puts text.extensions.join(" ") # => 'asc txt c cc h hh cpp'
21
- #
22
- # puts text.encoding # => 8bit
23
- # puts text.binary? # => false
24
- # puts text.ascii? # => true
25
- # puts text == 'text/plain' # => true
26
- # puts MIME::Type.simplified('x-appl/x-zip') # => 'appl/zip'
27
- #
28
- # puts MIME::Types.any? { |type|
29
- # type.content_type == 'text/plain'
30
- # } # => true
31
- # puts MIME::Types.all?(&:registered?)
32
- # # => false
33
- #
34
- class Type
35
- # The released version of Ruby MIME::Types
36
- VERSION = '1.25.1'
37
-
38
- include Comparable
39
-
40
- MEDIA_TYPE_RE = %r{([-\w.+]+)/([-\w.+]*)}o
41
- UNREG_RE = %r{[Xx]-}o
42
- ENCODING_RE = %r{(?:base64|7bit|8bit|quoted\-printable)}o
43
- PLATFORM_RE = %r|#{RUBY_PLATFORM}|o
44
-
45
- SIGNATURES = %w(application/pgp-keys application/pgp
46
- application/pgp-signature application/pkcs10
47
- application/pkcs7-mime application/pkcs7-signature
48
- text/vcard)
49
-
50
- IANA_URL = "http://www.iana.org/assignments/media-types/%s/%s"
51
- RFC_URL = "http://rfc-editor.org/rfc/rfc%s.txt"
52
- DRAFT_URL = "http://datatracker.ietf.org/public/idindex.cgi?command=id_details&filename=%s"
53
- LTSW_URL = "http://www.ltsw.se/knbase/internet/%s.htp"
54
- CONTACT_URL = "http://www.iana.org/assignments/contact-people.htm#%s"
55
-
56
- # Returns +true+ if the simplified type matches the current
57
- def like?(other)
58
- if other.respond_to?(:simplified)
59
- @simplified == other.simplified
60
- else
61
- @simplified == Type.simplified(other)
62
- end
63
- end
64
-
65
- # Compares the MIME::Type against the exact content type or the
66
- # simplified type (the simplified type will be used if comparing against
67
- # something that can be treated as a String with #to_s). In comparisons,
68
- # this is done against the lowercase version of the MIME::Type.
69
- def <=>(other)
70
- if other.respond_to?(:content_type)
71
- @content_type.downcase <=> other.content_type.downcase
72
- elsif other.respond_to?(:to_s)
73
- @simplified <=> Type.simplified(other.to_s)
74
- else
75
- @content_type.downcase <=> other.downcase
76
- end
77
- end
78
-
79
- # Compares the MIME::Type based on how reliable it is before doing a
80
- # normal <=> comparison. Used by MIME::Types#[] to sort types. The
81
- # comparisons involved are:
82
- #
83
- # 1. self.simplified <=> other.simplified (ensures that we
84
- # don't try to compare different types)
85
- # 2. IANA-registered definitions < other definitions.
86
- # 3. Generic definitions < platform definitions.
87
- # 3. Complete definitions < incomplete definitions.
88
- # 4. Current definitions < obsolete definitions.
89
- # 5. Obselete with use-instead references < obsolete without.
90
- # 6. Obsolete use-instead definitions are compared.
91
- def priority_compare(other)
92
- pc = simplified <=> other.simplified
93
-
94
- if pc.zero?
95
- pc = if registered? != other.registered?
96
- registered? ? -1 : 1 # registered < unregistered
97
- elsif platform? != other.platform?
98
- platform? ? 1 : -1 # generic < platform
99
- elsif complete? != other.complete?
100
- complete? ? -1 : 1 # complete < incomplete
101
- elsif obsolete? != other.obsolete?
102
- obsolete? ? 1 : -1 # current < obsolete
103
- else
104
- 0
105
- end
106
-
107
- if pc.zero? and obsolete? and (use_instead != other.use_instead)
108
- pc = if use_instead.nil?
109
- -1
110
- elsif other.use_instead.nil?
111
- 1
112
- else
113
- use_instead <=> other.use_instead
114
- end
115
- end
116
- end
117
-
118
- pc
119
- end
120
-
121
- # Returns +true+ if the other object is a MIME::Type and the content
122
- # types match.
123
- def eql?(other)
124
- other.kind_of?(MIME::Type) and self == other
125
- end
126
-
127
- # Returns the whole MIME content-type string.
128
- #
129
- # text/plain => text/plain
130
- # x-chemical/x-pdb => x-chemical/x-pdb
131
- attr_reader :content_type
132
- # Returns the media type of the simplified MIME type.
133
- #
134
- # text/plain => text
135
- # x-chemical/x-pdb => chemical
136
- attr_reader :media_type
137
- # Returns the media type of the unmodified MIME type.
138
- #
139
- # text/plain => text
140
- # x-chemical/x-pdb => x-chemical
141
- attr_reader :raw_media_type
142
- # Returns the sub-type of the simplified MIME type.
143
- #
144
- # text/plain => plain
145
- # x-chemical/x-pdb => pdb
146
- attr_reader :sub_type
147
- # Returns the media type of the unmodified MIME type.
148
- #
149
- # text/plain => plain
150
- # x-chemical/x-pdb => x-pdb
151
- attr_reader :raw_sub_type
152
- # The MIME types main- and sub-label can both start with <tt>x-</tt>,
153
- # which indicates that it is a non-registered name. Of course, after
154
- # registration this flag can disappear, adds to the confusing
155
- # proliferation of MIME types. The simplified string has the <tt>x-</tt>
156
- # removed and are translated to lowercase.
157
- #
158
- # text/plain => text/plain
159
- # x-chemical/x-pdb => chemical/pdb
160
- attr_reader :simplified
161
- # The list of extensions which are known to be used for this MIME::Type.
162
- # Non-array values will be coerced into an array with #to_a. Array
163
- # values will be flattened and +nil+ values removed.
164
- attr_accessor :extensions
165
- remove_method :extensions= ;
166
- def extensions=(ext) #:nodoc:
167
- @extensions = [ext].flatten.compact
168
- end
169
-
170
- # The encoding (7bit, 8bit, quoted-printable, or base64) required to
171
- # transport the data of this content type safely across a network, which
172
- # roughly corresponds to Content-Transfer-Encoding. A value of +nil+ or
173
- # <tt>:default</tt> will reset the #encoding to the #default_encoding
174
- # for the MIME::Type. Raises ArgumentError if the encoding provided is
175
- # invalid.
176
- #
177
- # If the encoding is not provided on construction, this will be either
178
- # 'quoted-printable' (for text/* media types) and 'base64' for eveything
179
- # else.
180
- attr_accessor :encoding
181
- remove_method :encoding= ;
182
- def encoding=(enc) #:nodoc:
183
- if enc.nil? or enc == :default
184
- @encoding = self.default_encoding
185
- elsif enc =~ ENCODING_RE
186
- @encoding = enc
187
- else
188
- raise ArgumentError, "The encoding must be nil, :default, base64, 7bit, 8bit, or quoted-printable."
189
- end
190
- end
191
-
192
- # The regexp for the operating system that this MIME::Type is specific
193
- # to.
194
- attr_accessor :system
195
- remove_method :system= ;
196
- def system=(os) #:nodoc:
197
- if os.nil? or os.kind_of?(Regexp)
198
- @system = os
199
- else
200
- @system = %r|#{os}|
201
- end
202
- end
203
- # Returns the default encoding for the MIME::Type based on the media
204
- # type.
205
- attr_reader :default_encoding
206
- remove_method :default_encoding
207
- def default_encoding
208
- (@media_type == 'text') ? 'quoted-printable' : 'base64'
209
- end
210
-
211
- # Returns the media type or types that should be used instead of this
212
- # media type, if it is obsolete. If there is no replacement media type,
213
- # or it is not obsolete, +nil+ will be returned.
214
- attr_reader :use_instead
215
- remove_method :use_instead
216
- def use_instead
217
- return nil unless @obsolete
218
- @use_instead
219
- end
220
-
221
- # Returns +true+ if the media type is obsolete.
222
- def obsolete?
223
- @obsolete ? true : false
224
- end
225
- # Sets the obsolescence indicator for this media type.
226
- attr_writer :obsolete
227
-
228
- # The documentation for this MIME::Type. Documentation about media
229
- # types will be found on a media type definition as a comment.
230
- # Documentation will be found through #docs.
231
- attr_accessor :docs
232
- remove_method :docs= ;
233
- def docs=(d)
234
- if d
235
- a = d.scan(%r{use-instead:#{MEDIA_TYPE_RE}})
236
-
237
- if a.empty?
238
- @use_instead = nil
239
- else
240
- @use_instead = a.map { |el| "#{el[0]}/#{el[1]}" }
241
- end
242
- end
243
- @docs = d
244
- end
245
-
246
- # The encoded URL list for this MIME::Type. See #urls for more
247
- # information.
248
- attr_accessor :url
249
- # The decoded URL list for this MIME::Type.
250
- # The special URL value IANA will be translated into:
251
- # http://www.iana.org/assignments/media-types/<mediatype>/<subtype>
252
- #
253
- # The special URL value RFC### will be translated into:
254
- # http://www.rfc-editor.org/rfc/rfc###.txt
255
- #
256
- # The special URL value DRAFT:name will be translated into:
257
- # https://datatracker.ietf.org/public/idindex.cgi?
258
- # command=id_detail&filename=<name>
259
- #
260
- # The special URL value LTSW will be translated into:
261
- # http://www.ltsw.se/knbase/internet/<mediatype>.htp
262
- #
263
- # The special URL value [token] will be translated into:
264
- # http://www.iana.org/assignments/contact-people.htm#<token>
265
- #
266
- # These values will be accessible through #urls, which always returns an
267
- # array.
268
- def urls
269
- @url.map do |el|
270
- case el
271
- when %r{^IANA$}
272
- IANA_URL % [ @media_type, @sub_type ]
273
- when %r{^RFC(\d+)$}
274
- RFC_URL % $1
275
- when %r{^DRAFT:(.+)$}
276
- DRAFT_URL % $1
277
- when %r{^LTSW$}
278
- LTSW_URL % @media_type
279
- when %r{^\{([^=]+)=([^\}]+)\}}
280
- [$1, $2]
281
- when %r{^\[([^=]+)=([^\]]+)\]}
282
- [$1, CONTACT_URL % $2]
283
- when %r{^\[([^\]]+)\]}
284
- CONTACT_URL % $1
285
- else
286
- el
287
- end
288
- end
289
- end
290
-
291
- class << self
292
- # The MIME types main- and sub-label can both start with <tt>x-</tt>,
293
- # which indicates that it is a non-registered name. Of course, after
294
- # registration this flag can disappear, adds to the confusing
295
- # proliferation of MIME types. The simplified string has the
296
- # <tt>x-</tt> removed and are translated to lowercase.
297
- def simplified(content_type)
298
- matchdata = MEDIA_TYPE_RE.match(content_type)
299
-
300
- if matchdata.nil?
301
- simplified = nil
302
- else
303
- media_type = matchdata.captures[0].downcase.gsub(UNREG_RE, '')
304
- subtype = matchdata.captures[1].downcase.gsub(UNREG_RE, '')
305
- simplified = "#{media_type}/#{subtype}"
306
- end
307
- simplified
308
- end
309
-
310
- # Creates a MIME::Type from an array in the form of:
311
- # [type-name, [extensions], encoding, system]
312
- #
313
- # +extensions+, +encoding+, and +system+ are optional.
314
- #
315
- # MIME::Type.from_array("application/x-ruby", ['rb'], '8bit')
316
- # MIME::Type.from_array(["application/x-ruby", ['rb'], '8bit'])
317
- #
318
- # These are equivalent to:
319
- #
320
- # MIME::Type.new('application/x-ruby') do |t|
321
- # t.extensions = %w(rb)
322
- # t.encoding = '8bit'
323
- # end
324
- def from_array(*args) #:yields MIME::Type.new:
325
- # Dereferences the array one level, if necessary.
326
- args = args.first if args.first.kind_of? Array
327
-
328
- unless args.size.between?(1, 8)
329
- raise ArgumentError, "Array provided must contain between one and eight elements."
330
- end
331
-
332
- MIME::Type.new(args.shift) do |t|
333
- t.extensions, t.encoding, t.system, t.obsolete, t.docs, t.url,
334
- t.registered = *args
335
- yield t if block_given?
336
- end
337
- end
338
-
339
- # Creates a MIME::Type from a hash. Keys are case-insensitive,
340
- # dashes may be replaced with underscores, and the internal Symbol
341
- # of the lowercase-underscore version can be used as well. That is,
342
- # Content-Type can be provided as content-type, Content_Type,
343
- # content_type, or :content_type.
344
- #
345
- # Known keys are <tt>Content-Type</tt>,
346
- # <tt>Content-Transfer-Encoding</tt>, <tt>Extensions</tt>, and
347
- # <tt>System</tt>.
348
- #
349
- # MIME::Type.from_hash('Content-Type' => 'text/x-yaml',
350
- # 'Content-Transfer-Encoding' => '8bit',
351
- # 'System' => 'linux',
352
- # 'Extensions' => ['yaml', 'yml'])
353
- #
354
- # This is equivalent to:
355
- #
356
- # MIME::Type.new('text/x-yaml') do |t|
357
- # t.encoding = '8bit'
358
- # t.system = 'linux'
359
- # t.extensions = ['yaml', 'yml']
360
- # end
361
- def from_hash(hash) #:yields MIME::Type.new:
362
- type = {}
363
- hash.each_pair do |k, v|
364
- type[k.to_s.tr('A-Z', 'a-z').gsub(/-/, '_').to_sym] = v
365
- end
366
-
367
- MIME::Type.new(type[:content_type]) do |t|
368
- t.extensions = type[:extensions]
369
- t.encoding = type[:content_transfer_encoding]
370
- t.system = type[:system]
371
- t.obsolete = type[:obsolete]
372
- t.docs = type[:docs]
373
- t.url = type[:url]
374
- t.registered = type[:registered]
375
-
376
- yield t if block_given?
377
- end
378
- end
379
-
380
- # Essentially a copy constructor.
381
- #
382
- # MIME::Type.from_mime_type(plaintext)
383
- #
384
- # is equivalent to:
385
- #
386
- # MIME::Type.new(plaintext.content_type.dup) do |t|
387
- # t.extensions = plaintext.extensions.dup
388
- # t.system = plaintext.system.dup
389
- # t.encoding = plaintext.encoding.dup
390
- # end
391
- def from_mime_type(mime_type) #:yields the new MIME::Type:
392
- MIME::Type.new(mime_type.content_type.dup) do |t|
393
- t.extensions = mime_type.extensions.map { |e| e.dup }
394
- t.url = mime_type.url && mime_type.url.map { |e| e.dup }
395
-
396
- mime_type.system && t.system = mime_type.system.dup
397
- mime_type.encoding && t.encoding = mime_type.encoding.dup
398
-
399
- t.obsolete = mime_type.obsolete?
400
- t.registered = mime_type.registered?
401
-
402
- mime_type.docs && t.docs = mime_type.docs.dup
403
-
404
- yield t if block_given?
405
- end
406
- end
407
- end
408
-
409
- # Builds a MIME::Type object from the provided MIME Content Type value
410
- # (e.g., 'text/plain' or 'applicaton/x-eruby'). The constructed object
411
- # is yielded to an optional block for additional configuration, such as
412
- # associating extensions and encoding information.
413
- def initialize(content_type) #:yields self:
414
- matchdata = MEDIA_TYPE_RE.match(content_type)
415
-
416
- if matchdata.nil?
417
- raise InvalidContentType, "Invalid Content-Type provided ('#{content_type}')"
418
- end
419
-
420
- @content_type = content_type
421
- @raw_media_type = matchdata.captures[0]
422
- @raw_sub_type = matchdata.captures[1]
423
-
424
- @simplified = MIME::Type.simplified(@content_type)
425
- matchdata = MEDIA_TYPE_RE.match(@simplified)
426
- @media_type = matchdata.captures[0]
427
- @sub_type = matchdata.captures[1]
428
-
429
- self.extensions = nil
430
- self.encoding = :default
431
- self.system = nil
432
- self.registered = true
433
- self.url = nil
434
- self.obsolete = nil
435
- self.docs = nil
436
-
437
- yield self if block_given?
438
- end
439
-
440
- # MIME content-types which are not regestered by IANA nor defined in
441
- # RFCs are required to start with <tt>x-</tt>. This counts as well for
442
- # a new media type as well as a new sub-type of an existing media
443
- # type. If either the media-type or the content-type begins with
444
- # <tt>x-</tt>, this method will return +false+.
445
- def registered?
446
- if (@raw_media_type =~ UNREG_RE) || (@raw_sub_type =~ UNREG_RE)
447
- false
448
- else
449
- @registered
450
- end
451
- end
452
- attr_writer :registered #:nodoc:
453
-
454
- # MIME types can be specified to be sent across a network in particular
455
- # formats. This method returns +true+ when the MIME type encoding is set
456
- # to <tt>base64</tt>.
457
- def binary?
458
- @encoding == 'base64'
459
- end
460
-
461
- # MIME types can be specified to be sent across a network in particular
462
- # formats. This method returns +false+ when the MIME type encoding is
463
- # set to <tt>base64</tt>.
464
- def ascii?
465
- not binary?
466
- end
467
-
468
- # Returns +true+ when the simplified MIME type is in the list of known
469
- # digital signatures.
470
- def signature?
471
- SIGNATURES.include?(@simplified.downcase)
472
- end
473
-
474
- # Returns +true+ if the MIME::Type is specific to an operating system.
475
- def system?
476
- not @system.nil?
477
- end
478
-
479
- # Returns +true+ if the MIME::Type is specific to the current operating
480
- # system as represented by RUBY_PLATFORM.
481
- def platform?
482
- system? and (RUBY_PLATFORM =~ @system)
483
- end
3
+ require 'mime/type'
4
+ require 'mime/types/cache'
5
+ require 'mime/types/loader'
6
+
7
+ # MIME::Types is a registry of MIME types. It is both a class (created with
8
+ # MIME::Types.new) and a default registry (loaded automatically or through
9
+ # interactions with MIME::Types.[] and MIME::Types.type_for).
10
+ #
11
+ # == The Default mime-types Registry
12
+ #
13
+ # The default mime-types registry is loaded automatically when the library
14
+ # is required (<tt>require 'mime/types'</tt>), but it may be lazily loaded
15
+ # (loaded on first use) with the use of the environment variable
16
+ # +RUBY_MIME_TYPES_LAZY_LOAD+ having any value other than +false+. The
17
+ # initial startup is about 14× faster (~10 ms vs ~140 ms), but the
18
+ # registry will be loaded at some point in the future.
19
+ #
20
+ # The default mime-types registry can also be loaded from a Marshal cache
21
+ # file specific to the version of MIME::Types being loaded. This will be
22
+ # handled automatically with the use of a file referred to in the
23
+ # environment variable +RUBY_MIME_TYPES_CACHE+. MIME::Types will attempt to
24
+ # load the registry from this cache file (MIME::Type::Cache.load); if it
25
+ # cannot be loaded (because the file does not exist, there is an error, or
26
+ # the data is for a different version of mime-types), the default registry
27
+ # will be loaded from the normal JSON version and then the cache file will
28
+ # be *written* to the location indicated by +RUBY_MIME_TYPES_CACHE+. Cache
29
+ # file loads just over 4½× faster (~30 ms vs ~140 ms).
30
+ # loads.
31
+ #
32
+ # Notes:
33
+ # * The loading of the default registry is *not* atomic; when using a
34
+ # multi-threaded environment, it is recommended that lazy loading is not
35
+ # used and mime-types is loaded as early as possible.
36
+ # * Cache files should be specified per application in a multiprocess
37
+ # environment and should be initialized during deployment or before
38
+ # forking to minimize the chance that the multiple processes will be
39
+ # trying to write to the same cache file at the same time, or that two
40
+ # applications that are on different versions of mime-types would be
41
+ # thrashing the cache.
42
+ # * Unless cache files are preinitialized, the application using the
43
+ # mime-types cache file must have read/write permission to the cache file.
44
+ #
45
+ # == Usage
46
+ # require 'mime/types'
47
+ #
48
+ # plaintext = MIME::Types['text/plain']
49
+ # print plaintext.media_type # => 'text'
50
+ # print plaintext.sub_type # => 'plain'
51
+ #
52
+ # puts plaintext.extensions.join(" ") # => 'asc txt c cc h hh cpp'
53
+ #
54
+ # puts plaintext.encoding # => 8bit
55
+ # puts plaintext.binary? # => false
56
+ # puts plaintext.ascii? # => true
57
+ # puts plaintext.obsolete? # => false
58
+ # puts plaintext.registered? # => true
59
+ # puts plaintext == 'text/plain' # => true
60
+ # puts MIME::Type.simplified('x-appl/x-zip') # => 'appl/zip'
61
+ #
62
+ class MIME::Types
63
+ # The release version of Ruby MIME::Types
64
+ VERSION = MIME::Type::VERSION
65
+
66
+ include Enumerable
67
+
68
+ # The data version.
69
+ attr_reader :data_version
70
+
71
+ # Creates a new MIME::Types registry.
72
+ def initialize
73
+ @type_variants = Container.new
74
+ @extension_index = Container.new
75
+ @data_version = VERSION.dup.freeze
76
+ end
484
77
 
485
- # Returns +true+ if the MIME::Type specifies an extension list,
486
- # indicating that it is a complete MIME::Type.
487
- def complete?
488
- not @extensions.empty?
489
- end
78
+ def add_type_variant(mime_type) # :nodoc:
79
+ MIME.deprecated(self, __method__, :private)
80
+ add_type_variant!(mime_type)
81
+ end
490
82
 
491
- # Returns the MIME type as a string.
492
- def to_s
493
- @content_type
494
- end
83
+ def index_extensions(mime_type) # :nodoc:
84
+ MIME.deprecated(self, __method__, :private)
85
+ index_extensions!(mime_type)
86
+ end
495
87
 
496
- # Returns the MIME type as a string for implicit conversions.
497
- def to_str
498
- @content_type
499
- end
88
+ def defined_types # :nodoc:
89
+ MIME.deprecated(self, __method__)
90
+ @type_variants.values.flatten
91
+ end
500
92
 
501
- # Returns the MIME type as an array suitable for use with
502
- # MIME::Type.from_array.
503
- def to_a
504
- [ @content_type, @extensions, @encoding, @system, @obsolete, @docs,
505
- @url, registered? ]
506
- end
93
+ # Returns the number of known type variants.
94
+ def count
95
+ @type_variants.values.reduce(0) { |m, o| m + o.size }
96
+ end
507
97
 
508
- # Returns the MIME type as an array suitable for use with
509
- # MIME::Type.from_hash.
510
- def to_hash
511
- { 'Content-Type' => @content_type,
512
- 'Content-Transfer-Encoding' => @encoding,
513
- 'Extensions' => @extensions,
514
- 'System' => @system,
515
- 'Obsolete' => @obsolete,
516
- 'Docs' => @docs,
517
- 'URL' => @url,
518
- 'Registered' => registered?,
519
- }
520
- end
98
+ # Iterates through the type variants.
99
+ def each
100
+ @type_variants.values.each { |tv| tv.each { |t| yield t } }
521
101
  end
522
102
 
523
- # = MIME::Types
524
- # MIME types are used in MIME-compliant communications, as in e-mail or
525
- # HTTP traffic, to indicate the type of content which is transmitted.
526
- # MIME::Types provides the ability for detailed information about MIME
527
- # entities (provided as a set of MIME::Type objects) to be determined and
528
- # used programmatically. There are many types defined by RFCs and vendors,
529
- # so the list is long but not complete; don't hesitate to ask to add
530
- # additional information. This library follows the IANA collection of MIME
531
- # types (see below for reference).
103
+ @__types__ = nil
104
+
105
+ # Returns a list of MIME::Type objects, which may be empty. The optional
106
+ # flag parameters are <tt>:complete</tt> (finds only complete MIME::Type
107
+ # objects) and <tt>:registered</tt> (finds only MIME::Types that are
108
+ # registered). It is possible for multiple matches to be returned for
109
+ # either type (in the example below, 'text/plain' returns two values --
110
+ # one for the general case, and one for VMS systems).
532
111
  #
533
- # == Description
534
- # MIME types are used in MIME entities, as in email or HTTP traffic. It is
535
- # useful at times to have information available about MIME types (or,
536
- # inversely, about files). A MIME::Type stores the known information about
537
- # one MIME type.
112
+ # puts "\nMIME::Types['text/plain']"
113
+ # MIME::Types['text/plain'].each { |t| puts t.to_a.join(", ") }
538
114
  #
539
- # == Usage
540
- # require 'mime/types'
115
+ # puts "\nMIME::Types[/^image/, complete: true]"
116
+ # MIME::Types[/^image/, :complete => true].each do |t|
117
+ # puts t.to_a.join(", ")
118
+ # end
541
119
  #
542
- # plaintext = MIME::Types['text/plain']
543
- # print plaintext.media_type # => 'text'
544
- # print plaintext.sub_type # => 'plain'
120
+ # If multiple type definitions are returned, returns them sorted as
121
+ # follows:
122
+ # 1. Complete definitions sort before incomplete ones;
123
+ # 2. IANA-registered definitions sort before LTSW-recorded
124
+ # definitions.
125
+ # 3. Generic definitions sort before platform-specific ones;
126
+ # 4. Current definitions sort before obsolete ones;
127
+ # 5. Obsolete definitions with use-instead clauses sort before those
128
+ # without;
129
+ # 6. Obsolete definitions use-instead clauses are compared.
130
+ # 7. Sort on name.
545
131
  #
546
- # puts plaintext.extensions.join(" ") # => 'asc txt c cc h hh cpp'
132
+ # An additional flag of :platform (finds only MIME::Types for the current
133
+ # platform) is currently supported but deprecated.
134
+ def [](type_id, flags = {})
135
+ if flags[:platform]
136
+ MIME.deprecated(self, __method__, "using the :platform flag")
137
+ end
138
+
139
+ matches = case type_id
140
+ when MIME::Type
141
+ @type_variants[type_id.simplified]
142
+ when Regexp
143
+ match(type_id)
144
+ else
145
+ @type_variants[MIME::Type.simplified(type_id)]
146
+ end
147
+
148
+ prune_matches(matches, flags).sort { |a, b| a.priority_compare(b) }
149
+ end
150
+
151
+ # Return the list of MIME::Types which belongs to the file based on its
152
+ # filename extension. If there is no extension, the filename will be used
153
+ # as the matching criteria on its own.
547
154
  #
548
- # puts plaintext.encoding # => 8bit
549
- # puts plaintext.binary? # => false
550
- # puts plaintext.ascii? # => true
551
- # puts plaintext.obsolete? # => false
552
- # puts plaintext.registered? # => true
553
- # puts plaintext == 'text/plain' # => true
554
- # puts MIME::Type.simplified('x-appl/x-zip') # => 'appl/zip'
155
+ # This will always return a merged, flatten, priority sorted, unique array.
555
156
  #
556
- # This module is built to conform to the MIME types of RFCs 2045 and 2231.
557
- # It follows the official IANA registry at
558
- # http://www.iana.org/assignments/media-types/ and
559
- # ftp://ftp.iana.org/assignments/media-types with some unofficial types
560
- # added from the the collection at
561
- # http://www.ltsw.se/knbase/internet/mime.htp
562
- class Types
563
- # The released version of Ruby MIME::Types
564
- VERSION = MIME::Type::VERSION
565
- DATA_VERSION = (VERSION.to_f * 100).to_i
566
-
567
- # The data version.
568
- attr_reader :data_version
569
-
570
- class HashWithArrayDefault < Hash # :nodoc:
571
- def initialize
572
- super { |h, k| h[k] = [] }
573
- end
574
-
575
- def marshal_dump
576
- {}.merge(self)
577
- end
578
-
579
- def marshal_load(hash)
580
- self.merge!(hash)
581
- end
157
+ # puts MIME::Types.type_for('citydesk.xml')
158
+ # => [application/xml, text/xml]
159
+ # puts MIME::Types.type_for('citydesk.gif')
160
+ # => [image/gif]
161
+ # puts MIME::Types.type_for(%w(citydesk.xml citydesk.gif))
162
+ # => [application/xml, image/gif, text/xml]
163
+ #
164
+ # If +platform+ is +true+, then only file types that are specific to the
165
+ # current platform will be returned. This parameter has been deprecated.
166
+ def type_for(filename, platform = false)
167
+ types = [ filename ].flatten.map { |fn|
168
+ @extension_index[File.basename(fn.chomp.downcase).gsub(/.*\./o, '')]
169
+ }.flatten.sort { |a, b| a.priority_compare(b) }.uniq
170
+
171
+ if platform
172
+ MIME.deprecated(self, __method__,
173
+ "using the platform parameter")
174
+ types.select(&:platform?)
175
+ else
176
+ types
582
177
  end
178
+ end
179
+ alias_method :of, :type_for
583
180
 
584
- class CacheContainer # :nodoc:
585
- attr_reader :version, :data
586
- def initialize(version, data)
587
- @version, @data = version, data
181
+ # Add one or more MIME::Type objects to the set of known types. If the
182
+ # type is already known, a warning will be displayed.
183
+ #
184
+ # The last parameter may be the value <tt>:silent</tt> or +true+ which
185
+ # will suppress duplicate MIME type warnings.
186
+ def add(*types)
187
+ quiet = ((types.last == :silent) or (types.last == true))
188
+
189
+ types.each do |mime_type|
190
+ case mime_type
191
+ when true, false, nil, Symbol
192
+ nil
193
+ when MIME::Types
194
+ variants = mime_type.instance_variable_get(:@type_variants)
195
+ add(*variants.values.flatten, quiet)
196
+ when Array
197
+ add(*mime_type, quiet)
198
+ else
199
+ add_type(mime_type, quiet)
588
200
  end
589
201
  end
202
+ end
590
203
 
591
- def initialize(data_version = DATA_VERSION)
592
- @type_variants = HashWithArrayDefault.new
593
- @extension_index = HashWithArrayDefault.new
594
- @data_version = data_version
204
+ # Add a single MIME::Type object to the set of known types. If the type is
205
+ # already known, a warning will be displayed. The +quiet+ parameter may be
206
+ # a truthy value to suppress that warning.
207
+ def add_type(mime_type, quiet = false)
208
+ if !quiet and @type_variants[mime_type.simplified].include?(mime_type)
209
+ warn("Type %s is already registered as a variant of %s." % [
210
+ mime_type, mime_type.simplified ])
595
211
  end
596
212
 
597
- def add_type_variant(mime_type) #:nodoc:
598
- @type_variants[mime_type.simplified] << mime_type
599
- end
213
+ add_type_variant!(mime_type)
214
+ index_extensions!(mime_type)
215
+ end
216
+
217
+ class << self
218
+ include Enumerable
600
219
 
601
- def index_extensions(mime_type) #:nodoc:
602
- mime_type.extensions.each { |ext| @extension_index[ext] << mime_type }
220
+ # Load MIME::Types from a v1 file registry.
221
+ #
222
+ # This method has been deprecated.
223
+ def load_from_file(filename)
224
+ MIME.deprecated(self, __method__)
225
+ MIME::Types::Loader.load_from_v1(filename)
603
226
  end
604
227
 
605
- def defined_types #:nodoc:
606
- @type_variants.values.flatten
228
+ # MIME::Types#[] against the default MIME::Types registry.
229
+ def [](type_id, flags = {})
230
+ __types__[type_id, flags]
607
231
  end
608
232
 
609
- # Returns the number of known types. A shortcut of MIME::Types[//].size.
610
- # (Keep in mind that this is memory intensive, cache the result to spare
611
- # resources)
233
+ # MIME::Types#count against the default MIME::Types registry.
612
234
  def count
613
- defined_types.size
235
+ __types__.count
614
236
  end
615
237
 
238
+ # MIME::Types#each against the default MIME::Types registry.
616
239
  def each
617
- defined_types.each { |t| yield t }
240
+ __types__.each {|t| yield t }
618
241
  end
619
242
 
620
- @__types__ = nil
243
+ # MIME::Types#type_for against the default MIME::Types registry.
244
+ def type_for(filename, platform = false)
245
+ __types__.type_for(filename, platform)
246
+ end
247
+ alias_method :of, :type_for
621
248
 
622
- # Returns a list of MIME::Type objects, which may be empty. The optional
623
- # flag parameters are :complete (finds only complete MIME::Type objects)
624
- # and :platform (finds only MIME::Types for the current platform). It is
625
- # possible for multiple matches to be returned for either type (in the
626
- # example below, 'text/plain' returns two values -- one for the general
627
- # case, and one for VMS systems.
628
- #
629
- # puts "\nMIME::Types['text/plain']"
630
- # MIME::Types['text/plain'].each { |t| puts t.to_a.join(", ") }
631
- #
632
- # puts "\nMIME::Types[/^image/, :complete => true]"
633
- # MIME::Types[/^image/, :complete => true].each do |t|
634
- # puts t.to_a.join(", ")
635
- # end
636
- #
637
- # If multiple type definitions are returned, returns them sorted as
638
- # follows:
639
- # 1. Complete definitions sort before incomplete ones;
640
- # 2. IANA-registered definitions sort before LTSW-recorded
641
- # definitions.
642
- # 3. Generic definitions sort before platform-specific ones;
643
- # 4. Current definitions sort before obsolete ones;
644
- # 5. Obsolete definitions with use-instead clauses sort before those
645
- # without;
646
- # 6. Obsolete definitions use-instead clauses are compared.
647
- # 7. Sort on name.
648
- def [](type_id, flags = {})
649
- matches = case type_id
650
- when MIME::Type
651
- @type_variants[type_id.simplified]
652
- when Regexp
653
- match(type_id)
654
- else
655
- @type_variants[MIME::Type.simplified(type_id)]
656
- end
657
-
658
- prune_matches(matches, flags).sort { |a, b| a.priority_compare(b) }
249
+ # MIME::Types#add against the default MIME::Types registry.
250
+ def add(*types)
251
+ __types__.add(*types)
659
252
  end
660
253
 
661
- # Return the list of MIME::Types which belongs to the file based on its
662
- # filename extension. If +platform+ is +true+, then only file types that
663
- # are specific to the current platform will be returned.
664
- #
665
- # This will always return an array.
666
- #
667
- # puts "MIME::Types.type_for('citydesk.xml')
668
- # => [application/xml, text/xml]
669
- # puts "MIME::Types.type_for('citydesk.gif')
670
- # => [image/gif]
671
- def type_for(filename, platform = false)
672
- ext = filename.chomp.downcase.gsub(/.*\./o, '')
673
- list = @extension_index[ext]
674
- list.delete_if { |e| not e.platform? } if platform
675
- list
254
+ # Returns the currently defined cache file, if any.
255
+ def cache_file
256
+ MIME.deprecated(self, __method__)
257
+ ENV['RUBY_MIME_TYPES_CACHE']
676
258
  end
677
259
 
678
- # A synonym for MIME::Types.type_for
679
- def of(filename, platform = false)
680
- type_for(filename, platform)
260
+ def add_type_variant(mime_type) # :nodoc:
261
+ __types__.add_type_variant(mime_type)
681
262
  end
682
263
 
683
- # Add one or more MIME::Type objects to the set of known types. Each
684
- # type should be experimental (e.g., 'application/x-ruby'). If the type
685
- # is already known, a warning will be displayed.
686
- #
687
- # <strong>Please inform the maintainer of this module when registered
688
- # types are missing.</strong>
689
- def add(*types)
690
- types.each do |mime_type|
691
- if mime_type.kind_of? MIME::Types
692
- add(*mime_type.defined_types)
693
- else
694
- if @type_variants.include?(mime_type.simplified)
695
- if @type_variants[mime_type.simplified].include?(mime_type)
696
- warn "Type #{mime_type} already registered as a variant of #{mime_type.simplified}." unless defined? MIME::Types::LOAD
697
- end
698
- end
699
- add_type_variant(mime_type)
700
- index_extensions(mime_type)
701
- end
702
- end
264
+ def index_extensions(mime_type) # :nodoc:
265
+ __types__.index_extensions(mime_type)
703
266
  end
704
267
 
705
268
  private
706
- def prune_matches(matches, flags)
707
- matches.delete_if { |e| not e.complete? } if flags[:complete]
708
- matches.delete_if { |e| not e.platform? } if flags[:platform]
709
- matches
269
+ def lazy_load?
270
+ (lazy = ENV['RUBY_MIME_TYPES_LAZY_LOAD']) && (lazy != 'false')
710
271
  end
711
272
 
712
- def match(pattern)
713
- matches = @type_variants.select { |k, v| k =~ pattern }
714
- if matches.respond_to? :values
715
- matches.values.flatten
716
- else
717
- matches.map { |m| m.last }.flatten
718
- end
273
+ def __types__
274
+ (defined?(@__types__) and @__types__) or load_default_mime_types
719
275
  end
720
276
 
721
- class << self
722
- def add_type_variant(mime_type) #:nodoc:
723
- __types__.add_type_variant(mime_type)
724
- end
725
-
726
- def index_extensions(mime_type) #:nodoc:
727
- __types__.index_extensions(mime_type)
728
- end
729
-
730
- # The regular expression used to match a file-based MIME type
731
- # definition.
732
- TEXT_FORMAT_RE = %r{
733
- \A
734
- \s*
735
- ([*])? # 0: Unregistered?
736
- (!)? # 1: Obsolete?
737
- (?:(\w+):)? # 2: Platform marker
738
- #{MIME::Type::MEDIA_TYPE_RE}? # 3,4: Media type
739
- (?:\s+@([^\s]+))? # 5: Extensions
740
- (?:\s+:(#{MIME::Type::ENCODING_RE}))? # 6: Encoding
741
- (?:\s+'(.+))? # 7: URL list
742
- (?:\s+=(.+))? # 8: Documentation
743
- (?:\s*([#].*)?)?
744
- \s*
745
- \z
746
- }x
747
-
748
- # Build the type list from a file in the format:
749
- #
750
- # [*][!][os:]mt/st[<ws>@ext][<ws>:enc][<ws>'url-list][<ws>=docs]
751
- #
752
- # == *
753
- # An unofficial MIME type. This should be used if and only if the MIME type
754
- # is not properly specified (that is, not under either x-type or
755
- # vnd.name.type).
756
- #
757
- # == !
758
- # An obsolete MIME type. May be used with an unofficial MIME type.
759
- #
760
- # == os:
761
- # Platform-specific MIME type definition.
762
- #
763
- # == mt
764
- # The media type.
765
- #
766
- # == st
767
- # The media subtype.
768
- #
769
- # == <ws>@ext
770
- # The list of comma-separated extensions.
771
- #
772
- # == <ws>:enc
773
- # The encoding.
774
- #
775
- # == <ws>'url-list
776
- # The list of comma-separated URLs.
777
- #
778
- # == <ws>=docs
779
- # The documentation string.
780
- #
781
- # That is, everything except the media type and the subtype is optional. The
782
- # more information that's available, though, the richer the values that can
783
- # be provided.
784
- def load_from_file(filename) #:nodoc:
785
- if defined? ::Encoding
786
- data = File.open(filename, 'r:UTF-8:-') { |f| f.read }
787
- else
788
- data = File.open(filename) { |f| f.read }
789
- end
790
- data = data.split($/)
791
- mime = MIME::Types.new
792
- data.each_with_index { |line, index|
793
- item = line.chomp.strip
794
- next if item.empty?
795
-
796
- begin
797
- m = TEXT_FORMAT_RE.match(item).captures
798
- rescue Exception
799
- puts "#{filename}:#{index}: Parsing error in MIME type definitions."
800
- puts "=> #{line}"
801
- raise
802
- end
803
-
804
- unregistered, obsolete, platform, mediatype, subtype, extensions,
805
- encoding, urls, docs, comment = *m
806
-
807
- if mediatype.nil?
808
- if comment.nil?
809
- puts "#{filename}:#{index}: Parsing error in MIME type definitions."
810
- puts "=> #{line}"
811
- raise RuntimeError
812
- end
813
-
814
- next
815
- end
816
-
817
- extensions &&= extensions.split(/,/)
818
- urls &&= urls.split(/,/)
819
-
820
- mime_type = MIME::Type.new("#{mediatype}/#{subtype}") do |t|
821
- t.extensions = extensions
822
- t.encoding = encoding
823
- t.system = platform
824
- t.obsolete = obsolete
825
- t.registered = false if unregistered
826
- t.docs = docs
827
- t.url = urls
828
- end
829
-
830
- mime.add(mime_type)
831
- }
832
- mime
833
- end
834
-
835
- # Returns a list of MIME::Type objects, which may be empty. The
836
- # optional flag parameters are :complete (finds only complete
837
- # MIME::Type objects) and :platform (finds only MIME::Types for the
838
- # current platform). It is possible for multiple matches to be
839
- # returned for either type (in the example below, 'text/plain' returns
840
- # two values -- one for the general case, and one for VMS systems.
841
- #
842
- # puts "\nMIME::Types['text/plain']"
843
- # MIME::Types['text/plain'].each { |t| puts t.to_a.join(", ") }
844
- #
845
- # puts "\nMIME::Types[/^image/, :complete => true]"
846
- # MIME::Types[/^image/, :complete => true].each do |t|
847
- # puts t.to_a.join(", ")
848
- # end
849
- def [](type_id, flags = {})
850
- __types__[type_id, flags]
851
- end
852
-
853
- include Enumerable
854
-
855
- def count
856
- __types__.count
857
- end
858
-
859
- def each
860
- __types__.each {|t| yield t }
861
- end
862
-
863
- # Return the list of MIME::Types which belongs to the file based on
864
- # its filename extension. If +platform+ is +true+, then only file
865
- # types that are specific to the current platform will be returned.
866
- #
867
- # This will always return an array.
868
- #
869
- # puts "MIME::Types.type_for('citydesk.xml')
870
- # => [application/xml, text/xml]
871
- # puts "MIME::Types.type_for('citydesk.gif')
872
- # => [image/gif]
873
- def type_for(filename, platform = false)
874
- __types__.type_for(filename, platform)
875
- end
876
-
877
- # A synonym for MIME::Types.type_for
878
- def of(filename, platform = false)
879
- __types__.type_for(filename, platform)
880
- end
881
-
882
- # Add one or more MIME::Type objects to the set of known types. Each
883
- # type should be experimental (e.g., 'application/x-ruby'). If the
884
- # type is already known, a warning will be displayed.
885
- #
886
- # <strong>Please inform the maintainer of this module when registered
887
- # types are missing.</strong>
888
- def add(*types)
889
- __types__.add(*types)
890
- end
891
-
892
- # Returns the currently defined cache file, if any.
893
- def cache_file
894
- ENV['RUBY_MIME_TYPES_CACHE']
895
- end
896
-
897
- private
898
- def load_mime_types_from_cache
899
- load_mime_types_from_cache! if cache_file
900
- end
901
-
902
- def load_mime_types_from_cache!
903
- raise ArgumentError, "No RUBY_MIME_TYPES_CACHE set." unless cache_file
904
- return false unless File.exists? cache_file
905
-
906
- begin
907
- data = File.read(cache_file)
908
- container = Marshal.load(data)
909
-
910
- if container.version == VERSION
911
- @__types__ = Marshal.load(container.data)
912
- true
913
- else
914
- false
915
- end
916
- rescue => e
917
- warn "Could not load MIME::Types cache: #{e}"
918
- false
919
- end
920
- end
921
-
922
- def write_mime_types_to_cache
923
- write_mime_types_to_cache! if cache_file
924
- end
925
-
926
- def write_mime_types_to_cache!
927
- raise ArgumentError, "No RUBY_MIME_TYPES_CACHE set." unless cache_file
928
-
929
- File.open(cache_file, 'w') do |f|
930
- cache = MIME::Types::CacheContainer.new(VERSION,
931
- Marshal.dump(__types__))
932
- f.write Marshal.dump(cache)
933
- end
934
-
935
- true
936
- end
937
-
938
- def load_and_parse_mime_types
939
- const_set(:LOAD, true) unless $DEBUG
940
- Dir[File.join(File.dirname(__FILE__), 'types', '*')].sort.each { |f|
941
- add(load_from_file(f))
942
- }
943
- remove_const :LOAD if defined? LOAD
277
+ def load_default_mime_types
278
+ @__types__ = MIME::Types::Cache.load
279
+ unless @__types__
280
+ @__types__ = MIME::Types::Loader.load
281
+ MIME::Types::Cache.save(@__types__)
944
282
  end
283
+ @__types__
284
+ end
285
+ end
945
286
 
946
- def lazy_load?
947
- (lazy = ENV['RUBY_MIME_TYPES_LAZY_LOAD']) && (lazy != 'false')
948
- end
287
+ private
288
+ def add_type_variant!(mime_type)
289
+ @type_variants[mime_type.simplified] << mime_type
290
+ end
949
291
 
950
- def __types__
951
- load_mime_types unless @__types__
952
- @__types__
953
- end
292
+ def index_extensions!(mime_type)
293
+ mime_type.extensions.each { |ext| @extension_index[ext] << mime_type }
294
+ end
954
295
 
955
- def load_mime_types
956
- @__types__ = new(VERSION)
957
- unless load_mime_types_from_cache
958
- load_and_parse_mime_types
959
- write_mime_types_to_cache
960
- end
961
- end
962
- end
296
+ def prune_matches(matches, flags)
297
+ matches.delete_if { |e| not e.complete? } if flags[:complete]
298
+ matches.delete_if { |e| not e.platform? } if flags[:platform]
299
+ matches.delete_if { |e| not e.registered? } if flags[:registered]
300
+ matches
301
+ end
963
302
 
964
- load_mime_types unless lazy_load?
303
+ def match(pattern)
304
+ @type_variants.select { |k, v| k =~ pattern }.values.flatten
965
305
  end
306
+
307
+ load_default_mime_types unless lazy_load?
966
308
  end
967
309
 
968
310
  # vim: ft=ruby