mime-types 2.99.3 → 3.4.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} +29 -30
- data/Contributing.md +132 -0
- data/History.md +269 -0
- data/{Licence.rdoc → Licence.md} +4 -18
- data/Manifest.txt +8 -25
- data/README.rdoc +63 -73
- data/Rakefile +200 -97
- data/lib/mime/type/columnar.rb +30 -63
- data/lib/mime/type.rb +294 -458
- data/lib/mime/types/_columnar.rb +137 -0
- data/lib/mime/types/cache.rb +52 -74
- data/lib/mime/types/columnar.rb +2 -147
- data/lib/mime/types/container.rb +96 -0
- data/lib/mime/types/deprecations.rb +17 -34
- data/lib/mime/types/full.rb +19 -0
- data/lib/mime/types/loader.rb +36 -152
- data/lib/mime/types/logger.rb +7 -5
- data/lib/mime/types/registry.rb +90 -0
- data/lib/mime/types.rb +55 -148
- data/lib/mime-types.rb +2 -2
- data/test/minitest_helper.rb +8 -18
- data/test/test_mime_type.rb +489 -464
- data/test/test_mime_types.rb +139 -91
- data/test/test_mime_types_cache.rb +85 -57
- data/test/test_mime_types_class.rb +120 -100
- data/test/test_mime_types_lazy.rb +30 -28
- data/test/test_mime_types_loader.rb +18 -45
- metadata +92 -77
- 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/columnar.rb +0 -88
- data/support/convert.rb +0 -158
- data/support/iana_registry.rb +0 -172
data/lib/mime/type.rb
CHANGED
@@ -1,29 +1,69 @@
|
|
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
|
#
|
5
9
|
# == Usage
|
6
10
|
# require 'mime/types'
|
7
11
|
#
|
8
|
-
# plaintext = MIME::Types['text/plain']
|
9
|
-
# # returns [text/plain, text/plain]
|
12
|
+
# plaintext = MIME::Types['text/plain'] # => [ text/plain ]
|
10
13
|
# text = plaintext.first
|
11
|
-
#
|
12
|
-
#
|
14
|
+
# puts text.media_type # => 'text'
|
15
|
+
# puts text.sub_type # => 'plain'
|
13
16
|
#
|
14
|
-
# puts text.extensions.join(
|
17
|
+
# puts text.extensions.join(' ') # => 'txt asc c cc h hh cpp hpp dat hlp'
|
18
|
+
# puts text.preferred_extension # => 'txt'
|
19
|
+
# puts text.friendly # => 'Text Document'
|
20
|
+
# puts text.i18n_key # => 'text.plain'
|
15
21
|
#
|
16
|
-
# puts text.encoding # =>
|
22
|
+
# puts text.encoding # => quoted-printable
|
23
|
+
# puts text.default_encoding # => quoted-printable
|
17
24
|
# puts text.binary? # => false
|
18
25
|
# puts text.ascii? # => true
|
26
|
+
# puts text.obsolete? # => false
|
27
|
+
# puts text.registered? # => true
|
28
|
+
# puts text.provisional? # => false
|
29
|
+
# puts text.complete? # => true
|
30
|
+
#
|
31
|
+
# puts text # => 'text/plain'
|
32
|
+
#
|
19
33
|
# puts text == 'text/plain' # => true
|
20
|
-
# puts
|
34
|
+
# puts 'text/plain' == text # => true
|
35
|
+
# puts text == 'text/x-plain' # => false
|
36
|
+
# puts 'text/x-plain' == text # => false
|
37
|
+
#
|
38
|
+
# puts MIME::Type.simplified('x-appl/x-zip') # => 'x-appl/x-zip'
|
39
|
+
# puts MIME::Type.i18n_key('x-appl/x-zip') # => 'x-appl.x-zip'
|
40
|
+
#
|
41
|
+
# puts text.like?('text/x-plain') # => true
|
42
|
+
# puts text.like?(MIME::Type.new('x-text/x-plain')) # => true
|
43
|
+
#
|
44
|
+
# puts text.xrefs.inspect # => { "rfc" => [ "rfc2046", "rfc3676", "rfc5147" ] }
|
45
|
+
# puts text.xref_urls # => [ "http://www.iana.org/go/rfc2046",
|
46
|
+
# # "http://www.iana.org/go/rfc3676",
|
47
|
+
# # "http://www.iana.org/go/rfc5147" ]
|
48
|
+
#
|
49
|
+
# xtext = MIME::Type.new('x-text/x-plain')
|
50
|
+
# puts xtext.media_type # => 'text'
|
51
|
+
# puts xtext.raw_media_type # => 'x-text'
|
52
|
+
# puts xtext.sub_type # => 'plain'
|
53
|
+
# puts xtext.raw_sub_type # => 'x-plain'
|
54
|
+
# puts xtext.complete? # => false
|
55
|
+
#
|
56
|
+
# puts MIME::Types.any? { |type| type.content_type == 'text/plain' } # => true
|
57
|
+
# puts MIME::Types.all?(&:registered?) # => false
|
58
|
+
#
|
59
|
+
# # Various string representations of MIME types
|
60
|
+
# qcelp = MIME::Types['audio/QCELP'].first # => audio/QCELP
|
61
|
+
# puts qcelp.content_type # => 'audio/QCELP'
|
62
|
+
# puts qcelp.simplified # => 'audio/qcelp'
|
21
63
|
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
# puts MIME::Types.all?(&:registered?)
|
26
|
-
# # => false
|
64
|
+
# xwingz = MIME::Types['application/x-Wingz'].first # => application/x-Wingz
|
65
|
+
# puts xwingz.content_type # => 'application/x-Wingz'
|
66
|
+
# puts xwingz.simplified # => 'application/x-wingz'
|
27
67
|
class MIME::Type
|
28
68
|
# Reflects a MIME content-type specification that is not correctly
|
29
69
|
# formatted (it isn't +type+/+subtype+).
|
@@ -53,81 +93,69 @@ class MIME::Type
|
|
53
93
|
end
|
54
94
|
|
55
95
|
# The released version of the mime-types library.
|
56
|
-
VERSION =
|
96
|
+
VERSION = "3.4.1"
|
57
97
|
|
58
98
|
include Comparable
|
59
99
|
|
60
100
|
# :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'
|
101
|
+
# TODO verify mime-type character restrictions; I am pretty sure that this is
|
102
|
+
# too wide open.
|
103
|
+
MEDIA_TYPE_RE = %r{([-\w.+]+)/([-\w.+]*)}.freeze
|
104
|
+
I18N_RE = /[^[:alnum:]]/.freeze
|
105
|
+
BINARY_ENCODINGS = %w[base64 8bit].freeze
|
106
|
+
ASCII_ENCODINGS = %w[7bit quoted-printable].freeze
|
75
107
|
# :startdoc:
|
76
108
|
|
77
|
-
|
78
|
-
|
79
|
-
:DEFAULT_ENCODINGS, :BINARY_ENCODINGS, :TEXT_ENCODINGS,
|
80
|
-
:VALID_ENCODINGS, :IANA_URL, :RFC_URL, :DRAFT_URL,
|
81
|
-
:CONTACT_URL
|
82
|
-
end
|
109
|
+
private_constant :MEDIA_TYPE_RE, :I18N_RE, :BINARY_ENCODINGS,
|
110
|
+
:ASCII_ENCODINGS
|
83
111
|
|
84
112
|
# Builds a MIME::Type object from the +content_type+, a MIME Content Type
|
85
|
-
# value (e.g., 'text/plain' or '
|
113
|
+
# value (e.g., 'text/plain' or 'application/x-eruby'). The constructed object
|
86
114
|
# is yielded to an optional block for additional configuration, such as
|
87
115
|
# associating extensions and encoding information.
|
88
116
|
#
|
89
117
|
# * When provided a Hash or a MIME::Type, the MIME::Type will be
|
90
118
|
# constructed with #init_with.
|
91
|
-
# * When provided an Array, the MIME::Type will be constructed
|
92
|
-
# the first
|
93
|
-
# extensions.
|
119
|
+
# * When provided an Array, the MIME::Type will be constructed using
|
120
|
+
# the first element as the content type and the remaining flattened
|
121
|
+
# elements as extensions.
|
94
122
|
# * Otherwise, the content_type will be used as a string.
|
95
123
|
#
|
96
124
|
# Yields the newly constructed +self+ object.
|
97
|
-
def initialize(content_type) # :yields self
|
125
|
+
def initialize(content_type) # :yields: self
|
98
126
|
@friendly = {}
|
99
|
-
|
100
|
-
|
101
|
-
self.
|
102
|
-
self.signature = nil
|
127
|
+
@obsolete = @registered = @provisional = false
|
128
|
+
@preferred_extension = @docs = @use_instead = nil
|
129
|
+
self.extensions = []
|
103
130
|
|
104
131
|
case content_type
|
105
132
|
when Hash
|
106
133
|
init_with(content_type)
|
107
134
|
when Array
|
108
|
-
self.content_type = content_type
|
109
|
-
self.extensions = content_type
|
135
|
+
self.content_type = content_type.shift
|
136
|
+
self.extensions = content_type.flatten
|
110
137
|
when MIME::Type
|
111
138
|
init_with(content_type.to_h)
|
112
139
|
else
|
113
140
|
self.content_type = content_type
|
114
141
|
end
|
115
142
|
|
116
|
-
self.extensions ||= []
|
117
|
-
self.docs ||= []
|
118
143
|
self.encoding ||= :default
|
119
144
|
self.xrefs ||= {}
|
120
145
|
|
121
146
|
yield self if block_given?
|
122
147
|
end
|
123
148
|
|
124
|
-
#
|
149
|
+
# Indicates that a MIME type is like another type. This differs from
|
150
|
+
# <tt>==</tt> because <tt>x-</tt> prefixes are removed for this comparison.
|
125
151
|
def like?(other)
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
152
|
+
other =
|
153
|
+
if other.respond_to?(:simplified)
|
154
|
+
MIME::Type.simplified(other.simplified, remove_x_prefix: true)
|
155
|
+
else
|
156
|
+
MIME::Type.simplified(other.to_s, remove_x_prefix: true)
|
157
|
+
end
|
158
|
+
MIME::Type.simplified(simplified, remove_x_prefix: true) == other
|
131
159
|
end
|
132
160
|
|
133
161
|
# Compares the +other+ MIME::Type against the exact content type or the
|
@@ -135,10 +163,16 @@ class MIME::Type
|
|
135
163
|
# something that can be treated as a String with #to_s). In comparisons, this
|
136
164
|
# is done against the lowercase version of the MIME::Type.
|
137
165
|
def <=>(other)
|
138
|
-
if other.
|
139
|
-
|
140
|
-
elsif other.respond_to?(:
|
141
|
-
|
166
|
+
if other.nil?
|
167
|
+
-1
|
168
|
+
elsif other.respond_to?(:simplified)
|
169
|
+
simplified <=> other.simplified
|
170
|
+
else
|
171
|
+
filtered = "silent" if other == :silent
|
172
|
+
filtered ||= "true" if other == true
|
173
|
+
filtered ||= other.to_s
|
174
|
+
|
175
|
+
simplified <=> MIME::Type.simplified(filtered)
|
142
176
|
end
|
143
177
|
end
|
144
178
|
|
@@ -160,24 +194,25 @@ class MIME::Type
|
|
160
194
|
# before unregistered or obsolete content types.
|
161
195
|
def priority_compare(other)
|
162
196
|
pc = simplified <=> other.simplified
|
163
|
-
if pc.zero?
|
164
|
-
pc =
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
197
|
+
if pc.zero? || !(extensions & other.extensions).empty?
|
198
|
+
pc =
|
199
|
+
if (reg = registered?) != other.registered?
|
200
|
+
reg ? -1 : 1 # registered < unregistered
|
201
|
+
elsif (comp = complete?) != other.complete?
|
202
|
+
comp ? -1 : 1 # complete < incomplete
|
203
|
+
elsif (obs = obsolete?) != other.obsolete?
|
204
|
+
obs ? 1 : -1 # current < obsolete
|
205
|
+
elsif obs && ((ui = use_instead) != (oui = other.use_instead))
|
206
|
+
if ui.nil?
|
207
|
+
1
|
208
|
+
elsif oui.nil?
|
209
|
+
-1
|
210
|
+
else
|
211
|
+
ui <=> oui
|
212
|
+
end
|
213
|
+
else
|
214
|
+
0
|
215
|
+
end
|
181
216
|
end
|
182
217
|
|
183
218
|
pc
|
@@ -186,7 +221,7 @@ class MIME::Type
|
|
186
221
|
# Returns +true+ if the +other+ object is a MIME::Type and the content types
|
187
222
|
# match.
|
188
223
|
def eql?(other)
|
189
|
-
other.
|
224
|
+
other.is_a?(MIME::Type) && (self == other)
|
190
225
|
end
|
191
226
|
|
192
227
|
# Returns the whole MIME content-type string.
|
@@ -200,58 +235,77 @@ class MIME::Type
|
|
200
235
|
# audio/QCELP => audio/QCELP
|
201
236
|
attr_reader :content_type
|
202
237
|
# A simplified form of the MIME content-type string, suitable for
|
203
|
-
# case-insensitive comparison, with
|
204
|
-
# removed and converted to lowercase.
|
238
|
+
# case-insensitive comparison, with the content_type converted to lowercase.
|
205
239
|
#
|
206
240
|
# text/plain => text/plain
|
207
|
-
# x-chemical/x-pdb => chemical/pdb
|
241
|
+
# x-chemical/x-pdb => x-chemical/x-pdb
|
208
242
|
# audio/QCELP => audio/qcelp
|
209
243
|
attr_reader :simplified
|
210
244
|
# Returns the media type of the simplified MIME::Type.
|
211
245
|
#
|
212
246
|
# text/plain => text
|
213
|
-
# x-chemical/x-pdb => chemical
|
247
|
+
# x-chemical/x-pdb => x-chemical
|
248
|
+
# audio/QCELP => audio
|
214
249
|
attr_reader :media_type
|
215
250
|
# Returns the media type of the unmodified MIME::Type.
|
216
251
|
#
|
217
252
|
# text/plain => text
|
218
253
|
# x-chemical/x-pdb => x-chemical
|
254
|
+
# audio/QCELP => audio
|
219
255
|
attr_reader :raw_media_type
|
220
256
|
# Returns the sub-type of the simplified MIME::Type.
|
221
257
|
#
|
222
258
|
# text/plain => plain
|
223
259
|
# x-chemical/x-pdb => pdb
|
260
|
+
# audio/QCELP => QCELP
|
224
261
|
attr_reader :sub_type
|
225
262
|
# Returns the media type of the unmodified MIME::Type.
|
226
263
|
#
|
227
264
|
# text/plain => plain
|
228
265
|
# x-chemical/x-pdb => x-pdb
|
266
|
+
# audio/QCELP => qcelp
|
229
267
|
attr_reader :raw_sub_type
|
230
268
|
|
269
|
+
##
|
231
270
|
# The list of extensions which are known to be used for this MIME::Type.
|
232
271
|
# Non-array values will be coerced into an array with #to_a. Array values
|
233
272
|
# will be flattened, +nil+ values removed, and made unique.
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
273
|
+
#
|
274
|
+
# :attr_accessor: extensions
|
275
|
+
def extensions
|
276
|
+
@extensions.to_a
|
277
|
+
end
|
278
|
+
|
279
|
+
##
|
280
|
+
def extensions=(value) # :nodoc:
|
281
|
+
@extensions = Set[*Array(value).flatten.compact].freeze
|
282
|
+
MIME::Types.send(:reindex_extensions, self)
|
239
283
|
end
|
240
284
|
|
241
285
|
# Merge the +extensions+ provided into this MIME::Type. The extensions added
|
242
286
|
# will be merged uniquely.
|
243
287
|
def add_extensions(*extensions)
|
244
|
-
self.extensions
|
288
|
+
self.extensions += extensions
|
245
289
|
end
|
246
290
|
|
247
291
|
##
|
248
|
-
# The preferred extension for this MIME type
|
292
|
+
# The preferred extension for this MIME type. If one is not set and there are
|
293
|
+
# exceptions defined, the first extension will be used.
|
294
|
+
#
|
295
|
+
# When setting #preferred_extensions, if #extensions does not contain this
|
296
|
+
# extension, this will be added to #xtensions.
|
249
297
|
#
|
250
|
-
# :
|
298
|
+
# :attr_accessor: preferred_extension
|
251
299
|
|
252
300
|
##
|
253
301
|
def preferred_extension
|
254
|
-
extensions.first
|
302
|
+
@preferred_extension || extensions.first
|
303
|
+
end
|
304
|
+
|
305
|
+
##
|
306
|
+
def preferred_extension=(value) # :nodoc:
|
307
|
+
add_extensions(value) if value
|
308
|
+
@preferred_extension = value
|
255
309
|
end
|
256
310
|
|
257
311
|
##
|
@@ -270,60 +324,41 @@ class MIME::Type
|
|
270
324
|
|
271
325
|
##
|
272
326
|
attr_reader :encoding
|
327
|
+
|
328
|
+
##
|
273
329
|
def encoding=(enc) # :nodoc:
|
274
|
-
if
|
330
|
+
if enc.nil? || (enc == :default)
|
275
331
|
@encoding = default_encoding
|
276
|
-
elsif BINARY_ENCODINGS.include?(enc)
|
332
|
+
elsif BINARY_ENCODINGS.include?(enc) || ASCII_ENCODINGS.include?(enc)
|
277
333
|
@encoding = enc
|
278
334
|
else
|
279
335
|
fail InvalidEncoding, enc
|
280
336
|
end
|
281
337
|
end
|
282
338
|
|
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
339
|
# Returns the default encoding for the MIME::Type based on the media type.
|
299
340
|
def default_encoding
|
300
|
-
|
341
|
+
@media_type == "text" ? "quoted-printable" : "base64"
|
301
342
|
end
|
302
343
|
|
303
344
|
##
|
304
|
-
# Returns the media type or types that should be used instead of this
|
305
|
-
#
|
306
|
-
#
|
345
|
+
# Returns the media type or types that should be used instead of this media
|
346
|
+
# type, if it is obsolete. If there is no replacement media type, or it is
|
347
|
+
# not obsolete, +nil+ will be returned.
|
307
348
|
#
|
308
349
|
# :attr_accessor: use_instead
|
309
350
|
|
310
351
|
##
|
311
352
|
def use_instead
|
312
|
-
|
313
|
-
@use_instead
|
353
|
+
obsolete? ? @use_instead : nil
|
314
354
|
end
|
315
355
|
|
316
356
|
##
|
317
357
|
attr_writer :use_instead
|
318
358
|
|
319
359
|
# Returns +true+ if the media type is obsolete.
|
320
|
-
|
321
|
-
|
322
|
-
end
|
323
|
-
|
324
|
-
def obsolete=(v) # :nodoc:
|
325
|
-
@obsolete = !!v
|
326
|
-
end
|
360
|
+
attr_accessor :obsolete
|
361
|
+
alias_method :obsolete?, :obsolete
|
327
362
|
|
328
363
|
# The documentation for this MIME::Type.
|
329
364
|
attr_accessor :docs
|
@@ -333,18 +368,19 @@ class MIME::Type
|
|
333
368
|
# call-seq:
|
334
369
|
# text_plain.friendly # => "Text File"
|
335
370
|
# text_plain.friendly('en') # => "Text File"
|
336
|
-
def friendly(lang =
|
371
|
+
def friendly(lang = "en")
|
337
372
|
@friendly ||= {}
|
338
373
|
|
339
374
|
case lang
|
340
|
-
when String
|
341
|
-
@friendly[lang]
|
375
|
+
when String, Symbol
|
376
|
+
@friendly[lang.to_s]
|
342
377
|
when Array
|
343
|
-
@friendly.
|
378
|
+
@friendly.update(Hash[*lang])
|
344
379
|
when Hash
|
345
|
-
@friendly.
|
380
|
+
@friendly.update(lang)
|
346
381
|
else
|
347
|
-
fail ArgumentError
|
382
|
+
fail ArgumentError,
|
383
|
+
"Expected a language or translation set, not #{lang.inspect}"
|
348
384
|
end
|
349
385
|
end
|
350
386
|
|
@@ -359,50 +395,6 @@ class MIME::Type
|
|
359
395
|
# # from application/x-msword
|
360
396
|
attr_reader :i18n_key
|
361
397
|
|
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
398
|
##
|
407
399
|
# The cross-references list for this MIME::Type.
|
408
400
|
#
|
@@ -412,134 +404,47 @@ class MIME::Type
|
|
412
404
|
attr_reader :xrefs
|
413
405
|
|
414
406
|
##
|
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
|
-
[]
|
407
|
+
def xrefs=(xrefs) # :nodoc:
|
408
|
+
@xrefs = MIME::Types::Container.new(xrefs)
|
443
409
|
end
|
444
410
|
|
445
411
|
# The decoded cross-reference URL list for this MIME::Type.
|
446
412
|
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
|
413
|
+
xrefs.flat_map { |type, values|
|
414
|
+
name = :"xref_url_for_#{type.tr("-", "_")}"
|
415
|
+
respond_to?(name, true) && xref_map(values, name) || values.to_a
|
470
416
|
}
|
471
417
|
end
|
472
418
|
|
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
|
419
|
+
# Indicates whether the MIME type has been registered with IANA.
|
420
|
+
attr_accessor :registered
|
421
|
+
alias_method :registered?, :registered
|
496
422
|
|
497
|
-
|
498
|
-
|
423
|
+
# Indicates whether the MIME type's registration with IANA is provisional.
|
424
|
+
attr_accessor :provisional
|
425
|
+
|
426
|
+
# Indicates whether the MIME type's registration with IANA is provisional.
|
427
|
+
def provisional?
|
428
|
+
registered? && @provisional
|
499
429
|
end
|
500
430
|
|
501
431
|
# MIME types can be specified to be sent across a network in particular
|
502
432
|
# formats. This method returns +true+ when the MIME::Type encoding is set
|
503
433
|
# to <tt>base64</tt>.
|
504
434
|
def binary?
|
505
|
-
BINARY_ENCODINGS.include?(
|
435
|
+
BINARY_ENCODINGS.include?(encoding)
|
506
436
|
end
|
507
437
|
|
508
438
|
# MIME types can be specified to be sent across a network in particular
|
509
439
|
# formats. This method returns +false+ when the MIME::Type encoding is
|
510
440
|
# set to <tt>base64</tt>.
|
511
441
|
def ascii?
|
512
|
-
|
442
|
+
ASCII_ENCODINGS.include?(encoding)
|
513
443
|
end
|
514
444
|
|
515
|
-
#
|
516
|
-
|
517
|
-
|
518
|
-
!!@signature
|
519
|
-
end
|
520
|
-
|
521
|
-
def signature=(v) # :nodoc:
|
522
|
-
@signature = !!v
|
523
|
-
end
|
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
|
445
|
+
# Indicateswhether the MIME type is declared as a signature type.
|
446
|
+
attr_accessor :signature
|
447
|
+
alias_method :signature?, :signature
|
543
448
|
|
544
449
|
# Returns +true+ if the MIME::Type specifies an extension list,
|
545
450
|
# indicating that it is a complete MIME::Type.
|
@@ -560,41 +465,14 @@ class MIME::Type
|
|
560
465
|
content_type
|
561
466
|
end
|
562
467
|
|
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
468
|
# Converts the MIME::Type to a JSON string.
|
591
469
|
def to_json(*args)
|
592
|
-
require
|
470
|
+
require "json"
|
593
471
|
to_h.to_json(*args)
|
594
472
|
end
|
595
473
|
|
596
|
-
# Converts the MIME::Type to a hash
|
597
|
-
#
|
474
|
+
# Converts the MIME::Type to a hash. The output of this method can also be
|
475
|
+
# used to initialize a MIME::Type.
|
598
476
|
def to_h
|
599
477
|
encode_with({})
|
600
478
|
end
|
@@ -605,18 +483,27 @@ class MIME::Type
|
|
605
483
|
#
|
606
484
|
# This method should be considered a private implementation detail.
|
607
485
|
def encode_with(coder)
|
608
|
-
coder[
|
609
|
-
coder[
|
610
|
-
coder[
|
611
|
-
coder[
|
612
|
-
coder[
|
486
|
+
coder["content-type"] = @content_type
|
487
|
+
coder["docs"] = @docs unless @docs.nil? || @docs.empty?
|
488
|
+
coder["friendly"] = @friendly unless @friendly.nil? || @friendly.empty?
|
489
|
+
coder["encoding"] = @encoding
|
490
|
+
coder["extensions"] = @extensions.to_a unless @extensions.empty?
|
491
|
+
coder["preferred-extension"] = @preferred_extension if @preferred_extension
|
613
492
|
if obsolete?
|
614
|
-
coder[
|
615
|
-
coder[
|
493
|
+
coder["obsolete"] = obsolete?
|
494
|
+
coder["use-instead"] = use_instead if use_instead
|
616
495
|
end
|
617
|
-
|
618
|
-
|
619
|
-
|
496
|
+
unless xrefs.empty?
|
497
|
+
{}.tap do |hash|
|
498
|
+
xrefs.each do |k, v|
|
499
|
+
hash[k] = v.to_a.sort
|
500
|
+
end
|
501
|
+
coder["xrefs"] = hash
|
502
|
+
end
|
503
|
+
end
|
504
|
+
coder["registered"] = registered?
|
505
|
+
coder["provisional"] = provisional? if provisional?
|
506
|
+
coder["signature"] = signature? if signature?
|
620
507
|
coder
|
621
508
|
end
|
622
509
|
|
@@ -625,174 +512,123 @@ class MIME::Type
|
|
625
512
|
#
|
626
513
|
# This method should be considered a private implementation detail.
|
627
514
|
def init_with(coder)
|
628
|
-
self.content_type = coder[
|
629
|
-
self.docs
|
630
|
-
|
631
|
-
self.
|
632
|
-
self.
|
633
|
-
self.obsolete
|
634
|
-
self.registered
|
635
|
-
self.
|
636
|
-
self.
|
637
|
-
self.
|
515
|
+
self.content_type = coder["content-type"]
|
516
|
+
self.docs = coder["docs"] || ""
|
517
|
+
self.encoding = coder["encoding"]
|
518
|
+
self.extensions = coder["extensions"] || []
|
519
|
+
self.preferred_extension = coder["preferred-extension"]
|
520
|
+
self.obsolete = coder["obsolete"] || false
|
521
|
+
self.registered = coder["registered"] || false
|
522
|
+
self.provisional = coder["provisional"] || false
|
523
|
+
self.signature = coder["signature"]
|
524
|
+
self.xrefs = coder["xrefs"] || {}
|
525
|
+
self.use_instead = coder["use-instead"]
|
526
|
+
|
527
|
+
friendly(coder["friendly"] || {})
|
638
528
|
end
|
639
529
|
|
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
|
530
|
+
def inspect # :nodoc:
|
531
|
+
# We are intentionally lying here because MIME::Type::Columnar is an
|
532
|
+
# implementation detail.
|
533
|
+
"#<MIME::Type: #{self}>"
|
534
|
+
end
|
655
535
|
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
536
|
+
class << self
|
537
|
+
# MIME media types are case-insensitive, but are typically presented in a
|
538
|
+
# case-preserving format in the type registry. This method converts
|
539
|
+
# +content_type+ to lowercase.
|
540
|
+
#
|
541
|
+
# In previous versions of mime-types, this would also remove any extension
|
542
|
+
# prefix (<tt>x-</tt>). This is no longer default behaviour, but may be
|
543
|
+
# provided by providing a truth value to +remove_x_prefix+.
|
544
|
+
def simplified(content_type, remove_x_prefix: false)
|
545
|
+
simplify_matchdata(match(content_type), remove_x_prefix)
|
661
546
|
end
|
662
547
|
|
663
548
|
# Converts a provided +content_type+ into a translation key suitable for
|
664
549
|
# use with the I18n library.
|
665
550
|
def i18n_key(content_type)
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
551
|
+
simplify_matchdata(match(content_type), joiner: ".") { |e|
|
552
|
+
e.gsub!(I18N_RE, "-")
|
553
|
+
}
|
554
|
+
end
|
555
|
+
|
556
|
+
# Return a +MatchData+ object of the +content_type+ against pattern of
|
557
|
+
# media types.
|
558
|
+
def match(content_type)
|
559
|
+
case content_type
|
560
|
+
when MatchData
|
561
|
+
content_type
|
562
|
+
else
|
563
|
+
MEDIA_TYPE_RE.match(content_type)
|
564
|
+
end
|
565
|
+
end
|
566
|
+
|
567
|
+
private
|
672
568
|
|
673
|
-
|
569
|
+
def simplify_matchdata(matchdata, remove_x = false, joiner: "/")
|
570
|
+
return nil unless matchdata
|
674
571
|
|
675
572
|
matchdata.captures.map { |e|
|
676
573
|
e.downcase!
|
677
|
-
e.
|
678
|
-
e
|
574
|
+
e.sub!(/^x-/, "") if remove_x
|
575
|
+
yield e if block_given?
|
679
576
|
e
|
680
|
-
}.join(
|
577
|
+
}.join(joiner)
|
681
578
|
end
|
579
|
+
end
|
682
580
|
|
683
|
-
|
684
|
-
# [ type-name, [ extensions ], encoding, system ]
|
685
|
-
#
|
686
|
-
# +extensions+, and +encoding+ are optional; +system+ is ignored.
|
687
|
-
#
|
688
|
-
# MIME::Type.from_array('application/x-ruby', %w(rb), '8bit')
|
689
|
-
# MIME::Type.from_array([ 'application/x-ruby', [ 'rb' ], '8bit' ])
|
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__)
|
581
|
+
private
|
703
582
|
|
704
|
-
|
705
|
-
|
583
|
+
def content_type=(type_string)
|
584
|
+
match = MEDIA_TYPE_RE.match(type_string)
|
585
|
+
fail InvalidContentType, type_string if match.nil?
|
706
586
|
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
587
|
+
@content_type = intern_string(type_string)
|
588
|
+
@raw_media_type, @raw_sub_type = match.captures
|
589
|
+
@simplified = intern_string(MIME::Type.simplified(match))
|
590
|
+
@i18n_key = intern_string(MIME::Type.i18n_key(match))
|
591
|
+
@media_type, @sub_type = MEDIA_TYPE_RE.match(@simplified).captures
|
711
592
|
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
end
|
593
|
+
@raw_media_type = intern_string(@raw_media_type)
|
594
|
+
@raw_sub_type = intern_string(@raw_sub_type)
|
595
|
+
@media_type = intern_string(@media_type)
|
596
|
+
@sub_type = intern_string(@sub_type)
|
597
|
+
end
|
718
598
|
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
#
|
725
|
-
#
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
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
|
599
|
+
if String.method_defined?(:-@)
|
600
|
+
def intern_string(string)
|
601
|
+
-string
|
602
|
+
end
|
603
|
+
else
|
604
|
+
# MRI 2.2 and older don't have a method for string interning,
|
605
|
+
# so we simply freeze them for keeping a similar interface
|
606
|
+
def intern_string(string)
|
607
|
+
string.freeze
|
608
|
+
end
|
609
|
+
end
|
752
610
|
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
t.obsolete = type[:obsolete]
|
757
|
-
t.docs = type[:docs]
|
758
|
-
t.url = type[:url]
|
759
|
-
t.registered = type[:registered]
|
611
|
+
def xref_map(values, helper)
|
612
|
+
values.map { |value| send(helper, value) }
|
613
|
+
end
|
760
614
|
|
761
|
-
|
762
|
-
|
763
|
-
|
615
|
+
def xref_url_for_rfc(value)
|
616
|
+
"http://www.iana.org/go/%s" % value
|
617
|
+
end
|
764
618
|
|
765
|
-
|
766
|
-
|
767
|
-
# MIME::Type.from_mime_type(plaintext)
|
768
|
-
#
|
769
|
-
# is equivalent to:
|
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)
|
783
|
-
end
|
619
|
+
def xref_url_for_draft(value)
|
620
|
+
"http://www.iana.org/go/%s" % value.sub(/\ARFC/, "draft")
|
784
621
|
end
|
785
622
|
|
786
|
-
|
623
|
+
def xref_url_for_rfc_errata(value)
|
624
|
+
"http://www.rfc-editor.org/errata_search.php?eid=%s" % value
|
625
|
+
end
|
787
626
|
|
788
|
-
def
|
789
|
-
|
790
|
-
|
627
|
+
def xref_url_for_person(value)
|
628
|
+
"http://www.iana.org/assignments/media-types/media-types.xhtml#%s" % value
|
629
|
+
end
|
791
630
|
|
792
|
-
|
793
|
-
|
794
|
-
@simplified = MIME::Type.simplified(match)
|
795
|
-
@i18n_key = MIME::Type.i18n_key(match)
|
796
|
-
@media_type, @sub_type = MEDIA_TYPE_RE.match(@simplified).captures
|
631
|
+
def xref_url_for_template(value)
|
632
|
+
"http://www.iana.org/assignments/media-types/%s" % value
|
797
633
|
end
|
798
634
|
end
|