Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Mail gem problem
# - Konfeo.com
# - Mail wysyłany jako organizator
# - ~ 15 000 wysyłanych maili miesięcznie
# ------------------------------------------------------------
# Kodowanie nagłówków maili
require 'mail'
m = Mail.new
m.from = 'Żółty żółw <zolw@wp.pl>'
puts m.encoded
# (...)
From: =?UTF-8?B?xbvDs8WCdHk=?= =?UTF-8?B?IMW8w7PFgnc=?= <zolw@wp.pl>
# (...)
# ------------------------------------------------------------
# Czasami dziwny problem...
# - Nieprawidłowe wyświetlanie nadawcy (mail.app, Thunderbird)
# - Odrzucanie maili do wysyłki przez Mandrill-a
# ------------------------------------------------------------
# Konsultacje z supportem Mandrill-a
# Błąd:
# Klub Świadomego Menadżera - Świadome zarządzanie budżetem domowym
# =?UTF-8?B?S2x1YiDFmndpYWRvbWVnbyBNZW5hZMW8ZXJhIC0gxZp3aWFkb21lIHphcnrE?=
# =?UTF-8?B?hWR6YW5pZSBidWTFvGV0ZW0gZG9tb3d5bQ==?=
#
# OK:
# Klub Świadomego Menadżera: świadome zarządzanie budżetem domowym
# =?UTF-8?B?S2x1YiDFmndpYWRvbWVnbyBNZW5hZMW8ZXJhOiDFm3dpYWRvbWUgemFyesSF?=
# =?UTF-8?B?ZHphbmllIGJ1ZMW8ZXRlbSBkb21vd3lt?=
# ------------------------------------------------------------
# Wykrycie problemu w działaniu gema Mail
# RFC2047: Each 'encoded-word' MUST represent
# an integral number of characters. A multi-octet
# character may not be split across adjacent
# 'encoded-word's.
# ------------------------------------------------------------
# Pierwszy pomysł -- patch do gema Mail
def encode_base64(str)
[str].pack( 'm' )
end
str = 'Klub Świadomego Menadżera - Świadome zarządzanie budżetem domowym'
str.encoding # => #<Encoding:UTF-8>
puts out = [str].pack('m')
# S2x1YiDFmndpYWRvbWVnbyBNZW5hZMW8ZXJhIC0gxZp3aWFkb21lIHphcnrE
# hWR6YW5pZSBidWTFvGV0ZW0gZG9tb3d5bQ==
out.unpack('m').first.encoding # => #<Encoding:ASCII-8BIT>
out.unpack('m').first.encode 'UTF-8'
# Encoding::UndefinedConversionError: "\xC5" from ASCII-8BIT to UTF-8
out.unpack('m').first.encode Encoding::ISO8859_2
# Encoding::UndefinedConversionError: "\xC5" to UTF-8
# in conversion from ASCII-8BIT to UTF-8 to ISO-8859-2
# ------------------------------------------------------------
# Rozwiązanie
require 'mail'
m = Mail.new
m.from = 'Żółw <b@wp.pl>'
puts m.encoded
# (...)
From: =?UTF-8?B?xbvDs8WCdw==?= <b@wp.pl>
# (...)
from = 'Żółw <b@wp.pl>'
from = from.encode Encoding::ISO8859_2
m.from = from
puts m.encoded
# (...)
From: =?ISO-8859-2?B?r/Ozdw==?= <b@wp.pl>
# (...)
pjg commented Sep 19, 2013

Moja pobieżna analiza wykazała, że działanie pack('m') jest poprawne. Tylko, że średnio się nadaje do znaków Unicode, co sam miałeś okazję doświadczyć.

Widzę, że gem mail używa pack('m') tylko w przypadku Ruby 1.9:

https://github.com/mikel/mail/blob/master/lib/mail/version_specific/ruby_1_9.rb

W przypadku Ruby 2.0+ w grę wchodzą dużo bardziej zaawansowane algorytmy "pakujące":
https://github.com/mikel/mail/blob/master/lib/mail/multibyte/unicode.rb
https://github.com/mikel/mail/blob/master/lib/mail/multibyte/chars.rb

Innymi słowy - upgrade do Ruby 2.0 powinien rozwiązać wszystkie Twoje problemy, bez uciekania się do używania archaicznego Latin 2 ;)

Owner
macuk commented Mar 3, 2014

Dzięki za Twój komentarz. GH nie wysłał mi żadnej notyfikacji i dopiero teraz go przeczytałem. Właśnie jestem w trakcie migracji na Rails 4.0 i Ryby 2.1 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment