mime-types 2.99.3 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/{Code-of-Conduct.rdoc → Code-of-Conduct.md} +19 -20
- data/Contributing.md +143 -0
- data/History.md +240 -0
- data/{Licence.rdoc → Licence.md} +4 -18
- data/Manifest.txt +8 -25
- data/README.rdoc +62 -73
- data/Rakefile +175 -58
- data/lib/mime-types.rb +1 -1
- data/lib/mime/type.rb +213 -424
- data/lib/mime/type/columnar.rb +29 -62
- data/lib/mime/types.rb +46 -141
- data/lib/mime/types/_columnar.rb +136 -0
- data/lib/mime/types/cache.rb +51 -73
- data/lib/mime/types/columnar.rb +2 -147
- data/lib/mime/types/container.rb +96 -0
- data/lib/mime/types/deprecations.rb +4 -25
- data/lib/mime/types/full.rb +19 -0
- data/lib/mime/types/loader.rb +12 -141
- data/lib/mime/types/logger.rb +5 -1
- data/lib/mime/types/registry.rb +90 -0
- data/test/minitest_helper.rb +5 -13
- data/test/test_mime_type.rb +470 -456
- data/test/test_mime_types.rb +135 -87
- data/test/test_mime_types_cache.rb +82 -54
- data/test/test_mime_types_class.rb +118 -98
- data/test/test_mime_types_lazy.rb +26 -24
- data/test/test_mime_types_loader.rb +6 -33
- metadata +107 -64
- data/Contributing.rdoc +0 -170
- data/History-Types.rdoc +0 -454
- data/History.rdoc +0 -590
- data/data/mime-types.json +0 -1
- data/data/mime.content_type.column +0 -1980
- data/data/mime.docs.column +0 -1980
- data/data/mime.encoding.column +0 -1980
- data/data/mime.friendly.column +0 -1980
- data/data/mime.obsolete.column +0 -1980
- data/data/mime.registered.column +0 -1980
- data/data/mime.signature.column +0 -1980
- data/data/mime.use_instead.column +0 -1980
- data/data/mime.xrefs.column +0 -1980
- data/docs/COPYING.txt +0 -339
- data/docs/artistic.txt +0 -127
- data/lib/mime/types/loader_path.rb +0 -15
- data/support/apache_mime_types.rb +0 -108
- data/support/benchmarks/load.rb +0 -64
- data/support/benchmarks/load_allocations.rb +0 -83
- data/support/benchmarks/object_counts.rb +0 -41
- data/support/convert.rb +0 -158
- data/support/convert/columnar.rb +0 -88
- data/support/iana_registry.rb +0 -172
data/lib/mime-types.rb
CHANGED
data/lib/mime/type.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
##
|
4
|
+
module MIME
|
5
|
+
end
|
2
6
|
|
3
7
|
# The definition of one MIME content-type.
|
4
8
|
#
|
@@ -53,33 +57,21 @@ class MIME::Type
|
|
53
57
|
end
|
54
58
|
|
55
59
|
# The released version of the mime-types library.
|
56
|
-
VERSION = '
|
60
|
+
VERSION = '3.3.1'
|
57
61
|
|
58
62
|
include Comparable
|
59
63
|
|
60
64
|
# :stopdoc:
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
BINARY_ENCODINGS = %w(base64 8bit)
|
68
|
-
TEXT_ENCODINGS = %w(7bit quoted-printable)
|
69
|
-
VALID_ENCODINGS = DEFAULT_ENCODINGS + BINARY_ENCODINGS + TEXT_ENCODINGS
|
70
|
-
|
71
|
-
IANA_URL = 'http://www.iana.org/assignments/media-types/%s/%s'
|
72
|
-
RFC_URL = 'http://rfc-editor.org/rfc/rfc%s.txt'
|
73
|
-
DRAFT_URL = 'http://datatracker.ietf.org/public/idindex.cgi?command=id_details&filename=%s' # rubocop:disable Metrics/LineLength
|
74
|
-
CONTACT_URL = 'http://www.iana.org/assignments/contact-people.htm#%s'
|
65
|
+
# TODO verify mime-type character restrictions; I am pretty sure that this is
|
66
|
+
# too wide open.
|
67
|
+
MEDIA_TYPE_RE = %r{([-\w.+]+)/([-\w.+]*)}.freeze
|
68
|
+
I18N_RE = /[^[:alnum:]]/.freeze
|
69
|
+
BINARY_ENCODINGS = %w(base64 8bit).freeze
|
70
|
+
ASCII_ENCODINGS = %w(7bit quoted-printable).freeze
|
75
71
|
# :startdoc:
|
76
72
|
|
77
|
-
|
78
|
-
|
79
|
-
:DEFAULT_ENCODINGS, :BINARY_ENCODINGS, :TEXT_ENCODINGS,
|
80
|
-
:VALID_ENCODINGS, :IANA_URL, :RFC_URL, :DRAFT_URL,
|
81
|
-
:CONTACT_URL
|
82
|
-
end
|
73
|
+
private_constant :MEDIA_TYPE_RE, :I18N_RE, :BINARY_ENCODINGS,
|
74
|
+
:ASCII_ENCODINGS
|
83
75
|
|
84
76
|
# Builds a MIME::Type object from the +content_type+, a MIME Content Type
|
85
77
|
# value (e.g., 'text/plain' or 'applicaton/x-eruby'). The constructed object
|
@@ -88,46 +80,45 @@ class MIME::Type
|
|
88
80
|
#
|
89
81
|
# * When provided a Hash or a MIME::Type, the MIME::Type will be
|
90
82
|
# constructed with #init_with.
|
91
|
-
# * When provided an Array, the MIME::Type will be constructed
|
92
|
-
# the first
|
93
|
-
# extensions.
|
83
|
+
# * When provided an Array, the MIME::Type will be constructed using
|
84
|
+
# the first element as the content type and the remaining flattened
|
85
|
+
# elements as extensions.
|
94
86
|
# * Otherwise, the content_type will be used as a string.
|
95
87
|
#
|
96
88
|
# Yields the newly constructed +self+ object.
|
97
89
|
def initialize(content_type) # :yields self:
|
98
90
|
@friendly = {}
|
99
|
-
|
100
|
-
|
101
|
-
self.
|
102
|
-
self.signature = nil
|
91
|
+
@obsolete = @registered = false
|
92
|
+
@preferred_extension = @docs = @use_instead = nil
|
93
|
+
self.extensions = []
|
103
94
|
|
104
95
|
case content_type
|
105
96
|
when Hash
|
106
97
|
init_with(content_type)
|
107
98
|
when Array
|
108
|
-
self.content_type = content_type
|
109
|
-
self.extensions = content_type
|
99
|
+
self.content_type = content_type.shift
|
100
|
+
self.extensions = content_type.flatten
|
110
101
|
when MIME::Type
|
111
102
|
init_with(content_type.to_h)
|
112
103
|
else
|
113
104
|
self.content_type = content_type
|
114
105
|
end
|
115
106
|
|
116
|
-
self.extensions ||= []
|
117
|
-
self.docs ||= []
|
118
107
|
self.encoding ||= :default
|
119
108
|
self.xrefs ||= {}
|
120
109
|
|
121
110
|
yield self if block_given?
|
122
111
|
end
|
123
112
|
|
124
|
-
#
|
113
|
+
# Indicates that a MIME type is like another type. This differs from
|
114
|
+
# <tt>==</tt> because <tt>x-</tt> prefixes are removed for this comparison.
|
125
115
|
def like?(other)
|
126
|
-
if other.respond_to?(:simplified)
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
116
|
+
other = if other.respond_to?(:simplified)
|
117
|
+
MIME::Type.simplified(other.simplified, remove_x_prefix: true)
|
118
|
+
else
|
119
|
+
MIME::Type.simplified(other.to_s, remove_x_prefix: true)
|
120
|
+
end
|
121
|
+
MIME::Type.simplified(simplified, remove_x_prefix: true) == other
|
131
122
|
end
|
132
123
|
|
133
124
|
# Compares the +other+ MIME::Type against the exact content type or the
|
@@ -135,10 +126,16 @@ class MIME::Type
|
|
135
126
|
# something that can be treated as a String with #to_s). In comparisons, this
|
136
127
|
# is done against the lowercase version of the MIME::Type.
|
137
128
|
def <=>(other)
|
138
|
-
if other.
|
139
|
-
|
140
|
-
elsif other.respond_to?(:
|
141
|
-
|
129
|
+
if other.nil?
|
130
|
+
-1
|
131
|
+
elsif other.respond_to?(:simplified)
|
132
|
+
simplified <=> other.simplified
|
133
|
+
else
|
134
|
+
filtered = 'silent' if other == :silent
|
135
|
+
filtered ||= 'true' if other == true
|
136
|
+
filtered ||= other.to_s
|
137
|
+
|
138
|
+
simplified <=> MIME::Type.simplified(filtered)
|
142
139
|
end
|
143
140
|
end
|
144
141
|
|
@@ -160,7 +157,7 @@ class MIME::Type
|
|
160
157
|
# before unregistered or obsolete content types.
|
161
158
|
def priority_compare(other)
|
162
159
|
pc = simplified <=> other.simplified
|
163
|
-
if pc.zero?
|
160
|
+
if pc.zero? || !(extensions & other.extensions).empty?
|
164
161
|
pc = if (reg = registered?) != other.registered?
|
165
162
|
reg ? -1 : 1 # registered < unregistered
|
166
163
|
elsif (comp = complete?) != other.complete?
|
@@ -204,54 +201,74 @@ class MIME::Type
|
|
204
201
|
# removed and converted to lowercase.
|
205
202
|
#
|
206
203
|
# text/plain => text/plain
|
207
|
-
# x-chemical/x-pdb => chemical/pdb
|
204
|
+
# x-chemical/x-pdb => x-chemical/x-pdb
|
208
205
|
# audio/QCELP => audio/qcelp
|
209
206
|
attr_reader :simplified
|
210
207
|
# Returns the media type of the simplified MIME::Type.
|
211
208
|
#
|
212
209
|
# text/plain => text
|
213
|
-
# x-chemical/x-pdb => chemical
|
210
|
+
# x-chemical/x-pdb => x-chemical
|
211
|
+
# audio/QCELP => audio
|
214
212
|
attr_reader :media_type
|
215
213
|
# Returns the media type of the unmodified MIME::Type.
|
216
214
|
#
|
217
215
|
# text/plain => text
|
218
216
|
# x-chemical/x-pdb => x-chemical
|
217
|
+
# audio/QCELP => audio
|
219
218
|
attr_reader :raw_media_type
|
220
219
|
# Returns the sub-type of the simplified MIME::Type.
|
221
220
|
#
|
222
221
|
# text/plain => plain
|
223
222
|
# x-chemical/x-pdb => pdb
|
223
|
+
# audio/QCELP => QCELP
|
224
224
|
attr_reader :sub_type
|
225
225
|
# Returns the media type of the unmodified MIME::Type.
|
226
226
|
#
|
227
227
|
# text/plain => plain
|
228
228
|
# x-chemical/x-pdb => x-pdb
|
229
|
+
# audio/QCELP => qcelp
|
229
230
|
attr_reader :raw_sub_type
|
230
231
|
|
232
|
+
##
|
231
233
|
# The list of extensions which are known to be used for this MIME::Type.
|
232
234
|
# Non-array values will be coerced into an array with #to_a. Array values
|
233
235
|
# will be flattened, +nil+ values removed, and made unique.
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
236
|
+
#
|
237
|
+
# :attr_accessor: extensions
|
238
|
+
def extensions
|
239
|
+
@extensions.to_a
|
240
|
+
end
|
241
|
+
|
242
|
+
##
|
243
|
+
def extensions=(value) # :nodoc:
|
244
|
+
@extensions = Set[*Array(value).flatten.compact].freeze
|
245
|
+
MIME::Types.send(:reindex_extensions, self)
|
239
246
|
end
|
240
247
|
|
241
248
|
# Merge the +extensions+ provided into this MIME::Type. The extensions added
|
242
249
|
# will be merged uniquely.
|
243
250
|
def add_extensions(*extensions)
|
244
|
-
self.extensions
|
251
|
+
self.extensions += extensions
|
245
252
|
end
|
246
253
|
|
247
254
|
##
|
248
|
-
# The preferred extension for this MIME type
|
255
|
+
# The preferred extension for this MIME type. If one is not set and there are
|
256
|
+
# exceptions defined, the first extension will be used.
|
249
257
|
#
|
250
|
-
#
|
258
|
+
# When setting #preferred_extensions, if #extensions does not contain this
|
259
|
+
# extension, this will be added to #xtensions.
|
260
|
+
#
|
261
|
+
# :attr_accessor: preferred_extension
|
251
262
|
|
252
263
|
##
|
253
264
|
def preferred_extension
|
254
|
-
extensions.first
|
265
|
+
@preferred_extension || extensions.first
|
266
|
+
end
|
267
|
+
|
268
|
+
##
|
269
|
+
def preferred_extension=(value) # :nodoc:
|
270
|
+
add_extensions(value) if value
|
271
|
+
@preferred_extension = value
|
255
272
|
end
|
256
273
|
|
257
274
|
##
|
@@ -270,60 +287,41 @@ class MIME::Type
|
|
270
287
|
|
271
288
|
##
|
272
289
|
attr_reader :encoding
|
290
|
+
|
291
|
+
##
|
273
292
|
def encoding=(enc) # :nodoc:
|
274
|
-
if
|
293
|
+
if enc.nil? or enc == :default
|
275
294
|
@encoding = default_encoding
|
276
|
-
elsif BINARY_ENCODINGS.include?(enc) or
|
295
|
+
elsif BINARY_ENCODINGS.include?(enc) or ASCII_ENCODINGS.include?(enc)
|
277
296
|
@encoding = enc
|
278
297
|
else
|
279
298
|
fail InvalidEncoding, enc
|
280
299
|
end
|
281
300
|
end
|
282
301
|
|
283
|
-
# Returns +nil+ and assignments are ignored. Prior to mime-types 2.99, this
|
284
|
-
# would return the regular expression for the operating system indicated if
|
285
|
-
# the MIME::Type is a system-specific MIME::Type,
|
286
|
-
#
|
287
|
-
# This information about MIME content types is deprecated and will be removed
|
288
|
-
# in mime-types 3.
|
289
|
-
def system
|
290
|
-
MIME::Types.deprecated(self, __method__)
|
291
|
-
nil
|
292
|
-
end
|
293
|
-
|
294
|
-
def system=(_os) # :nodoc:
|
295
|
-
MIME::Types.deprecated(self, __method__)
|
296
|
-
end
|
297
|
-
|
298
302
|
# Returns the default encoding for the MIME::Type based on the media type.
|
299
303
|
def default_encoding
|
300
|
-
|
304
|
+
@media_type == 'text' ? 'quoted-printable' : 'base64'
|
301
305
|
end
|
302
306
|
|
303
307
|
##
|
304
|
-
# Returns the media type or types that should be used instead of this
|
305
|
-
#
|
306
|
-
#
|
308
|
+
# Returns the media type or types that should be used instead of this media
|
309
|
+
# type, if it is obsolete. If there is no replacement media type, or it is
|
310
|
+
# not obsolete, +nil+ will be returned.
|
307
311
|
#
|
308
312
|
# :attr_accessor: use_instead
|
309
313
|
|
310
314
|
##
|
311
315
|
def use_instead
|
312
|
-
|
313
|
-
@use_instead
|
316
|
+
obsolete? ? @use_instead : nil
|
314
317
|
end
|
315
318
|
|
316
319
|
##
|
317
320
|
attr_writer :use_instead
|
318
321
|
|
319
322
|
# Returns +true+ if the media type is obsolete.
|
320
|
-
|
321
|
-
|
322
|
-
end
|
323
|
-
|
324
|
-
def obsolete=(v) # :nodoc:
|
325
|
-
@obsolete = !!v
|
326
|
-
end
|
323
|
+
attr_accessor :obsolete
|
324
|
+
alias obsolete? obsolete
|
327
325
|
|
328
326
|
# The documentation for this MIME::Type.
|
329
327
|
attr_accessor :docs
|
@@ -333,18 +331,19 @@ class MIME::Type
|
|
333
331
|
# call-seq:
|
334
332
|
# text_plain.friendly # => "Text File"
|
335
333
|
# text_plain.friendly('en') # => "Text File"
|
336
|
-
def friendly(lang = 'en'
|
334
|
+
def friendly(lang = 'en')
|
337
335
|
@friendly ||= {}
|
338
336
|
|
339
337
|
case lang
|
340
|
-
when String
|
341
|
-
@friendly[lang]
|
338
|
+
when String, Symbol
|
339
|
+
@friendly[lang.to_s]
|
342
340
|
when Array
|
343
|
-
@friendly.
|
341
|
+
@friendly.update(Hash[*lang])
|
344
342
|
when Hash
|
345
|
-
@friendly.
|
343
|
+
@friendly.update(lang)
|
346
344
|
else
|
347
|
-
fail ArgumentError
|
345
|
+
fail ArgumentError,
|
346
|
+
"Expected a language or translation set, not #{lang.inspect}"
|
348
347
|
end
|
349
348
|
end
|
350
349
|
|
@@ -359,50 +358,6 @@ class MIME::Type
|
|
359
358
|
# # from application/x-msword
|
360
359
|
attr_reader :i18n_key
|
361
360
|
|
362
|
-
##
|
363
|
-
# Returns an empty array and warns that this method has been deprecated.
|
364
|
-
# Assignments are ignored. Prior to mime-types 2.99, this was the encoded
|
365
|
-
# references URL list for this MIME::Type.
|
366
|
-
#
|
367
|
-
# This was previously called #url.
|
368
|
-
#
|
369
|
-
# #references has been deprecated and both versions (#references and #url)
|
370
|
-
# will be removed in mime-types 3.
|
371
|
-
#
|
372
|
-
# :attr_accessor: references
|
373
|
-
|
374
|
-
##
|
375
|
-
def references(*)
|
376
|
-
MIME::Types.deprecated(self, __method__)
|
377
|
-
[]
|
378
|
-
end
|
379
|
-
|
380
|
-
##
|
381
|
-
def references=(_r) # :nodoc:
|
382
|
-
MIME::Types.deprecated(self, __method__)
|
383
|
-
end
|
384
|
-
|
385
|
-
##
|
386
|
-
# Returns an empty array and warns that this method has been deprecated.
|
387
|
-
# Assignments are ignored. Prior to mime-types 2.99, this was the encoded
|
388
|
-
# references URL list for this MIME::Type. See #urls for more information.
|
389
|
-
#
|
390
|
-
# #url has been deprecated and both versions (#references and #url) will be
|
391
|
-
# removed in mime-types 3.
|
392
|
-
#
|
393
|
-
# :attr_accessor: url
|
394
|
-
|
395
|
-
##
|
396
|
-
def url
|
397
|
-
MIME::Types.deprecated(self, __method__)
|
398
|
-
[]
|
399
|
-
end
|
400
|
-
|
401
|
-
##
|
402
|
-
def url=(_r) # :nodoc:
|
403
|
-
MIME::Types.deprecated(self, __method__)
|
404
|
-
end
|
405
|
-
|
406
361
|
##
|
407
362
|
# The cross-references list for this MIME::Type.
|
408
363
|
#
|
@@ -412,134 +367,39 @@ class MIME::Type
|
|
412
367
|
attr_reader :xrefs
|
413
368
|
|
414
369
|
##
|
415
|
-
def xrefs=(
|
416
|
-
@xrefs = MIME::Types::Container.new
|
417
|
-
@xrefs.each_value(&:sort!)
|
418
|
-
@xrefs.each_value(&:uniq!)
|
419
|
-
end
|
420
|
-
|
421
|
-
# Returns an empty array. Prior to mime-types 2.99, this returned the decoded
|
422
|
-
# URL list for this MIME::Type.
|
423
|
-
#
|
424
|
-
# The special URL value IANA was translated into:
|
425
|
-
# http://www.iana.org/assignments/media-types/<mediatype>/<subtype>
|
426
|
-
#
|
427
|
-
# The special URL value RFC### was translated into:
|
428
|
-
# http://www.rfc-editor.org/rfc/rfc###.txt
|
429
|
-
#
|
430
|
-
# The special URL value DRAFT:name was translated into:
|
431
|
-
# https://datatracker.ietf.org/public/idindex.cgi?
|
432
|
-
# command=id_detail&filename=<name>
|
433
|
-
#
|
434
|
-
# The special URL value [token] was translated into:
|
435
|
-
# http://www.iana.org/assignments/contact-people.htm#<token>
|
436
|
-
#
|
437
|
-
# These values were accessible through #urls, which always returns an array.
|
438
|
-
#
|
439
|
-
# This method is deprecated and will be removed in mime-types 3.
|
440
|
-
def urls
|
441
|
-
MIME::Types.deprecated(self, __method__)
|
442
|
-
[]
|
370
|
+
def xrefs=(xrefs) # :nodoc:
|
371
|
+
@xrefs = MIME::Types::Container.new(xrefs)
|
443
372
|
end
|
444
373
|
|
445
374
|
# The decoded cross-reference URL list for this MIME::Type.
|
446
375
|
def xref_urls
|
447
|
-
xrefs.flat_map { |
|
448
|
-
|
449
|
-
|
450
|
-
values.map { |data| 'http://www.iana.org/go/%s'.freeze % data }
|
451
|
-
when 'draft'.freeze
|
452
|
-
values.map { |data|
|
453
|
-
'http://www.iana.org/go/%s'.freeze % data.sub(/\ARFC/, 'draft')
|
454
|
-
}
|
455
|
-
when 'rfc-errata'.freeze
|
456
|
-
values.map { |data|
|
457
|
-
'http://www.rfc-editor.org/errata_search.php?eid=%s'.freeze % data
|
458
|
-
}
|
459
|
-
when 'person'.freeze
|
460
|
-
values.map { |data|
|
461
|
-
'http://www.iana.org/assignments/media-types/media-types.xhtml#%s'.freeze % data # rubocop:disable Metrics/LineLength
|
462
|
-
}
|
463
|
-
when 'template'.freeze
|
464
|
-
values.map { |data|
|
465
|
-
'http://www.iana.org/assignments/media-types/%s'.freeze % data
|
466
|
-
}
|
467
|
-
else # 'uri', 'text', etc.
|
468
|
-
values
|
469
|
-
end
|
376
|
+
xrefs.flat_map { |type, values|
|
377
|
+
name = :"xref_url_for_#{type.tr('-', '_')}"
|
378
|
+
respond_to?(name, true) and xref_map(values, name) or values.to_a
|
470
379
|
}
|
471
380
|
end
|
472
381
|
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
# assumption is no longer being made by default in this library.
|
477
|
-
#
|
478
|
-
# There are three possible registration states for a MIME::Type:
|
479
|
-
# - Explicitly registered, like application/x-www-url-encoded.
|
480
|
-
# - Explicitly not registered, like image/webp.
|
481
|
-
# - Unspecified, in which case the media-type and the content-type will be
|
482
|
-
# scanned to see if they start with <tt>x-</tt>, indicating that they
|
483
|
-
# are assumed unregistered.
|
484
|
-
#
|
485
|
-
# In mime-types 3, only a MIME content type that is explicitly registered
|
486
|
-
# will be used; there will be assumption that <tt>x-</tt> types are
|
487
|
-
# unregistered.
|
488
|
-
def registered?
|
489
|
-
if @registered.nil?
|
490
|
-
(@raw_media_type !~ UNREGISTERED_RE) and
|
491
|
-
(@raw_sub_type !~ UNREGISTERED_RE)
|
492
|
-
else
|
493
|
-
!!@registered
|
494
|
-
end
|
495
|
-
end
|
496
|
-
|
497
|
-
def registered=(v) # :nodoc:
|
498
|
-
@registered = v.nil? ? v : !!v
|
499
|
-
end
|
382
|
+
# Indicates whether the MIME type has been registered with IANA.
|
383
|
+
attr_accessor :registered
|
384
|
+
alias registered? registered
|
500
385
|
|
501
386
|
# MIME types can be specified to be sent across a network in particular
|
502
387
|
# formats. This method returns +true+ when the MIME::Type encoding is set
|
503
388
|
# to <tt>base64</tt>.
|
504
389
|
def binary?
|
505
|
-
BINARY_ENCODINGS.include?(
|
390
|
+
BINARY_ENCODINGS.include?(encoding)
|
506
391
|
end
|
507
392
|
|
508
393
|
# MIME types can be specified to be sent across a network in particular
|
509
394
|
# formats. This method returns +false+ when the MIME::Type encoding is
|
510
395
|
# set to <tt>base64</tt>.
|
511
396
|
def ascii?
|
512
|
-
|
513
|
-
end
|
514
|
-
|
515
|
-
# Returns +true+ when the simplified MIME::Type is one of the known digital
|
516
|
-
# signature types.
|
517
|
-
def signature?
|
518
|
-
!!@signature
|
397
|
+
ASCII_ENCODINGS.include?(encoding)
|
519
398
|
end
|
520
399
|
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
# Returns +false+. Prior to mime-types 2.99, would return +true+ if the
|
526
|
-
# MIME::Type is specific to an operating system.
|
527
|
-
#
|
528
|
-
# This method is deprecated and will be removed in mime-types 3.
|
529
|
-
def system?(*)
|
530
|
-
MIME::Types.deprecated(self, __method__)
|
531
|
-
false
|
532
|
-
end
|
533
|
-
|
534
|
-
# Returns +false+. Prior to mime-types 2.99, would return +true+ if the
|
535
|
-
# MIME::Type is specific to the current operating system as represented by
|
536
|
-
# RUBY_PLATFORM.
|
537
|
-
#
|
538
|
-
# This method is deprecated and will be removed in mime-types 3.
|
539
|
-
def platform?(*)
|
540
|
-
MIME::Types.deprecated(self, __method__)
|
541
|
-
false
|
542
|
-
end
|
400
|
+
# Indicateswhether the MIME type is declared as a signature type.
|
401
|
+
attr_accessor :signature
|
402
|
+
alias signature? signature
|
543
403
|
|
544
404
|
# Returns +true+ if the MIME::Type specifies an extension list,
|
545
405
|
# indicating that it is a complete MIME::Type.
|
@@ -560,41 +420,14 @@ class MIME::Type
|
|
560
420
|
content_type
|
561
421
|
end
|
562
422
|
|
563
|
-
# Returns the MIME::Type as an array suitable for use with
|
564
|
-
# MIME::Type.from_array.
|
565
|
-
#
|
566
|
-
# This method is deprecated and will be removed in mime-types 3.
|
567
|
-
def to_a
|
568
|
-
MIME::Types.deprecated(self, __method__)
|
569
|
-
[ @content_type, @extensions, @encoding, nil, obsolete?, @docs, [],
|
570
|
-
registered? ]
|
571
|
-
end
|
572
|
-
|
573
|
-
# Returns the MIME::Type as an array suitable for use with
|
574
|
-
# MIME::Type.from_hash.
|
575
|
-
#
|
576
|
-
# This method is deprecated and will be removed in mime-types 3.
|
577
|
-
def to_hash
|
578
|
-
MIME::Types.deprecated(self, __method__)
|
579
|
-
{ 'Content-Type' => @content_type,
|
580
|
-
'Content-Transfer-Encoding' => @encoding,
|
581
|
-
'Extensions' => @extensions,
|
582
|
-
'System' => nil,
|
583
|
-
'Obsolete' => obsolete?,
|
584
|
-
'Docs' => @docs,
|
585
|
-
'URL' => [],
|
586
|
-
'Registered' => registered?,
|
587
|
-
}
|
588
|
-
end
|
589
|
-
|
590
423
|
# Converts the MIME::Type to a JSON string.
|
591
424
|
def to_json(*args)
|
592
425
|
require 'json'
|
593
426
|
to_h.to_json(*args)
|
594
427
|
end
|
595
428
|
|
596
|
-
# Converts the MIME::Type to a hash
|
597
|
-
#
|
429
|
+
# Converts the MIME::Type to a hash. The output of this method can also be
|
430
|
+
# used to initialize a MIME::Type.
|
598
431
|
def to_h
|
599
432
|
encode_with({})
|
600
433
|
end
|
@@ -605,18 +438,26 @@ class MIME::Type
|
|
605
438
|
#
|
606
439
|
# This method should be considered a private implementation detail.
|
607
440
|
def encode_with(coder)
|
608
|
-
coder['content-type']
|
609
|
-
coder['docs']
|
610
|
-
coder['friendly']
|
611
|
-
coder['encoding']
|
612
|
-
coder['extensions']
|
441
|
+
coder['content-type'] = @content_type
|
442
|
+
coder['docs'] = @docs unless @docs.nil? or @docs.empty?
|
443
|
+
coder['friendly'] = @friendly unless @friendly.nil? or @friendly.empty?
|
444
|
+
coder['encoding'] = @encoding
|
445
|
+
coder['extensions'] = @extensions.to_a unless @extensions.empty?
|
446
|
+
coder['preferred-extension'] = @preferred_extension if @preferred_extension
|
613
447
|
if obsolete?
|
614
|
-
coder['obsolete']
|
615
|
-
coder['use-instead']
|
448
|
+
coder['obsolete'] = obsolete?
|
449
|
+
coder['use-instead'] = use_instead if use_instead
|
450
|
+
end
|
451
|
+
unless xrefs.empty?
|
452
|
+
{}.tap do |hash|
|
453
|
+
xrefs.each do |k, v|
|
454
|
+
hash[k] = v.to_a.sort
|
455
|
+
end
|
456
|
+
coder['xrefs'] = hash
|
457
|
+
end
|
616
458
|
end
|
617
|
-
coder['
|
618
|
-
coder['
|
619
|
-
coder['signature'] = signature? if signature?
|
459
|
+
coder['registered'] = registered?
|
460
|
+
coder['signature'] = signature? if signature?
|
620
461
|
coder
|
621
462
|
end
|
622
463
|
|
@@ -625,161 +466,68 @@ class MIME::Type
|
|
625
466
|
#
|
626
467
|
# This method should be considered a private implementation detail.
|
627
468
|
def init_with(coder)
|
628
|
-
self.content_type
|
629
|
-
self.docs
|
469
|
+
self.content_type = coder['content-type']
|
470
|
+
self.docs = coder['docs'] || ''
|
471
|
+
self.encoding = coder['encoding']
|
472
|
+
self.extensions = coder['extensions'] || []
|
473
|
+
self.preferred_extension = coder['preferred-extension']
|
474
|
+
self.obsolete = coder['obsolete'] || false
|
475
|
+
self.registered = coder['registered'] || false
|
476
|
+
self.signature = coder['signature']
|
477
|
+
self.xrefs = coder['xrefs'] || {}
|
478
|
+
self.use_instead = coder['use-instead']
|
479
|
+
|
630
480
|
friendly(coder['friendly'] || {})
|
631
|
-
self.encoding = coder['encoding']
|
632
|
-
self.extensions = coder['extensions'] || []
|
633
|
-
self.obsolete = coder['obsolete']
|
634
|
-
self.registered = coder['registered']
|
635
|
-
self.signature = coder['signature']
|
636
|
-
self.xrefs = coder['xrefs'] || {}
|
637
|
-
self.use_instead = coder['use-instead']
|
638
481
|
end
|
639
482
|
|
640
|
-
|
641
|
-
#
|
642
|
-
#
|
643
|
-
#
|
644
|
-
|
645
|
-
# <tt>x-</tt> removed and is translated to lowercase.
|
646
|
-
def simplified(content_type)
|
647
|
-
matchdata = case content_type
|
648
|
-
when MatchData
|
649
|
-
content_type
|
650
|
-
else
|
651
|
-
MEDIA_TYPE_RE.match(content_type)
|
652
|
-
end
|
653
|
-
|
654
|
-
return unless matchdata
|
483
|
+
def inspect # :nodoc:
|
484
|
+
# We are intentionally lying here because MIME::Type::Columnar is an
|
485
|
+
# implementation detail.
|
486
|
+
"#<MIME::Type: #{self}>"
|
487
|
+
end
|
655
488
|
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
489
|
+
class << self
|
490
|
+
# MIME media types are case-insensitive, but are typically presented in a
|
491
|
+
# case-preserving format in the type registry. This method converts
|
492
|
+
# +content_type+ to lowercase.
|
493
|
+
#
|
494
|
+
# In previous versions of mime-types, this would also remove any extension
|
495
|
+
# prefix (<tt>x-</tt>). This is no longer default behaviour, but may be
|
496
|
+
# provided by providing a truth value to +remove_x_prefix+.
|
497
|
+
def simplified(content_type, remove_x_prefix: false)
|
498
|
+
simplify_matchdata(match(content_type), remove_x_prefix)
|
661
499
|
end
|
662
500
|
|
663
501
|
# Converts a provided +content_type+ into a translation key suitable for
|
664
502
|
# use with the I18n library.
|
665
503
|
def i18n_key(content_type)
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
else
|
670
|
-
MEDIA_TYPE_RE.match(content_type)
|
671
|
-
end
|
672
|
-
|
673
|
-
return unless matchdata
|
674
|
-
|
675
|
-
matchdata.captures.map { |e|
|
676
|
-
e.downcase!
|
677
|
-
e.gsub!(UNREGISTERED_RE, ''.freeze)
|
678
|
-
e.gsub!(I18N_RE, '-'.freeze)
|
679
|
-
e
|
680
|
-
}.join('.'.freeze)
|
504
|
+
simplify_matchdata(match(content_type), joiner: '.') { |e|
|
505
|
+
e.gsub!(I18N_RE, '-')
|
506
|
+
}
|
681
507
|
end
|
682
508
|
|
683
|
-
#
|
684
|
-
#
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
# These are equivalent to:
|
692
|
-
#
|
693
|
-
# MIME::Type.new('application/x-ruby') do |t|
|
694
|
-
# t.extensions = %w(rb)
|
695
|
-
# t.encoding = '8bit'
|
696
|
-
# end
|
697
|
-
#
|
698
|
-
# It will yield the type (+t+) if a block is given.
|
699
|
-
#
|
700
|
-
# This method is deprecated and will be removed in mime-types 3.
|
701
|
-
def from_array(*args) # :yields t:
|
702
|
-
MIME::Types.deprecated(self, __method__)
|
703
|
-
|
704
|
-
# Dereferences the array one level, if necessary.
|
705
|
-
args = args.first if args.first.kind_of? Array
|
706
|
-
|
707
|
-
unless args.size.between?(1, 8)
|
708
|
-
fail ArgumentError,
|
709
|
-
'Array provided must contain between one and eight elements.'
|
710
|
-
end
|
711
|
-
|
712
|
-
MIME::Type.new(args.shift) do |t|
|
713
|
-
t.extensions, t.encoding, _system, t.obsolete, t.docs, _references,
|
714
|
-
t.registered = *args
|
715
|
-
yield t if block_given?
|
509
|
+
# Return a +MatchData+ object of the +content_type+ against pattern of
|
510
|
+
# media types.
|
511
|
+
def match(content_type)
|
512
|
+
case content_type
|
513
|
+
when MatchData
|
514
|
+
content_type
|
515
|
+
else
|
516
|
+
MEDIA_TYPE_RE.match(content_type)
|
716
517
|
end
|
717
518
|
end
|
718
519
|
|
719
|
-
|
720
|
-
# may be replaced with underscores, and the internal Symbol of the
|
721
|
-
# lowercase-underscore version can be used as well. That is,
|
722
|
-
# Content-Type can be provided as content-type, Content_Type,
|
723
|
-
# content_type, or :content_type.
|
724
|
-
#
|
725
|
-
# Known keys are <tt>Content-Type</tt>,
|
726
|
-
# <tt>Content-Transfer-Encoding</tt>, <tt>Extensions</tt>, and
|
727
|
-
# <tt>System</tt>. +System+ is ignored.
|
728
|
-
#
|
729
|
-
# MIME::Type.from_hash('Content-Type' => 'text/x-yaml',
|
730
|
-
# 'Content-Transfer-Encoding' => '8bit',
|
731
|
-
# 'System' => 'linux',
|
732
|
-
# 'Extensions' => ['yaml', 'yml'])
|
733
|
-
#
|
734
|
-
# This is equivalent to:
|
735
|
-
#
|
736
|
-
# MIME::Type.new('text/x-yaml') do |t|
|
737
|
-
# t.encoding = '8bit'
|
738
|
-
# t.system = 'linux'
|
739
|
-
# t.extensions = ['yaml', 'yml']
|
740
|
-
# end
|
741
|
-
#
|
742
|
-
# It will yield the constructed type +t+ if a block has been provided.
|
743
|
-
#
|
744
|
-
#
|
745
|
-
# This method is deprecated and will be removed in mime-types 3.
|
746
|
-
def from_hash(hash) # :yields t:
|
747
|
-
MIME::Types.deprecated(self, __method__)
|
748
|
-
type = {}
|
749
|
-
hash.each_pair do |k, v|
|
750
|
-
type[k.to_s.tr('A-Z', 'a-z').gsub(/-/, '_').to_sym] = v
|
751
|
-
end
|
520
|
+
private
|
752
521
|
|
753
|
-
|
754
|
-
|
755
|
-
t.encoding = type[:content_transfer_encoding]
|
756
|
-
t.obsolete = type[:obsolete]
|
757
|
-
t.docs = type[:docs]
|
758
|
-
t.url = type[:url]
|
759
|
-
t.registered = type[:registered]
|
760
|
-
|
761
|
-
yield t if block_given?
|
762
|
-
end
|
763
|
-
end
|
522
|
+
def simplify_matchdata(matchdata, remove_x = false, joiner: '/')
|
523
|
+
return nil unless matchdata
|
764
524
|
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
# MIME::Type.new(plaintext.content_type.dup) do |t|
|
772
|
-
# t.extensions = plaintext.extensions.dup
|
773
|
-
# t.system = plaintext.system.dup
|
774
|
-
# t.encoding = plaintext.encoding.dup
|
775
|
-
# end
|
776
|
-
#
|
777
|
-
# It will yield the type (+t+) if a block is given.
|
778
|
-
#
|
779
|
-
# This method is deprecated and will be removed in mime-types 3.
|
780
|
-
def from_mime_type(mime_type) # :yields the new MIME::Type:
|
781
|
-
MIME::Types.deprecated(self, __method__)
|
782
|
-
new(mime_type)
|
525
|
+
matchdata.captures.map { |e|
|
526
|
+
e.downcase!
|
527
|
+
e.sub!(/^x-/, '') if remove_x
|
528
|
+
yield e if block_given?
|
529
|
+
e
|
530
|
+
}.join(joiner)
|
783
531
|
end
|
784
532
|
end
|
785
533
|
|
@@ -789,10 +537,51 @@ class MIME::Type
|
|
789
537
|
match = MEDIA_TYPE_RE.match(type_string)
|
790
538
|
fail InvalidContentType, type_string if match.nil?
|
791
539
|
|
792
|
-
@content_type = type_string
|
540
|
+
@content_type = intern_string(type_string)
|
793
541
|
@raw_media_type, @raw_sub_type = match.captures
|
794
|
-
@simplified = MIME::Type.simplified(match)
|
795
|
-
@i18n_key = MIME::Type.i18n_key(match)
|
542
|
+
@simplified = intern_string(MIME::Type.simplified(match))
|
543
|
+
@i18n_key = intern_string(MIME::Type.i18n_key(match))
|
796
544
|
@media_type, @sub_type = MEDIA_TYPE_RE.match(@simplified).captures
|
545
|
+
|
546
|
+
@raw_media_type = intern_string(@raw_media_type)
|
547
|
+
@raw_sub_type = intern_string(@raw_sub_type)
|
548
|
+
@media_type = intern_string(@media_type)
|
549
|
+
@sub_type = intern_string(@sub_type)
|
550
|
+
end
|
551
|
+
|
552
|
+
if String.method_defined?(:-@)
|
553
|
+
def intern_string(string)
|
554
|
+
-string
|
555
|
+
end
|
556
|
+
else
|
557
|
+
# MRI 2.2 and older don't have a method for string interning,
|
558
|
+
# so we simply freeze them for keeping a similar interface
|
559
|
+
def intern_string(string)
|
560
|
+
string.freeze
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
def xref_map(values, helper)
|
565
|
+
values.map { |value| send(helper, value) }
|
566
|
+
end
|
567
|
+
|
568
|
+
def xref_url_for_rfc(value)
|
569
|
+
'http://www.iana.org/go/%s' % value
|
570
|
+
end
|
571
|
+
|
572
|
+
def xref_url_for_draft(value)
|
573
|
+
'http://www.iana.org/go/%s' % value.sub(/\ARFC/, 'draft')
|
574
|
+
end
|
575
|
+
|
576
|
+
def xref_url_for_rfc_errata(value)
|
577
|
+
'http://www.rfc-editor.org/errata_search.php?eid=%s' % value
|
578
|
+
end
|
579
|
+
|
580
|
+
def xref_url_for_person(value)
|
581
|
+
'http://www.iana.org/assignments/media-types/media-types.xhtml#%s' % value
|
582
|
+
end
|
583
|
+
|
584
|
+
def xref_url_for_template(value)
|
585
|
+
'http://www.iana.org/assignments/media-types/%s' % value
|
797
586
|
end
|
798
587
|
end
|