Skip to content

Instantly share code, notes, and snippets.

@macuk
Last active December 23, 2015 10:09
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save macuk/6619938 to your computer and use it in GitHub Desktop.
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
Copy link

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 ;)

@macuk
Copy link
Author

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