Module: Mail::Encodings
- Extended by:
- Utilities
- Includes:
- Patterns
- Defined in:
- lib/mail/encodings.rb,
lib/mail/encodings/7bit.rb,
lib/mail/encodings/8bit.rb,
lib/mail/encodings/base64.rb,
lib/mail/encodings/binary.rb,
lib/mail/encodings/quoted_printable.rb,
lib/mail/encodings/transfer_encoding.rb
Defined Under Namespace
Classes: Base64, Binary, EightBit, QuotedPrintable, SevenBit, TransferEncoding
Constant Summary
Constants included from Patterns
Patterns::ATOM_UNSAFE, Patterns::CONTROL_CHAR, Patterns::CRLF, Patterns::FIELD_BODY, Patterns::FIELD_LINE, Patterns::FIELD_NAME, Patterns::FWS, Patterns::HEADER_LINE, Patterns::PHRASE_UNSAFE, Patterns::QP_SAFE, Patterns::QP_UNSAFE, Patterns::TEXT, Patterns::TOKEN_UNSAFE, Patterns::WSP
Class Method Summary collapse
- .address_encode(address, charset = 'utf-8') ⇒ Object
-
.b_value_encode(encoded_str, encoding = nil) ⇒ Object
Encode a string with Base64 Encoding and returns it ready to be inserted as a value for a field, that is, in the =?<charset>?B?<string>?= format.
-
.decode_encode(str, output_type) ⇒ Object
Decodes or encodes a string as needed for either Base64 or QP encoding types in the =?<encoding>??<string>?=“ format.
-
.defined?(str) ⇒ Boolean
Is the encoding we want defined?.
- .encode_non_usascii(address, charset) ⇒ Object
- .get_all ⇒ Object
-
.get_encoding(str) ⇒ Object
Gets a defined encoding type, QuotedPrintable or Base64 for now.
- .get_name(enc) ⇒ Object
-
.param_decode(str, encoding) ⇒ Object
Decodes a parameter value using URI Escaping.
-
.param_encode(str) ⇒ Object
Encodes a parameter value using URI Escaping, note the language field ‘en’ can be set using Mail::Configuration, like so:.
-
.q_value_encode(encoded_str, encoding = nil) ⇒ Object
Encode a string with Quoted-Printable Encoding and returns it ready to be inserted as a value for a field, that is, in the =?<charset>?Q?<string>?= format.
-
.register(name, cls) ⇒ Object
Register transfer encoding.
-
.unquote_and_convert_to(str, to_encoding) ⇒ Object
Takes an encoded string of the format =?<encoding>??<string>?=.
-
.value_decode(str) ⇒ Object
Decodes a given string as Base64 or Quoted Printable, depending on what type it is.
Methods included from Utilities
atom_safe?, bracket, capitalize_field, constantize, dasherize, dquote, escape_paren, map_lines, map_with_index, match_to_s, paren, quote_atom, quote_phrase, quote_token, token_safe?, unbracket, underscoreize, unparen, unquote, uri_escape, uri_parser, uri_unescape
Class Method Details
.address_encode(address, charset = 'utf-8') ⇒ Object
178 179 180 181 182 183 184 185 186 |
# File 'lib/mail/encodings.rb', line 178 def Encodings.address_encode(address, charset = 'utf-8') if address.is_a?(Array) # loop back through for each element address.map { |a| Encodings.address_encode(a, charset) }.join(", ") else # find any word boundary that is not ascii and encode it encode_non_usascii(address, charset) end end |
.b_value_encode(encoded_str, encoding = nil) ⇒ Object
Encode a string with Base64 Encoding and returns it ready to be inserted as a value for a field, that is, in the =?<charset>?B?<string>?= format
Example:
Encodings.b_value_encode('This is あ string', 'UTF-8')
#=> "=?UTF-8?B?VGhpcyBpcyDjgYIgc3RyaW5n?="
215 216 217 218 219 220 221 |
# File 'lib/mail/encodings.rb', line 215 def Encodings.b_value_encode(encoded_str, encoding = nil) return encoded_str if encoded_str.to_s.ascii_only? string, encoding = RubyVer.b_value_encode(encoded_str, encoding) map_lines(string) do |str| "=?#{encoding}?B?#{str.chomp}?=" end.join(" ") end |
.decode_encode(str, output_type) ⇒ Object
Decodes or encodes a string as needed for either Base64 or QP encoding types in the =?<encoding>??<string>?=“ format.
The output type needs to be :decode to decode the input string or :encode to encode the input string. The character set used for encoding will either be the value of $KCODE for Ruby < 1.9 or the encoding on the string passed in.
On encoding, will only send out Base64 encoded strings.
98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/mail/encodings.rb', line 98 def Encodings.decode_encode(str, output_type) case when output_type == :decode Encodings.value_decode(str) else if str.ascii_only? str else Encodings.b_value_encode(str, find_encoding(str)) end end end |
.defined?(str) ⇒ Boolean
29 30 31 |
# File 'lib/mail/encodings.rb', line 29 def Encodings.defined?( str ) @transfer_encodings.include? get_name(str) end |
.encode_non_usascii(address, charset) ⇒ Object
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/mail/encodings.rb', line 188 def Encodings.encode_non_usascii(address, charset) return address if address.ascii_only? or charset.nil? us_ascii = %Q{\x00-\x7f} # Encode any non usascii strings embedded inside of quotes address.gsub!(/(".*?[^#{us_ascii}].*?")/) { |s| Encodings.b_value_encode(unquote(s), charset) } # Then loop through all remaining items and encode as needed tokens = address.split(/\s/) map_with_index(tokens) do |word, i| if word.ascii_only? word else previous_non_ascii = tokens[i-1] && !tokens[i-1].ascii_only? if previous_non_ascii word = " #{word}" end Encodings.b_value_encode(word, charset) end end.join(' ') end |
.get_all ⇒ Object
45 46 47 |
# File 'lib/mail/encodings.rb', line 45 def Encodings.get_all @transfer_encodings.values end |
.get_encoding(str) ⇒ Object
Gets a defined encoding type, QuotedPrintable or Base64 for now.
Each encoding needs to be defined as a Mail::Encodings::ClassName for this to work, allows us to add other encodings in the future.
Example:
Encodings.get_encoding(:base64) #=> Mail::Encodings::Base64
41 42 43 |
# File 'lib/mail/encodings.rb', line 41 def Encodings.get_encoding( str ) @transfer_encodings[get_name(str)] end |
.get_name(enc) ⇒ Object
49 50 51 |
# File 'lib/mail/encodings.rb', line 49 def Encodings.get_name(enc) enc = enc.to_s.gsub("-", "_").downcase end |
.param_decode(str, encoding) ⇒ Object
86 87 88 |
# File 'lib/mail/encodings.rb', line 86 def Encodings.param_decode(str, encoding) RubyVer.param_decode(str, encoding) end |
.param_encode(str) ⇒ Object
Encodes a parameter value using URI Escaping, note the language field ‘en’ can be set using Mail::Configuration, like so:
Mail.defaults.do
param_encode_language 'jp'
end
The character set used for encoding will either be the value of $KCODE for Ruby < 1.9 or the encoding on the string passed in.
Example:
Mail::Encodings.param_encode("This is fun") #=> "us-ascii'en'This%20is%20fun"
66 67 68 69 70 71 72 73 74 75 |
# File 'lib/mail/encodings.rb', line 66 def Encodings.param_encode(str) case when str.ascii_only? && str =~ TOKEN_UNSAFE %Q{"#{str}"} when str.ascii_only? str else RubyVer.param_encode(str) end end |
.q_value_encode(encoded_str, encoding = nil) ⇒ Object
Encode a string with Quoted-Printable Encoding and returns it ready to be inserted as a value for a field, that is, in the =?<charset>?Q?<string>?= format
Example:
Encodings.q_value_encode('This is あ string', 'UTF-8')
#=> "=?UTF-8?Q?This_is_=E3=81=82_string?="
230 231 232 233 234 235 236 237 |
# File 'lib/mail/encodings.rb', line 230 def Encodings.q_value_encode(encoded_str, encoding = nil) return encoded_str if encoded_str.to_s.ascii_only? string, encoding = RubyVer.q_value_encode(encoded_str, encoding) string.gsub!("=\r\n", '') # We already have limited the string to the length we want map_lines(string) do |str| "=?#{encoding}?Q?#{str.chomp.gsub(/ /, '_')}?=" end.join(" ") end |
.register(name, cls) ⇒ Object
Register transfer encoding
Example
Encodings.register “base64”, Mail::Encodings::Base64
20 21 22 |
# File 'lib/mail/encodings.rb', line 20 def Encodings.register(name, cls) @transfer_encodings[get_name(name)] = cls end |
.unquote_and_convert_to(str, to_encoding) ⇒ Object
Takes an encoded string of the format =?<encoding>??<string>?=
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/mail/encodings.rb', line 149 def Encodings.unquote_and_convert_to(str, to_encoding) original_encoding = split_encoding_from_string( str ) output = value_decode( str ).to_s if original_encoding.to_s.downcase.gsub("-", "") == to_encoding.to_s.downcase.gsub("-", "") output elsif original_encoding && to_encoding begin if RUBY_VERSION >= '1.9' output.encode(to_encoding) else require 'iconv' Iconv.iconv(to_encoding, original_encoding, output).first end rescue Iconv::IllegalSequence, Iconv::InvalidEncoding, Errno::EINVAL # the 'from' parameter specifies a charset other than what the text # actually is...not much we can do in this case but just return the # unconverted text. # # Ditto if either parameter represents an unknown charset, like # X-UNKNOWN. output end else output end end |
.value_decode(str) ⇒ Object
Decodes a given string as Base64 or Quoted Printable, depending on what type it is.
String has to be of the format =?<encoding>??<string>?=
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/mail/encodings.rb', line 115 def Encodings.value_decode(str) # Optimization: If there's no encoded-words in the string, just return it return str unless str.index("=?") str = str.gsub(/\?=(\s*)=\?/, '?==?') # Remove whitespaces between 'encoded-word's # Split on white-space boundaries with capture, so we capture the white-space as well str.split(/([ \t])/).map do |text| if text.index('=?') .nil? text else # Join QP encoded-words that are adjacent to avoid decoding partial chars text.gsub!(/\?\=\=\?.+?\?[Qq]\?/m, '') if text =~ /\?==\?/ # Search for occurences of quoted strings or plain strings text.scan(/( # Group around entire regex to include it in matches \=\?[^?]+\?([QB])\?[^?]+?\?\= # Quoted String with subgroup for encoding method | # or .+?(?=\=\?|$) # Plain String )/xmi).map do |matches| string, method = *matches if method == 'b' || method == 'B' b_value_decode(string) elsif method == 'q' || method == 'Q' q_value_decode(string) else string end end end end.join("") end |