mime-types 1.25.1 → 2.0

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.
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,127 +1,127 @@
1
- The "Artistic License"
2
-
3
- Preamble
4
-
5
- The intent of this document is to state the conditions under which a
6
- Package may be copied, such that the Copyright Holder maintains some
7
- semblance of artistic control over the development of the package,
8
- while giving the users of the package the right to use and distribute
9
- the Package in a more-or-less customary fashion, plus the right to make
10
- reasonable modifications.
11
-
12
- Definitions:
13
-
14
- "Package" refers to the collection of files distributed by the
15
- Copyright Holder, and derivatives of that collection of files
16
- created through textual modification.
17
-
18
- "Standard Version" refers to such a Package if it has not been
19
- modified, or has been modified in accordance with the wishes
20
- of the Copyright Holder as specified below.
21
-
22
- "Copyright Holder" is whoever is named in the copyright or
23
- copyrights for the package.
24
-
25
- "You" is you, if you're thinking about copying or distributing
26
- this Package.
27
-
28
- "Reasonable copying fee" is whatever you can justify on the
29
- basis of media cost, duplication charges, time of people involved,
30
- and so on. (You will not be required to justify it to the
31
- Copyright Holder, but only to the computing community at large
32
- as a market that must bear the fee.)
33
-
34
- "Freely Available" means that no fee is charged for the item
35
- itself, though there may be fees involved in handling the item.
36
- It also means that recipients of the item may redistribute it
37
- under the same conditions they received it.
38
-
39
- 1. You may make and give away verbatim copies of the source form of the
40
- Standard Version of this Package without restriction, provided that you
41
- duplicate all of the original copyright notices and associated disclaimers.
42
-
43
- 2. You may apply bug fixes, portability fixes and other modifications
44
- derived from the Public Domain or from the Copyright Holder. A Package
45
- modified in such a way shall still be considered the Standard Version.
46
-
47
- 3. You may otherwise modify your copy of this Package in any way, provided
48
- that you insert a prominent notice in each changed file stating how and
49
- when you changed that file, and provided that you do at least ONE of the
50
- following:
51
-
52
- a) place your modifications in the Public Domain or otherwise make them
53
- Freely Available, such as by posting said modifications to Usenet or
54
- an equivalent medium, or placing the modifications on a major archive
55
- site such as uunet.uu.net, or by allowing the Copyright Holder to include
56
- your modifications in the Standard Version of the Package.
57
-
58
- b) use the modified Package only within your corporation or organization.
59
-
60
- c) rename any non-standard executables so the names do not conflict
61
- with standard executables, which must also be provided, and provide
62
- a separate manual page for each non-standard executable that clearly
63
- documents how it differs from the Standard Version.
64
-
65
- d) make other distribution arrangements with the Copyright Holder.
66
-
67
- 4. You may distribute the programs of this Package in object code or
68
- executable form, provided that you do at least ONE of the following:
69
-
70
- a) distribute a Standard Version of the executables and library files,
71
- together with instructions (in the manual page or equivalent) on where
72
- to get the Standard Version.
73
-
74
- b) accompany the distribution with the machine-readable source of
75
- the Package with your modifications.
76
-
77
- c) give non-standard executables non-standard names, and clearly
78
- document the differences in manual pages (or equivalent), together
79
- with instructions on where to get the Standard Version.
80
-
81
- d) make other distribution arrangements with the Copyright Holder.
82
-
83
- 5. You may charge a reasonable copying fee for any distribution of this
84
- Package. You may charge any fee you choose for support of this
85
- Package. You may not charge a fee for this Package itself. However,
86
- you may distribute this Package in aggregate with other (possibly
87
- commercial) programs as part of a larger (possibly commercial) software
88
- distribution provided that you do not advertise this Package as a
89
- product of your own. You may embed this Package's interpreter within
90
- an executable of yours (by linking); this shall be construed as a mere
91
- form of aggregation, provided that the complete Standard Version of the
92
- interpreter is so embedded.
93
-
94
- 6. The scripts and library files supplied as input to or produced as
95
- output from the programs of this Package do not automatically fall
96
- under the copyright of this Package, but belong to whoever generated
97
- them, and may be sold commercially, and may be aggregated with this
98
- Package. If such scripts or library files are aggregated with this
99
- Package via the so-called "undump" or "unexec" methods of producing a
100
- binary executable image, then distribution of such an image shall
101
- neither be construed as a distribution of this Package nor shall it
102
- fall under the restrictions of Paragraphs 3 and 4, provided that you do
103
- not represent such an executable image as a Standard Version of this
104
- Package.
105
-
106
- 7. C subroutines (or comparably compiled subroutines in other
107
- languages) supplied by you and linked into this Package in order to
108
- emulate subroutines and variables of the language defined by this
109
- Package shall not be considered part of this Package, but are the
110
- equivalent of input as in Paragraph 6, provided these subroutines do
111
- not change the language in any way that would cause it to fail the
112
- regression tests for the language.
113
-
114
- 8. Aggregation of this Package with a commercial distribution is always
115
- permitted provided that the use of this Package is embedded; that is,
116
- when no overt attempt is made to make this Package's interfaces visible
117
- to the end user of the commercial distribution. Such use shall not be
118
- construed as a distribution of this Package.
119
-
120
- 9. The name of the Copyright Holder may not be used to endorse or promote
121
- products derived from this software without specific prior written permission.
122
-
123
- 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
124
- IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
125
- WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
126
-
127
- The End
1
+ = The "Artistic License"
2
+
3
+ Preamble
4
+
5
+ The intent of this document is to state the conditions under which a
6
+ Package may be copied, such that the Copyright Holder maintains some
7
+ semblance of artistic control over the development of the package,
8
+ while giving the users of the package the right to use and distribute
9
+ the Package in a more-or-less customary fashion, plus the right to make
10
+ reasonable modifications.
11
+
12
+ Definitions:
13
+
14
+ "Package" refers to the collection of files distributed by the
15
+ Copyright Holder, and derivatives of that collection of files
16
+ created through textual modification.
17
+
18
+ "Standard Version" refers to such a Package if it has not been
19
+ modified, or has been modified in accordance with the wishes
20
+ of the Copyright Holder as specified below.
21
+
22
+ "Copyright Holder" is whoever is named in the copyright or
23
+ copyrights for the package.
24
+
25
+ "You" is you, if you're thinking about copying or distributing
26
+ this Package.
27
+
28
+ "Reasonable copying fee" is whatever you can justify on the
29
+ basis of media cost, duplication charges, time of people involved,
30
+ and so on. (You will not be required to justify it to the
31
+ Copyright Holder, but only to the computing community at large
32
+ as a market that must bear the fee.)
33
+
34
+ "Freely Available" means that no fee is charged for the item
35
+ itself, though there may be fees involved in handling the item.
36
+ It also means that recipients of the item may redistribute it
37
+ under the same conditions they received it.
38
+
39
+ 1. You may make and give away verbatim copies of the source form of the
40
+ Standard Version of this Package without restriction, provided that you
41
+ duplicate all of the original copyright notices and associated disclaimers.
42
+
43
+ 2. You may apply bug fixes, portability fixes and other modifications
44
+ derived from the Public Domain or from the Copyright Holder. A Package
45
+ modified in such a way shall still be considered the Standard Version.
46
+
47
+ 3. You may otherwise modify your copy of this Package in any way, provided
48
+ that you insert a prominent notice in each changed file stating how and
49
+ when you changed that file, and provided that you do at least ONE of the
50
+ following:
51
+
52
+ a) place your modifications in the Public Domain or otherwise make them
53
+ Freely Available, such as by posting said modifications to Usenet or
54
+ an equivalent medium, or placing the modifications on a major archive
55
+ site such as uunet.uu.net, or by allowing the Copyright Holder to include
56
+ your modifications in the Standard Version of the Package.
57
+
58
+ b) use the modified Package only within your corporation or organization.
59
+
60
+ c) rename any non-standard executables so the names do not conflict
61
+ with standard executables, which must also be provided, and provide
62
+ a separate manual page for each non-standard executable that clearly
63
+ documents how it differs from the Standard Version.
64
+
65
+ d) make other distribution arrangements with the Copyright Holder.
66
+
67
+ 4. You may distribute the programs of this Package in object code or
68
+ executable form, provided that you do at least ONE of the following:
69
+
70
+ a) distribute a Standard Version of the executables and library files,
71
+ together with instructions (in the manual page or equivalent) on where
72
+ to get the Standard Version.
73
+
74
+ b) accompany the distribution with the machine-readable source of
75
+ the Package with your modifications.
76
+
77
+ c) give non-standard executables non-standard names, and clearly
78
+ document the differences in manual pages (or equivalent), together
79
+ with instructions on where to get the Standard Version.
80
+
81
+ d) make other distribution arrangements with the Copyright Holder.
82
+
83
+ 5. You may charge a reasonable copying fee for any distribution of this
84
+ Package. You may charge any fee you choose for support of this
85
+ Package. You may not charge a fee for this Package itself. However,
86
+ you may distribute this Package in aggregate with other (possibly
87
+ commercial) programs as part of a larger (possibly commercial) software
88
+ distribution provided that you do not advertise this Package as a
89
+ product of your own. You may embed this Package's interpreter within
90
+ an executable of yours (by linking); this shall be construed as a mere
91
+ form of aggregation, provided that the complete Standard Version of the
92
+ interpreter is so embedded.
93
+
94
+ 6. The scripts and library files supplied as input to or produced as
95
+ output from the programs of this Package do not automatically fall
96
+ under the copyright of this Package, but belong to whoever generated
97
+ them, and may be sold commercially, and may be aggregated with this
98
+ Package. If such scripts or library files are aggregated with this
99
+ Package via the so-called "undump" or "unexec" methods of producing a
100
+ binary executable image, then distribution of such an image shall
101
+ neither be construed as a distribution of this Package nor shall it
102
+ fall under the restrictions of Paragraphs 3 and 4, provided that you do
103
+ not represent such an executable image as a Standard Version of this
104
+ Package.
105
+
106
+ 7. C subroutines (or comparably compiled subroutines in other
107
+ languages) supplied by you and linked into this Package in order to
108
+ emulate subroutines and variables of the language defined by this
109
+ Package shall not be considered part of this Package, but are the
110
+ equivalent of input as in Paragraph 6, provided these subroutines do
111
+ not change the language in any way that would cause it to fail the
112
+ regression tests for the language.
113
+
114
+ 8. Aggregation of this Package with a commercial distribution is always
115
+ permitted provided that the use of this Package is embedded; that is,
116
+ when no overt attempt is made to make this Package's interfaces visible
117
+ to the end user of the commercial distribution. Such use shall not be
118
+ construed as a distribution of this Package.
119
+
120
+ 9. The name of the Copyright Holder may not be used to endorse or promote
121
+ products derived from this software without specific prior written permission.
122
+
123
+ 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
124
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
125
+ WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
126
+
127
+ The End
@@ -0,0 +1,50 @@
1
+ # -*- ruby encoding: utf-8 -*-
2
+
3
+ # The namespace for MIME applications, tools, and libraries.
4
+ module MIME # :nodoc:
5
+ end
6
+
7
+ class << MIME
8
+ # Used to mark a method as deprecated in the mime-types interface.
9
+ def deprecated(klass, sym, message = nil) # :nodoc:
10
+ level = case klass
11
+ when Class, Module
12
+ '.'
13
+ else
14
+ klass = klass.class
15
+ '#'
16
+ end
17
+ unless defined?(@__deprecated) and @__deprecated["#{klass}#{level}#{sym}"]
18
+ message = case message
19
+ when :private, :protected
20
+ "and will be #{message}"
21
+ when nil
22
+ "and will be removed"
23
+ else
24
+ message
25
+ end
26
+ warn "#{klass}#{level}#{sym} is deprecated #{message}."
27
+ (@__deprecated ||= {})["#{klass}#{level}#{sym}"] = true
28
+ end
29
+ end
30
+
31
+ # MIME::InvalidContentType was moved to MIME::Type::InvalidContentType.
32
+ # Provide a single warning about this fact in the interim.
33
+ def const_missing(name) # :nodoc:
34
+ case name.to_s
35
+ when "InvalidContentType"
36
+ warn_about_moved_constants(name)
37
+ MIME::Type.const_get(name.to_sym)
38
+ else
39
+ super
40
+ end
41
+ end
42
+
43
+ private
44
+ def warn_about_moved_constants(name) # :nodoc:
45
+ unless defined?(@__warned_constants) and @__warned_constants[name]
46
+ warn "MIME::#{name} is deprecated. Use MIME::Type::#{name} instead."
47
+ (@__warned_constants ||= {})[name] = true
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,634 @@
1
+ # -*- ruby encoding: utf-8 -*-
2
+
3
+ require 'mime'
4
+ require 'json'
5
+
6
+ # The definition of one MIME content-type.
7
+ #
8
+ # == Usage
9
+ # require 'mime/types'
10
+ #
11
+ # plaintext = MIME::Types['text/plain'].first
12
+ # # returns [text/plain, text/plain]
13
+ # text = plaintext.first
14
+ # print text.media_type # => 'text'
15
+ # print text.sub_type # => 'plain'
16
+ #
17
+ # puts text.extensions.join(" ") # => 'asc txt c cc h hh cpp'
18
+ #
19
+ # puts text.encoding # => 8bit
20
+ # puts text.binary? # => false
21
+ # puts text.ascii? # => true
22
+ # puts text == 'text/plain' # => true
23
+ # puts MIME::Type.simplified('x-appl/x-zip') # => 'appl/zip'
24
+ #
25
+ # puts MIME::Types.any? { |type|
26
+ # type.content_type == 'text/plain'
27
+ # } # => true
28
+ # puts MIME::Types.all?(&:registered?)
29
+ # # => false
30
+ class MIME::Type
31
+ # Reflects a MIME content-type specification that is not correctly
32
+ # formatted (it isn't +type+/+subtype+).
33
+ class InvalidContentType < ArgumentError
34
+ # :stopdoc:
35
+ def initialize(type_string)
36
+ @type_string = type_string
37
+ end
38
+
39
+ def to_s
40
+ "Invalid Content-Type #{@type_string.inspect}"
41
+ end
42
+ # :startdoc:
43
+ end
44
+
45
+ # Reflects an unsupported MIME encoding.
46
+ class InvalidEncoding < ArgumentError
47
+ # :stopdoc:
48
+ def initialize(encoding)
49
+ @encoding = encoding
50
+ end
51
+
52
+ def to_s
53
+ "Invalid Encoding #{@encoding.inspect} (valid values are " +
54
+ "#{MIME::Type::VALID_ENCODINGS.inspect})."
55
+ end
56
+ # :startdoc:
57
+ end
58
+
59
+ # The released version of the mime-types library.
60
+ VERSION = '2.0'
61
+
62
+ include Comparable
63
+
64
+ # :stopdoc:
65
+ MEDIA_TYPE_RE = %r{([-\w.+]+)/([-\w.+]*)}o
66
+ UNREGISTERED_RE = %r{[Xx]-}o
67
+ PLATFORM_RE = %r{#{RUBY_PLATFORM}}o
68
+
69
+ DEFAULT_ENCODINGS = [ nil, :default ]
70
+ BINARY_ENCODINGS = %w(base64 8bit)
71
+ TEXT_ENCODINGS = %w(7bit quoted-printable)
72
+ VALID_ENCODINGS = DEFAULT_ENCODINGS + BINARY_ENCODINGS + TEXT_ENCODINGS
73
+
74
+ IANA_URL = "http://www.iana.org/assignments/media-types/%s/%s"
75
+ RFC_URL = "http://rfc-editor.org/rfc/rfc%s.txt"
76
+ DRAFT_URL = "http://datatracker.ietf.org/public/idindex.cgi?command=id_details&filename=%s"
77
+ LTSW_URL = "http://www.ltsw.se/knbase/internet/%s.htp"
78
+ CONTACT_URL = "http://www.iana.org/assignments/contact-people.htm#%s"
79
+ # :startdoc:
80
+
81
+ # Builds a MIME::Type object from the provided MIME Content Type value
82
+ # (e.g., 'text/plain' or 'applicaton/x-eruby'). The constructed object is
83
+ # yielded to an optional block for additional configuration, such as
84
+ # associating extensions and encoding information.
85
+ #
86
+ # * When provided a Hash or a MIME::Type, the MIME::Type will be
87
+ # constructed with #init_with.
88
+ # * When provided an Array, the MIME::Type will be constructed only using
89
+ # the first two elements of the array as the content type and
90
+ # extensions.
91
+ # * Otherwise, the content_type will be used as a string.
92
+ def initialize(content_type) # :yields self:
93
+ self.system = nil
94
+ self.obsolete = false
95
+ self.registered = nil
96
+ self.use_instead = nil
97
+ self.signature = nil
98
+
99
+ case content_type
100
+ when Hash
101
+ init_with(content_type)
102
+ when Array
103
+ self.content_type = content_type[0]
104
+ self.extensions = content_type[1] || []
105
+ when MIME::Type
106
+ init_with(content_type.to_h)
107
+ else
108
+ self.content_type = content_type
109
+ end
110
+
111
+ self.extensions ||= []
112
+ self.docs ||= nil
113
+ self.encoding ||= :default
114
+ self.references ||= []
115
+
116
+ yield self if block_given?
117
+ end
118
+
119
+ # Returns +true+ if the simplified type matches the current
120
+ def like?(other)
121
+ if other.respond_to?(:simplified)
122
+ @simplified == other.simplified
123
+ else
124
+ @simplified == MIME::Type.simplified(other)
125
+ end
126
+ end
127
+
128
+ # Compares the MIME::Type against the exact content type or the simplified
129
+ # type (the simplified type will be used if comparing against something
130
+ # that can be treated as a String with #to_s). In comparisons, this is
131
+ # done against the lowercase version of the MIME::Type.
132
+ def <=>(other)
133
+ if other.respond_to?(:content_type)
134
+ @content_type.downcase <=> other.content_type.downcase
135
+ elsif other.respond_to?(:to_s)
136
+ @simplified <=> MIME::Type.simplified(other.to_s)
137
+ end
138
+ end
139
+
140
+ # Compares the MIME::Type based on how reliable it is before doing a
141
+ # normal <=> comparison. Used by MIME::Types#[] to sort types. The
142
+ # comparisons involved are:
143
+ #
144
+ # 1. self.simplified <=> other.simplified (ensures that we
145
+ # don't try to compare different types)
146
+ # 2. IANA-registered definitions < other definitions.
147
+ # 3. Generic definitions < platform definitions.
148
+ # 3. Complete definitions < incomplete definitions.
149
+ # 4. Current definitions < obsolete definitions.
150
+ # 5. Obselete with use-instead references < obsolete without.
151
+ # 6. Obsolete use-instead definitions are compared.
152
+ def priority_compare(other)
153
+ pc = simplified <=> other.simplified
154
+ if pc.zero?
155
+ pc = if (registered? != other.registered?)
156
+ registered? ? -1 : 1 # registered < unregistered
157
+ elsif (platform? != other.platform?)
158
+ platform? ? 1 : -1 # generic < platform
159
+ elsif (complete? != other.complete?)
160
+ complete? ? -1 : 1 # complete < incomplete
161
+ elsif (obsolete? != other.obsolete?)
162
+ obsolete? ? 1 : -1 # current < obsolete
163
+ elsif obsolete? and (use_instead != other.use_instead)
164
+ if use_instead.nil?
165
+ 1
166
+ elsif other.use_instead.nil?
167
+ -1
168
+ else
169
+ use_instead <=> other.use_instead
170
+ end
171
+ else
172
+ 0
173
+ end
174
+ end
175
+
176
+ pc
177
+ end
178
+
179
+ # Returns +true+ if the other object is a MIME::Type and the content types
180
+ # match.
181
+ def eql?(other)
182
+ other.kind_of?(MIME::Type) and self == other
183
+ end
184
+
185
+ # Returns the whole MIME content-type string.
186
+ #
187
+ # text/plain => text/plain
188
+ # x-chemical/x-pdb => x-chemical/x-pdb
189
+ attr_reader :content_type
190
+ # Returns the media type of the simplified MIME::Type.
191
+ #
192
+ # text/plain => text
193
+ # x-chemical/x-pdb => chemical
194
+ attr_reader :media_type
195
+ # Returns the media type of the unmodified MIME::Type.
196
+ #
197
+ # text/plain => text
198
+ # x-chemical/x-pdb => x-chemical
199
+ attr_reader :raw_media_type
200
+ # Returns the sub-type of the simplified MIME::Type.
201
+ #
202
+ # text/plain => plain
203
+ # x-chemical/x-pdb => pdb
204
+ attr_reader :sub_type
205
+ # Returns the media type of the unmodified MIME::Type.
206
+ #
207
+ # text/plain => plain
208
+ # x-chemical/x-pdb => x-pdb
209
+ attr_reader :raw_sub_type
210
+ # The MIME types main- and sub-label can both start with <tt>x-</tt>,
211
+ # which indicates that it is a non-registered name. Of course, after
212
+ # registration this flag can disappear, adds to the confusing
213
+ # proliferation of MIME types. The simplified string has the <tt>x-</tt>
214
+ # removed and are translated to lowercase.
215
+ #
216
+ # text/plain => text/plain
217
+ # x-chemical/x-pdb => chemical/pdb
218
+ attr_reader :simplified
219
+ # The list of extensions which are known to be used for this MIME::Type.
220
+ # Non-array values will be coerced into an array with #to_a. Array values
221
+ # will be flattened, +nil+ values removed, and made unique.
222
+ attr_reader :extensions
223
+ def extensions=(ext) # :nodoc:
224
+ @extensions = [ext].flatten.compact.sort.uniq
225
+ end
226
+
227
+ # Merge the extensions provided into this MIME::Type. The extensions added
228
+ # will be merged uniquely.
229
+ def add_extensions(*ext)
230
+ @extensions = (@extensions + ext).flatten.compact.sort.uniq
231
+ end
232
+
233
+ # The encoding (7bit, 8bit, quoted-printable, or base64) required to
234
+ # transport the data of this content type safely across a network, which
235
+ # roughly corresponds to Content-Transfer-Encoding. A value of +nil+ or
236
+ # <tt>:default</tt> will reset the #encoding to the #default_encoding for
237
+ # the MIME::Type. Raises ArgumentError if the encoding provided is
238
+ # invalid.
239
+ #
240
+ # If the encoding is not provided on construction, this will be either
241
+ # 'quoted-printable' (for text/* media types) and 'base64' for eveything
242
+ # else.
243
+ attr_reader :encoding
244
+ def encoding=(enc) # :nodoc:
245
+ if DEFAULT_ENCODINGS.include?(enc)
246
+ @encoding = self.default_encoding
247
+ elsif BINARY_ENCODINGS.include?(enc) or TEXT_ENCODINGS.include?(enc)
248
+ @encoding = enc
249
+ else
250
+ raise InvalidEncoding, enc
251
+ end
252
+ end
253
+
254
+ # If the MIME::Type is a system-specific MIME::Type, returns the regular
255
+ # expression for the operating system indicated.
256
+ #
257
+ # This information about MIME content types is deprecated.
258
+ def system
259
+ MIME.deprecated(self, __method__)
260
+ @system
261
+ end
262
+ def system=(os) # :nodoc:
263
+ if os.nil? or os.kind_of?(Regexp)
264
+ @system = os
265
+ else
266
+ @system = %r|#{os}|
267
+ end
268
+ end
269
+
270
+ # Returns the default encoding for the MIME::Type based on the media type.
271
+ def default_encoding
272
+ (@media_type == 'text') ? 'quoted-printable' : 'base64'
273
+ end
274
+
275
+ ##
276
+ # Returns the media type or types that should be used instead of this
277
+ # media type, if it is obsolete. If there is no replacement media type, or
278
+ # it is not obsolete, +nil+ will be returned.
279
+ def use_instead
280
+ return nil unless obsolete?
281
+ @use_instead
282
+ end
283
+ attr_writer :use_instead # :nodoc:
284
+
285
+ # Returns +true+ if the media type is obsolete.
286
+ def obsolete?
287
+ !!@obsolete
288
+ end
289
+ def obsolete=(v) # :nodoc:
290
+ @obsolete = !!v
291
+ end
292
+
293
+ # The documentation for this MIME::Type.
294
+ attr_accessor :docs
295
+
296
+ # The encoded references URL list for this MIME::Type. See #urls for more
297
+ # information.
298
+ #
299
+ # This was previously called #url.
300
+ attr_reader :references
301
+ def references=(r) # :nodoc:
302
+ @references = [ r ].flatten.compact.uniq
303
+ end
304
+
305
+ def url # :nodoc:
306
+ MIME.deprecated(self, __method__, "and has been renamed to #references")
307
+ references
308
+ end
309
+ def url=(r) # :nodoc:
310
+ MIME.deprecated(self, __method__, "and has been renamed to #references=")
311
+ self.references = r
312
+ end
313
+
314
+ # The decoded URL list for this MIME::Type.
315
+ #
316
+ # The special URL value IANA will be translated into:
317
+ # http://www.iana.org/assignments/media-types/<mediatype>/<subtype>
318
+ #
319
+ # The special URL value RFC### will be translated into:
320
+ # http://www.rfc-editor.org/rfc/rfc###.txt
321
+ #
322
+ # The special URL value DRAFT:name will be translated into:
323
+ # https://datatracker.ietf.org/public/idindex.cgi?
324
+ # command=id_detail&filename=<name>
325
+ #
326
+ # The special URL value LTSW will be translated into:
327
+ # http://www.ltsw.se/knbase/internet/<mediatype>.htp
328
+ #
329
+ # The special URL value [token] will be translated into:
330
+ # http://www.iana.org/assignments/contact-people.htm#<token>
331
+ #
332
+ # These values will be accessible through #urls, which always returns an
333
+ # array.
334
+ def urls
335
+ @references.map do |el|
336
+ case el
337
+ when %r{^IANA$}
338
+ IANA_URL % [ @media_type, @sub_type ]
339
+ when %r{^RFC(\d+)$}
340
+ RFC_URL % $1
341
+ when %r{^DRAFT:(.+)$}
342
+ DRAFT_URL % $1
343
+ when %r{^LTSW$}
344
+ LTSW_URL % @media_type
345
+ when %r{^\{([^=]+)=([^\}]+)\}}
346
+ [$1, $2]
347
+ when %r{^\[([^=]+)=([^\]]+)\]}
348
+ [$1, CONTACT_URL % $2]
349
+ when %r{^\[([^\]]+)\]}
350
+ CONTACT_URL % $1
351
+ else
352
+ el
353
+ end
354
+ end
355
+ end
356
+
357
+ # Prior to BCP 178 (RFC 6648), it could be assumed that MIME content types
358
+ # that start with <tt>x-</tt> were unregistered MIME. Per this BCP, this
359
+ # assumption is no longer being made by default in this library.
360
+ #
361
+ # There are three possible registration states for a MIME::Type:
362
+ # - Explicitly registered, like application/x-www-url-encoded.
363
+ # - Explicitly not registered, like image/webp.
364
+ # - Unspecified, in which case the media-type and the content-type will be
365
+ # scanned to see if they start with <tt>x-</tt>, indicating that they
366
+ # are assumed unregistered.
367
+ def registered?
368
+ if @registered.nil?
369
+ (@raw_media_type !~ UNREGISTERED_RE) and
370
+ (@raw_sub_type !~ UNREGISTERED_RE)
371
+ else
372
+ !!@registered
373
+ end
374
+ end
375
+ def registered=(v) # :nodoc:
376
+ @registered = v.nil? ? v : !!v
377
+ end
378
+
379
+ # MIME types can be specified to be sent across a network in particular
380
+ # formats. This method returns +true+ when the MIME::Type encoding is set
381
+ # to <tt>base64</tt>.
382
+ def binary?
383
+ BINARY_ENCODINGS.include?(@encoding)
384
+ end
385
+
386
+ # MIME types can be specified to be sent across a network in particular
387
+ # formats. This method returns +false+ when the MIME::Type encoding is
388
+ # set to <tt>base64</tt>.
389
+ def ascii?
390
+ not binary?
391
+ end
392
+
393
+ # Returns +true+ when the simplified MIME::Type is in the list of known
394
+ # digital signatures.
395
+ def signature?
396
+ !!@signature
397
+ end
398
+ def signature=(v) # :nodoc:
399
+ @signature = !!v
400
+ end
401
+
402
+ # Returns +true+ if the MIME::Type is specific to an operating system.
403
+ #
404
+ # This method is deprecated.
405
+ def system?
406
+ MIME.deprecated(self, __method__)
407
+ not @system.nil?
408
+ end
409
+
410
+ # Returns +true+ if the MIME::Type is specific to the current operating
411
+ # system as represented by RUBY_PLATFORM.
412
+ #
413
+ # This method is deprecated.
414
+ def platform?
415
+ MIME.deprecated(self, __method__)
416
+ system? and (RUBY_PLATFORM =~ @system)
417
+ end
418
+
419
+ # Returns +true+ if the MIME::Type specifies an extension list,
420
+ # indicating that it is a complete MIME::Type.
421
+ def complete?
422
+ not @extensions.empty?
423
+ end
424
+
425
+ # Returns the MIME::Type as a string.
426
+ def to_s
427
+ @content_type
428
+ end
429
+
430
+ # Returns the MIME::Type as a string for implicit conversions. This allows
431
+ # MIME::Type objects to appear on either side of a comparison.
432
+ #
433
+ # 'text/plain' == MIME::Type.new('text/plain')
434
+ def to_str
435
+ @content_type
436
+ end
437
+
438
+ # Returns the MIME::Type as an array suitable for use with
439
+ # MIME::Type.from_array.
440
+ #
441
+ # This method is deprecated.
442
+ def to_a
443
+ MIME.deprecated(self, __method__)
444
+ [ @content_type, @extensions, @encoding, @system, obsolete?, @docs,
445
+ @references, registered? ]
446
+ end
447
+
448
+ # Returns the MIME::Type as an array suitable for use with
449
+ # MIME::Type.from_hash.
450
+ #
451
+ # This method is deprecated.
452
+ def to_hash
453
+ MIME.deprecated(self, __method__)
454
+ { 'Content-Type' => @content_type,
455
+ 'Content-Transfer-Encoding' => @encoding,
456
+ 'Extensions' => @extensions,
457
+ 'System' => @system,
458
+ 'Obsolete' => obsolete?,
459
+ 'Docs' => @docs,
460
+ 'URL' => @references,
461
+ 'Registered' => registered?,
462
+ }
463
+ end
464
+
465
+ # Converts the MIME::Type to a JSON string.
466
+ def to_json(*args)
467
+ to_h.to_json(*args)
468
+ end
469
+
470
+ # Converts the MIME::Type to a hash suitable for use in JSON. The output
471
+ # of this method can also be used to initialize a MIME::Type.
472
+ def to_h
473
+ encode_with({})
474
+ end
475
+
476
+ # :stopdoc:
477
+ def encode_with(coder)
478
+ coder['content-type'] = @content_type
479
+ coder['docs'] = @docs unless @docs.nil? or @docs.empty?
480
+ coder['encoding'] = @encoding
481
+ coder['extensions'] = @extensions unless @extensions.empty?
482
+ if obsolete?
483
+ coder['obsolete'] = obsolete?
484
+ coder['use-instead'] = use_instead if use_instead
485
+ end
486
+ coder['references'] = references unless references.empty?
487
+ coder['registered'] = registered?
488
+ if signature?
489
+ coder['signature'] = signature?
490
+ end
491
+ coder['system'] = @system if @system
492
+ coder
493
+ end
494
+
495
+ def init_with(coder)
496
+ self.content_type = coder['content-type']
497
+ self.docs = coder['docs'] || []
498
+ self.encoding = coder['encoding']
499
+ self.extensions = coder['extensions'] || []
500
+ self.obsolete = coder['obsolete']
501
+ self.references = coder['references'] || []
502
+ self.registered = coder['registered']
503
+ self.signature = coder['signature']
504
+ self.system = coder['system']
505
+ self.use_instead = coder['use-instead']
506
+ end
507
+ # :startdoc:
508
+
509
+ class << self
510
+ # The MIME types main- and sub-label can both start with <tt>x-</tt>,
511
+ # which indicates that it is a non-registered name. Of course, after
512
+ # registration this flag can disappear, adds to the confusing
513
+ # proliferation of MIME types. The simplified string has the <tt>x-</tt>
514
+ # removed and are translated to lowercase.
515
+ def simplified(content_type)
516
+ matchdata = MEDIA_TYPE_RE.match(content_type)
517
+
518
+ if matchdata.nil?
519
+ nil
520
+ else
521
+ matchdata.captures.map { |e|
522
+ e.downcase.gsub(UNREGISTERED_RE, '')
523
+ }.join('/')
524
+ end
525
+ end
526
+
527
+ # Creates a MIME::Type from an array in the form of:
528
+ # [type-name, [extensions], encoding, system]
529
+ #
530
+ # +extensions+, +encoding+, and +system+ are optional.
531
+ #
532
+ # MIME::Type.from_array("application/x-ruby", ['rb'], '8bit')
533
+ # MIME::Type.from_array(["application/x-ruby", ['rb'], '8bit'])
534
+ #
535
+ # These are equivalent to:
536
+ #
537
+ # MIME::Type.new('application/x-ruby') do |t|
538
+ # t.extensions = %w(rb)
539
+ # t.encoding = '8bit'
540
+ # end
541
+ #
542
+ # This method is deprecated.
543
+ def from_array(*args) # :yields MIME::Type.new:
544
+ MIME.deprecated(self, __method__)
545
+
546
+ # Dereferences the array one level, if necessary.
547
+ args = args.first if args.first.kind_of? Array
548
+
549
+ unless args.size.between?(1, 8)
550
+ raise ArgumentError, "Array provided must contain between one and eight elements."
551
+ end
552
+
553
+ MIME::Type.new(args.shift) do |t|
554
+ t.extensions, t.encoding, t.system, t.obsolete, t.docs, t.references,
555
+ t.registered = *args
556
+ yield t if block_given?
557
+ end
558
+ end
559
+
560
+ # Creates a MIME::Type from a hash. Keys are case-insensitive, dashes
561
+ # may be replaced with underscores, and the internal Symbol of the
562
+ # lowercase-underscore version can be used as well. That is,
563
+ # Content-Type can be provided as content-type, Content_Type,
564
+ # content_type, or :content_type.
565
+ #
566
+ # Known keys are <tt>Content-Type</tt>,
567
+ # <tt>Content-Transfer-Encoding</tt>, <tt>Extensions</tt>, and
568
+ # <tt>System</tt>.
569
+ #
570
+ # MIME::Type.from_hash('Content-Type' => 'text/x-yaml',
571
+ # 'Content-Transfer-Encoding' => '8bit',
572
+ # 'System' => 'linux',
573
+ # 'Extensions' => ['yaml', 'yml'])
574
+ #
575
+ # This is equivalent to:
576
+ #
577
+ # MIME::Type.new('text/x-yaml') do |t|
578
+ # t.encoding = '8bit'
579
+ # t.system = 'linux'
580
+ # t.extensions = ['yaml', 'yml']
581
+ # end
582
+ #
583
+ # This method has been deprecated.
584
+ def from_hash(hash) # :yields MIME::Type.new:
585
+ MIME.deprecated(self, __method__)
586
+ type = {}
587
+ hash.each_pair do |k, v|
588
+ type[k.to_s.tr('A-Z', 'a-z').gsub(/-/, '_').to_sym] = v
589
+ end
590
+
591
+ MIME::Type.new(type[:content_type]) do |t|
592
+ t.extensions = type[:extensions]
593
+ t.encoding = type[:content_transfer_encoding]
594
+ t.system = type[:system]
595
+ t.obsolete = type[:obsolete]
596
+ t.docs = type[:docs]
597
+ t.url = type[:url]
598
+ t.registered = type[:registered]
599
+
600
+ yield t if block_given?
601
+ end
602
+ end
603
+
604
+ # Essentially a copy constructor.
605
+ #
606
+ # MIME::Type.from_mime_type(plaintext)
607
+ #
608
+ # is equivalent to:
609
+ #
610
+ # MIME::Type.new(plaintext.content_type.dup) do |t|
611
+ # t.extensions = plaintext.extensions.dup
612
+ # t.system = plaintext.system.dup
613
+ # t.encoding = plaintext.encoding.dup
614
+ # end
615
+ #
616
+ # This method has been deprecated.
617
+ def from_mime_type(mime_type) # :yields the new MIME::Type:
618
+ MIME.deprecated(self, __method__)
619
+ new(mime_type)
620
+ end
621
+ end
622
+
623
+ private
624
+ def content_type=(type_string)
625
+ match = MEDIA_TYPE_RE.match(type_string)
626
+ raise InvalidContentType, type_string if match.nil?
627
+
628
+ @content_type = type_string
629
+ @raw_media_type, @raw_sub_type = *match.captures
630
+ @simplified = MIME::Type.simplified(type_string)
631
+ @media_type, @sub_type =
632
+ *MEDIA_TYPE_RE.match(@simplified).captures
633
+ end
634
+ end