mail 2.6.1 → 2.8.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.
Files changed (188) hide show
  1. checksums.yaml +5 -5
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +150 -107
  4. data/lib/mail/attachments_list.rb +13 -10
  5. data/lib/mail/body.rb +104 -90
  6. data/lib/mail/check_delivery_params.rb +55 -10
  7. data/lib/mail/configuration.rb +3 -0
  8. data/lib/mail/constants.rb +79 -0
  9. data/lib/mail/elements/address.rb +96 -108
  10. data/lib/mail/elements/address_list.rb +13 -30
  11. data/lib/mail/elements/content_disposition_element.rb +10 -16
  12. data/lib/mail/elements/content_location_element.rb +9 -13
  13. data/lib/mail/elements/content_transfer_encoding_element.rb +7 -11
  14. data/lib/mail/elements/content_type_element.rb +17 -23
  15. data/lib/mail/elements/date_time_element.rb +8 -15
  16. data/lib/mail/elements/envelope_from_element.rb +23 -23
  17. data/lib/mail/elements/message_ids_element.rb +22 -15
  18. data/lib/mail/elements/mime_version_element.rb +8 -15
  19. data/lib/mail/elements/phrase_list.rb +13 -10
  20. data/lib/mail/elements/received_element.rb +28 -19
  21. data/lib/mail/elements.rb +1 -0
  22. data/lib/mail/encodings/7bit.rb +10 -14
  23. data/lib/mail/encodings/8bit.rb +5 -18
  24. data/lib/mail/encodings/base64.rb +15 -10
  25. data/lib/mail/encodings/binary.rb +4 -22
  26. data/lib/mail/encodings/identity.rb +24 -0
  27. data/lib/mail/encodings/quoted_printable.rb +13 -7
  28. data/lib/mail/encodings/transfer_encoding.rb +47 -28
  29. data/lib/mail/encodings/unix_to_unix.rb +20 -0
  30. data/lib/mail/encodings.rb +102 -92
  31. data/lib/mail/envelope.rb +12 -14
  32. data/lib/mail/field.rb +121 -85
  33. data/lib/mail/field_list.rb +62 -8
  34. data/lib/mail/fields/bcc_field.rb +42 -48
  35. data/lib/mail/fields/cc_field.rb +29 -50
  36. data/lib/mail/fields/comments_field.rb +28 -37
  37. data/lib/mail/fields/common_address_field.rb +170 -0
  38. data/lib/mail/fields/common_date_field.rb +58 -0
  39. data/lib/mail/fields/common_field.rb +77 -0
  40. data/lib/mail/fields/common_message_id_field.rb +42 -0
  41. data/lib/mail/fields/content_description_field.rb +8 -14
  42. data/lib/mail/fields/content_disposition_field.rb +20 -44
  43. data/lib/mail/fields/content_id_field.rb +25 -51
  44. data/lib/mail/fields/content_location_field.rb +12 -25
  45. data/lib/mail/fields/content_transfer_encoding_field.rb +32 -31
  46. data/lib/mail/fields/content_type_field.rb +51 -80
  47. data/lib/mail/fields/date_field.rb +24 -52
  48. data/lib/mail/fields/from_field.rb +29 -50
  49. data/lib/mail/fields/in_reply_to_field.rb +39 -49
  50. data/lib/mail/fields/keywords_field.rb +19 -32
  51. data/lib/mail/fields/message_id_field.rb +26 -71
  52. data/lib/mail/fields/mime_version_field.rb +20 -30
  53. data/lib/mail/fields/named_structured_field.rb +11 -0
  54. data/lib/mail/fields/named_unstructured_field.rb +11 -0
  55. data/lib/mail/fields/optional_field.rb +10 -7
  56. data/lib/mail/fields/{common/parameter_hash.rb → parameter_hash.rb} +16 -13
  57. data/lib/mail/fields/received_field.rb +44 -57
  58. data/lib/mail/fields/references_field.rb +36 -49
  59. data/lib/mail/fields/reply_to_field.rb +29 -50
  60. data/lib/mail/fields/resent_bcc_field.rb +29 -50
  61. data/lib/mail/fields/resent_cc_field.rb +29 -50
  62. data/lib/mail/fields/resent_date_field.rb +6 -30
  63. data/lib/mail/fields/resent_from_field.rb +29 -50
  64. data/lib/mail/fields/resent_message_id_field.rb +6 -29
  65. data/lib/mail/fields/resent_sender_field.rb +28 -57
  66. data/lib/mail/fields/resent_to_field.rb +29 -50
  67. data/lib/mail/fields/return_path_field.rb +51 -55
  68. data/lib/mail/fields/sender_field.rb +35 -56
  69. data/lib/mail/fields/structured_field.rb +4 -30
  70. data/lib/mail/fields/subject_field.rb +10 -11
  71. data/lib/mail/fields/to_field.rb +29 -50
  72. data/lib/mail/fields/unstructured_field.rb +36 -50
  73. data/lib/mail/fields.rb +1 -0
  74. data/lib/mail/header.rb +73 -110
  75. data/lib/mail/indifferent_hash.rb +1 -0
  76. data/lib/mail/mail.rb +6 -11
  77. data/lib/mail/matchers/attachment_matchers.rb +44 -0
  78. data/lib/mail/matchers/has_sent_mail.rb +53 -9
  79. data/lib/mail/message.rb +132 -136
  80. data/lib/mail/multibyte/chars.rb +24 -180
  81. data/lib/mail/multibyte/unicode.rb +31 -26
  82. data/lib/mail/multibyte/utils.rb +27 -43
  83. data/lib/mail/multibyte.rb +56 -16
  84. data/lib/mail/network/delivery_methods/exim.rb +9 -11
  85. data/lib/mail/network/delivery_methods/file_delivery.rb +14 -16
  86. data/lib/mail/network/delivery_methods/logger_delivery.rb +34 -0
  87. data/lib/mail/network/delivery_methods/sendmail.rb +68 -24
  88. data/lib/mail/network/delivery_methods/smtp.rb +77 -54
  89. data/lib/mail/network/delivery_methods/smtp_connection.rb +5 -9
  90. data/lib/mail/network/delivery_methods/test_mailer.rb +9 -9
  91. data/lib/mail/network/retriever_methods/base.rb +9 -8
  92. data/lib/mail/network/retriever_methods/imap.rb +21 -7
  93. data/lib/mail/network/retriever_methods/pop3.rb +6 -3
  94. data/lib/mail/network/retriever_methods/test_retriever.rb +4 -2
  95. data/lib/mail/network.rb +2 -0
  96. data/lib/mail/parser_tools.rb +15 -0
  97. data/lib/mail/parsers/address_lists_parser.rb +33226 -116
  98. data/lib/mail/parsers/address_lists_parser.rl +179 -0
  99. data/lib/mail/parsers/content_disposition_parser.rb +883 -49
  100. data/lib/mail/parsers/content_disposition_parser.rl +89 -0
  101. data/lib/mail/parsers/content_location_parser.rb +810 -23
  102. data/lib/mail/parsers/content_location_parser.rl +78 -0
  103. data/lib/mail/parsers/content_transfer_encoding_parser.rb +510 -21
  104. data/lib/mail/parsers/content_transfer_encoding_parser.rl +71 -0
  105. data/lib/mail/parsers/content_type_parser.rb +1031 -47
  106. data/lib/mail/parsers/content_type_parser.rl +90 -0
  107. data/lib/mail/parsers/date_time_parser.rb +879 -24
  108. data/lib/mail/parsers/date_time_parser.rl +69 -0
  109. data/lib/mail/parsers/envelope_from_parser.rb +3670 -40
  110. data/lib/mail/parsers/envelope_from_parser.rl +89 -0
  111. data/lib/mail/parsers/message_ids_parser.rb +5147 -25
  112. data/lib/mail/parsers/message_ids_parser.rl +93 -0
  113. data/lib/mail/parsers/mime_version_parser.rb +498 -26
  114. data/lib/mail/parsers/mime_version_parser.rl +68 -0
  115. data/lib/mail/parsers/phrase_lists_parser.rb +872 -21
  116. data/lib/mail/parsers/phrase_lists_parser.rl +90 -0
  117. data/lib/mail/parsers/received_parser.rb +8777 -42
  118. data/lib/mail/parsers/received_parser.rl +91 -0
  119. data/lib/mail/parsers/rfc2045_content_transfer_encoding.rl +13 -0
  120. data/lib/mail/parsers/rfc2045_content_type.rl +25 -0
  121. data/lib/mail/parsers/rfc2045_mime.rl +16 -0
  122. data/lib/mail/parsers/rfc2183_content_disposition.rl +15 -0
  123. data/lib/mail/parsers/rfc3629_utf8.rl +19 -0
  124. data/lib/mail/parsers/rfc5234_abnf_core_rules.rl +22 -0
  125. data/lib/mail/parsers/rfc5322.rl +74 -0
  126. data/lib/mail/parsers/rfc5322_address.rl +72 -0
  127. data/lib/mail/parsers/{ragel/date_time.rl → rfc5322_date_time.rl} +8 -1
  128. data/lib/mail/parsers/rfc5322_lexical_tokens.rl +60 -0
  129. data/lib/mail/parsers.rb +12 -25
  130. data/lib/mail/part.rb +11 -12
  131. data/lib/mail/parts_list.rb +88 -14
  132. data/lib/mail/smtp_envelope.rb +57 -0
  133. data/lib/mail/utilities.rb +377 -40
  134. data/lib/mail/values/unicode_tables.dat +0 -0
  135. data/lib/mail/version.rb +8 -15
  136. data/lib/mail/yaml.rb +30 -0
  137. data/lib/mail.rb +9 -32
  138. metadata +138 -94
  139. data/CHANGELOG.rdoc +0 -752
  140. data/CONTRIBUTING.md +0 -60
  141. data/Dependencies.txt +0 -2
  142. data/Gemfile +0 -15
  143. data/Rakefile +0 -29
  144. data/TODO.rdoc +0 -9
  145. data/VERSION +0 -4
  146. data/lib/mail/core_extensions/nil.rb +0 -19
  147. data/lib/mail/core_extensions/object.rb +0 -13
  148. data/lib/mail/core_extensions/smtp.rb +0 -24
  149. data/lib/mail/core_extensions/string/access.rb +0 -145
  150. data/lib/mail/core_extensions/string/multibyte.rb +0 -78
  151. data/lib/mail/core_extensions/string.rb +0 -43
  152. data/lib/mail/fields/common/address_container.rb +0 -16
  153. data/lib/mail/fields/common/common_address.rb +0 -135
  154. data/lib/mail/fields/common/common_date.rb +0 -35
  155. data/lib/mail/fields/common/common_field.rb +0 -57
  156. data/lib/mail/fields/common/common_message_id.rb +0 -48
  157. data/lib/mail/multibyte/exceptions.rb +0 -8
  158. data/lib/mail/parsers/ragel/common.rl +0 -184
  159. data/lib/mail/parsers/ragel/parser_info.rb +0 -61
  160. data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb +0 -14864
  161. data/lib/mail/parsers/ragel/ruby/machines/address_lists_machine.rb.rl +0 -37
  162. data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb +0 -751
  163. data/lib/mail/parsers/ragel/ruby/machines/content_disposition_machine.rb.rl +0 -37
  164. data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb +0 -614
  165. data/lib/mail/parsers/ragel/ruby/machines/content_location_machine.rb.rl +0 -37
  166. data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb +0 -447
  167. data/lib/mail/parsers/ragel/ruby/machines/content_transfer_encoding_machine.rb.rl +0 -37
  168. data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb +0 -825
  169. data/lib/mail/parsers/ragel/ruby/machines/content_type_machine.rb.rl +0 -37
  170. data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb +0 -817
  171. data/lib/mail/parsers/ragel/ruby/machines/date_time_machine.rb.rl +0 -37
  172. data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb +0 -2129
  173. data/lib/mail/parsers/ragel/ruby/machines/envelope_from_machine.rb.rl +0 -37
  174. data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb +0 -1570
  175. data/lib/mail/parsers/ragel/ruby/machines/message_ids_machine.rb.rl +0 -37
  176. data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb +0 -440
  177. data/lib/mail/parsers/ragel/ruby/machines/mime_version_machine.rb.rl +0 -37
  178. data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb +0 -564
  179. data/lib/mail/parsers/ragel/ruby/machines/phrase_lists_machine.rb.rl +0 -37
  180. data/lib/mail/parsers/ragel/ruby/machines/rb_actions.rl +0 -51
  181. data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb +0 -5144
  182. data/lib/mail/parsers/ragel/ruby/machines/received_machine.rb.rl +0 -37
  183. data/lib/mail/parsers/ragel/ruby/parser.rb.rl.erb +0 -37
  184. data/lib/mail/parsers/ragel/ruby.rb +0 -39
  185. data/lib/mail/parsers/ragel.rb +0 -17
  186. data/lib/mail/patterns.rb +0 -37
  187. data/lib/mail/version_specific/ruby_1_8.rb +0 -119
  188. data/lib/mail/version_specific/ruby_1_9.rb +0 -159
@@ -1,37 +0,0 @@
1
- %%{
2
- machine received;
3
-
4
- include rb_actions "rb_actions.rl";
5
- include common "../../common.rl";
6
-
7
- getkey data_unpacked[p];
8
-
9
- main := received;
10
- }%%
11
-
12
- module Mail
13
- module Parsers
14
- module Ragel
15
- module ReceivedMachine
16
- %%write data;
17
-
18
- def self.parse(data)
19
- p = 0
20
- eof = data.length
21
- stack = []
22
-
23
- actions = []
24
- data_unpacked = data.bytes.to_a
25
- %%write init;
26
- %%write exec;
27
-
28
- if p == eof && cs >= %%{ write first_final; }%%
29
- return actions, nil
30
- else
31
- return [], "Only able to parse up to #{data[0..p]}"
32
- end
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,37 +0,0 @@
1
- %%{
2
- machine <%= parser_name %>;
3
-
4
- include rb_actions "rb_actions.rl";
5
- include common "../../common.rl";
6
-
7
- getkey data_unpacked[p];
8
-
9
- main := <%= parser_name %>;
10
- }%%
11
-
12
- module Mail
13
- module Parsers
14
- module Ragel
15
- module <%= parser_name_cc %>
16
- %%write data;
17
-
18
- def self.parse(data)
19
- p = 0
20
- eof = data.length
21
- stack = []
22
-
23
- actions = []
24
- data_unpacked = data.bytes.to_a
25
- %%write init;
26
- %%write exec;
27
-
28
- if p == eof && cs >= %%{ write first_final; }%%
29
- return actions, nil
30
- else
31
- return [], "Only able to parse up to #{data[0..p]}"
32
- end
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,39 +0,0 @@
1
- module Mail
2
- module Parsers
3
- module Ragel
4
- module Ruby
5
- def self.silence_warnings
6
- original_verbose = $VERBOSE
7
- $VERBOSE = nil
8
- yield
9
- $VERBOSE = original_verbose
10
- end
11
- # Ragel-generated parsers give a lot of warnings
12
- # and may cause logs to balloon in size
13
- silence_warnings do
14
- Mail::Parsers::Ragel::FIELD_PARSERS.each do |field_parser|
15
- require "mail/parsers/ragel/ruby/machines/#{field_parser}_machine"
16
- end
17
- end
18
-
19
- MACHINE_LIST = {
20
- :address_lists => AddressListsMachine,
21
- :phrase_lists => PhraseListsMachine,
22
- :date_time => DateTimeMachine,
23
- :received => ReceivedMachine,
24
- :message_ids => MessageIdsMachine,
25
- :envelope_from => EnvelopeFromMachine,
26
- :mime_version => MimeVersionMachine,
27
- :content_type => ContentTypeMachine,
28
- :content_disposition => ContentDispositionMachine,
29
- :content_transfer_encoding => ContentTransferEncodingMachine,
30
- :content_location => ContentLocationMachine
31
- }
32
-
33
- def self.parse(machine, string)
34
- MACHINE_LIST[machine].parse(string)
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,17 +0,0 @@
1
- module Mail
2
- module Parsers
3
- module Ragel
4
- require 'mail/parsers/ragel/parser_info'
5
- require "mail/parsers/ragel/ruby"
6
-
7
- def self.parse(machine, string)
8
- @machine_module ||= Ruby
9
- @machine_module.parse(machine, string)
10
- end
11
-
12
- def self.machine_module=(m)
13
- @machine_module = m
14
- end
15
- end
16
- end
17
- end
data/lib/mail/patterns.rb DELETED
@@ -1,37 +0,0 @@
1
- # encoding: us-ascii
2
- module Mail
3
- module Patterns
4
- white_space = %Q|\x9\x20|
5
- text = %Q|\x1-\x8\xB\xC\xE-\x7f|
6
- field_name = %Q|\x21-\x39\x3b-\x7e|
7
- qp_safe = %Q|\x20-\x3c\x3e-\x7e|
8
-
9
- aspecial = %Q|()<>[]:;@\\,."| # RFC5322
10
- tspecial = %Q|()<>@,;:\\"/[]?=| # RFC2045
11
- sp = %Q| |
12
- control = %Q|\x00-\x1f\x7f-\xff|
13
-
14
- if control.respond_to?(:force_encoding)
15
- control = control.force_encoding(Encoding::BINARY)
16
- end
17
-
18
- CRLF = /\r\n/
19
- WSP = /[#{white_space}]/
20
- FWS = /#{CRLF}#{WSP}*/
21
- TEXT = /[#{text}]/ # + obs-text
22
- FIELD_NAME = /[#{field_name}]+/
23
- FIELD_PREFIX = /\A(#{FIELD_NAME})/
24
- FIELD_BODY = /.+/m
25
- FIELD_LINE = /^[#{field_name}]+:\s*.+$/
26
- FIELD_SPLIT = /^(#{FIELD_NAME})\s*:\s*(#{FIELD_BODY})?$/
27
- HEADER_LINE = /^([#{field_name}]+:\s*.+)$/
28
- HEADER_SPLIT = /#{CRLF}(?!#{WSP})/
29
-
30
- QP_UNSAFE = /[^#{qp_safe}]/
31
- QP_SAFE = /[#{qp_safe}]/
32
- CONTROL_CHAR = /[#{control}]/n
33
- ATOM_UNSAFE = /[#{Regexp.quote aspecial}#{control}#{sp}]/n
34
- PHRASE_UNSAFE = /[#{Regexp.quote aspecial}#{control}]/n
35
- TOKEN_UNSAFE = /[#{Regexp.quote tspecial}#{control}#{sp}]/n
36
- end
37
- end
@@ -1,119 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Mail
4
- class Ruby18
5
- require 'base64'
6
- require 'iconv'
7
-
8
- # Escapes any parenthesis in a string that are unescaped. This can't
9
- # use the Ruby 1.9.1 regexp feature of negative look behind so we have
10
- # to do two replacement, first unescape everything, then re-escape it
11
- def Ruby18.escape_paren( str )
12
- re = /\\\)/
13
- str = str.gsub(re) { |s| ')'}
14
- re = /\\\(/
15
- str = str.gsub(re) { |s| '('}
16
- re = /([\(\)])/ # Only match unescaped parens
17
- str.gsub(re) { |s| '\\' + s }
18
- end
19
-
20
- def Ruby18.paren( str )
21
- str = $1 if str =~ /^\((.*)?\)$/
22
- str = escape_paren( str )
23
- '(' + str + ')'
24
- end
25
-
26
- def Ruby18.escape_bracket( str )
27
- re = /\\\>/
28
- str = str.gsub(re) { |s| '>'}
29
- re = /\\\</
30
- str = str.gsub(re) { |s| '<'}
31
- re = /([\<\>])/ # Only match unescaped parens
32
- str.gsub(re) { |s| '\\' + s }
33
- end
34
-
35
- def Ruby18.bracket( str )
36
- str = $1 if str =~ /^\<(.*)?\>$/
37
- str = escape_bracket( str )
38
- '<' + str + '>'
39
- end
40
-
41
- def Ruby18.decode_base64(str)
42
- Base64.decode64(str) if str
43
- end
44
-
45
- def Ruby18.encode_base64(str)
46
- Base64.encode64(str)
47
- end
48
-
49
- def Ruby18.has_constant?(klass, string)
50
- klass.constants.include?( string )
51
- end
52
-
53
- def Ruby18.get_constant(klass, string)
54
- klass.const_get( string )
55
- end
56
-
57
- def Ruby18.b_value_encode(str, encoding)
58
- # Ruby 1.8 requires an encoding to work
59
- raise ArgumentError, "Must supply an encoding" if encoding.nil?
60
- encoding = encoding.to_s.upcase.gsub('_', '-')
61
- [Encodings::Base64.encode(str), fix_encoding(encoding)]
62
- end
63
-
64
- def Ruby18.b_value_decode(str)
65
- match = str.match(/\=\?(.+)?\?[Bb]\?(.+)?\?\=/m)
66
- if match
67
- encoding = match[1]
68
- str = Ruby18.decode_base64(match[2])
69
- str = Iconv.conv('UTF-8//IGNORE', fix_encoding(encoding), str)
70
- end
71
- str
72
- end
73
-
74
- def Ruby18.q_value_encode(str, encoding)
75
- # Ruby 1.8 requires an encoding to work
76
- raise ArgumentError, "Must supply an encoding" if encoding.nil?
77
- encoding = encoding.to_s.upcase.gsub('_', '-')
78
- [Encodings::QuotedPrintable.encode(str), encoding]
79
- end
80
-
81
- def Ruby18.q_value_decode(str)
82
- match = str.match(/\=\?(.+)?\?[Qq]\?(.+)?\?\=/m)
83
- if match
84
- encoding = match[1]
85
- string = match[2].gsub(/_/, '=20')
86
- # Remove trailing = if it exists in a Q encoding
87
- string = string.sub(/\=$/, '')
88
- str = Encodings::QuotedPrintable.decode(string)
89
- str = Iconv.conv('UTF-8//IGNORE', fix_encoding(encoding), str)
90
- end
91
- str
92
- end
93
-
94
- def Ruby18.param_decode(str, encoding)
95
- URI.unescape(str)
96
- end
97
-
98
- def Ruby18.param_encode(str)
99
- encoding = $KCODE.to_s.downcase
100
- language = Configuration.instance.param_encode_language
101
- "#{encoding}'#{language}'#{URI.escape(str)}"
102
- end
103
-
104
- private
105
-
106
- def Ruby18.fix_encoding(encoding)
107
- case encoding.upcase
108
- when 'UTF8', 'UTF_8'
109
- 'UTF-8'
110
- when 'UTF16', 'UTF-16'
111
- 'UTF-16BE'
112
- when 'UTF32', 'UTF-32'
113
- 'UTF-32BE'
114
- else
115
- encoding
116
- end
117
- end
118
- end
119
- end
@@ -1,159 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Mail
4
- class Ruby19
5
-
6
- # Escapes any parenthesis in a string that are unescaped this uses
7
- # a Ruby 1.9.1 regexp feature of negative look behind
8
- def Ruby19.escape_paren( str )
9
- re = /(?<!\\)([\(\)])/ # Only match unescaped parens
10
- str.gsub(re) { |s| '\\' + s }
11
- end
12
-
13
- def Ruby19.paren( str )
14
- str = $1 if str =~ /^\((.*)?\)$/
15
- str = escape_paren( str )
16
- '(' + str + ')'
17
- end
18
-
19
- def Ruby19.escape_bracket( str )
20
- re = /(?<!\\)([\<\>])/ # Only match unescaped brackets
21
- str.gsub(re) { |s| '\\' + s }
22
- end
23
-
24
- def Ruby19.bracket( str )
25
- str = $1 if str =~ /^\<(.*)?\>$/
26
- str = escape_bracket( str )
27
- '<' + str + '>'
28
- end
29
-
30
- def Ruby19.decode_base64(str)
31
- str.unpack( 'm' ).first
32
- end
33
-
34
- def Ruby19.encode_base64(str)
35
- [str].pack( 'm' )
36
- end
37
-
38
- def Ruby19.has_constant?(klass, string)
39
- klass.const_defined?( string, false )
40
- end
41
-
42
- def Ruby19.get_constant(klass, string)
43
- klass.const_get( string )
44
- end
45
-
46
- def Ruby19.b_value_encode(str, encoding = nil)
47
- encoding = str.encoding.to_s
48
- [Ruby19.encode_base64(str), encoding]
49
- end
50
-
51
- def Ruby19.b_value_decode(str)
52
- match = str.match(/\=\?(.+)?\?[Bb]\?(.+)?\?\=/m)
53
- if match
54
- charset = match[1]
55
- str = Ruby19.decode_base64(match[2])
56
- str.force_encoding(pick_encoding(charset))
57
- end
58
- decoded = str.encode("utf-8", :invalid => :replace, :replace => "")
59
- decoded.valid_encoding? ? decoded : decoded.encode("utf-16le", :invalid => :replace, :replace => "").encode("utf-8")
60
- end
61
-
62
- def Ruby19.q_value_encode(str, encoding = nil)
63
- encoding = str.encoding.to_s
64
- [Encodings::QuotedPrintable.encode(str), encoding]
65
- end
66
-
67
- def Ruby19.q_value_decode(str)
68
- match = str.match(/\=\?(.+)?\?[Qq]\?(.+)?\?\=/m)
69
- if match
70
- charset = match[1]
71
- string = match[2].gsub(/_/, '=20')
72
- # Remove trailing = if it exists in a Q encoding
73
- string = string.sub(/\=$/, '')
74
- str = Encodings::QuotedPrintable.decode(string)
75
- str.force_encoding(pick_encoding(charset))
76
- # We assume that binary strings hold utf-8 directly to work around
77
- # jruby/jruby#829 which subtly changes String#encode semantics.
78
- str.force_encoding('utf-8') if str.encoding == Encoding::ASCII_8BIT
79
- end
80
- decoded = str.encode("utf-8", :invalid => :replace, :replace => "")
81
- decoded.valid_encoding? ? decoded : decoded.encode("utf-16le", :invalid => :replace, :replace => "").encode("utf-8")
82
- rescue Encoding::UndefinedConversionError
83
- str.dup.force_encoding("utf-8")
84
- end
85
-
86
- def Ruby19.param_decode(str, encoding)
87
- string = uri_parser.unescape(str)
88
- string.force_encoding(encoding) if encoding
89
- string
90
- end
91
-
92
- def Ruby19.param_encode(str)
93
- encoding = str.encoding.to_s.downcase
94
- language = Configuration.instance.param_encode_language
95
- "#{encoding}'#{language}'#{uri_parser.escape(str)}"
96
- end
97
-
98
- def Ruby19.uri_parser
99
- @uri_parser ||= URI::Parser.new
100
- end
101
-
102
- # Pick a Ruby encoding corresponding to the message charset. Most
103
- # charsets have a Ruby encoding, but some need manual aliasing here.
104
- #
105
- # TODO: add this as a test somewhere:
106
- # Encoding.list.map { |e| [e.to_s.upcase == pick_encoding(e.to_s.downcase.gsub("-", "")), e.to_s] }.select {|a,b| !b}
107
- # Encoding.list.map { |e| [e.to_s == pick_encoding(e.to_s), e.to_s] }.select {|a,b| !b}
108
- def Ruby19.pick_encoding(charset)
109
- case charset
110
-
111
- # ISO-8859-8-I etc. http://en.wikipedia.org/wiki/ISO-8859-8-I
112
- when /^iso-?8859-(\d+)(-i)?$/i
113
- "ISO-8859-#{$1}"
114
-
115
- # ISO-8859-15, ISO-2022-JP and alike
116
- when /iso-?(\d{4})-?(\w{1,2})/i
117
- "ISO-#{$1}-#{$2}"
118
-
119
- # "ISO-2022-JP-KDDI" and alike
120
- when /iso-?(\d{4})-?(\w{1,2})-?(\w*)/i
121
- "ISO-#{$1}-#{$2}-#{$3}"
122
-
123
- # UTF-8, UTF-32BE and alike
124
- when /utf[\-_]?(\d{1,2})?(\w{1,2})/i
125
- "UTF-#{$1}#{$2}".gsub(/\A(UTF-(?:16|32))\z/, '\\1BE')
126
-
127
- # Windows-1252 and alike
128
- when /Windows-?(.*)/i
129
- "Windows-#{$1}"
130
-
131
- when /^8bit$/
132
- Encoding::ASCII_8BIT
133
-
134
- # alternatives/misspellings of us-ascii seen in the wild
135
- when /^iso-?646(-us)?$/i, /us=ascii/i
136
- Encoding::ASCII
137
-
138
- # Microsoft-specific alias for MACROMAN
139
- when /^macintosh$/i
140
- Encoding::MACROMAN
141
-
142
- # Microsoft-specific alias for CP949 (Korean)
143
- when 'ks_c_5601-1987'
144
- Encoding::CP949
145
-
146
- # Wrongly written Shift_JIS (Japanese)
147
- when 'shift-jis'
148
- Encoding::Shift_JIS
149
-
150
- # GB2312 (Chinese charset) is a subset of GB18030 (its replacement)
151
- when /gb2312/i
152
- Encoding::GB18030
153
-
154
- else
155
- charset
156
- end
157
- end
158
- end
159
- end