Skip to content

Commit

Permalink
Fix to parse correctly base64 encoded mail #45
Browse files Browse the repository at this point in the history
  • Loading branch information
rust committed Aug 23, 2012
1 parent 742f2a3 commit 68fbf6e
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 14 deletions.
42 changes: 28 additions & 14 deletions lib/jpmobile/mail.rb
Expand Up @@ -48,9 +48,10 @@ def mobile=(m)
if @mobile = m
@charset = m.mail_charset(@charset)

if @body
@body.charset = @charset
@body.mobile = m
if self.body
self.body.content_type_with_jpmobile = self.content_type
self.body.charset = @charset
self.body.mobile = m
end
end
end
Expand Down Expand Up @@ -116,9 +117,10 @@ def process_body_raw_with_jpmobile
if @mobile
@body.charset = @charset
@body.mobile = @mobile
@body.content_type_with_jpmobile = self.content_type

if has_content_transfer_encoding? and
["base64", "quoted-printable"].include?(content_transfer_encoding) and
["base64", "quoted-printable"].include?(self.content_transfer_encoding) and
["text"].include?(@mobile_main_type)
@body.decode_transfer_encoding
end
Expand Down Expand Up @@ -273,6 +275,11 @@ def convert_encoding_jpmobile
end

if @body_part_jpmobile and @mobile and !@charset.blank?
if ["base64", "quoted-printable"].include?(self.content_transfer_encoding) and
self.content_type.match(/text/)
@body_part_jpmobile = Jpmobile::Util.decode(@body_part_jpmobile, self.content_transfer_encoding, @charset)
self.content_transfer_encoding = @mobile.class::MAIL_CONTENT_TRANSFER_ENCODING
end
@body_part_jpmobile = @mobile.decode_transfer_encoding(@body_part_jpmobile, @charset)
end
end
Expand Down Expand Up @@ -315,18 +322,24 @@ def ascii_compatible!(str)
end

class Body
attr_accessor :mobile
attr_accessor :mobile, :content_type_with_jpmobile

# convert encoding
def encoded_with_jpmobile(transfer_encoding = '8bit')
if @mobile and !multipart?
if @mobile.to_mail_body_encoded?(@raw_source)
@raw_source
elsif Jpmobile::Util.ascii_8bit?(@raw_source)
enc = Mail::Encodings::get_encoding(get_best_encoding(transfer_encoding))
Jpmobile::Util.force_encode(enc.encode(@raw_source), nil, @charset)
_raw_source = if transfer_encoding == encoding
@raw_source
else
enc = Mail::Encodings::get_encoding(get_best_encoding(transfer_encoding))
enc.encode(@raw_source)
end
Jpmobile::Util.force_encode(_raw_source, nil, @charset)
else
if transfer_encoding == 'quoted-printable'
case transfer_encoding
when /quoted-printable/
# [str].pack("M").gsub(/\n/, "\r\n")
Jpmobile::Util.force_encode([@mobile.to_mail_body(Jpmobile::Util.force_encode(@raw_source, @charset, Jpmobile::Util::UTF8))].pack("M").gsub(/\n/, "\r\n"), Jpmobile::Util::BINARY, @charset)
# @mobile.to_mail_body(Jpmobile::Util.force_encode(@raw_source, @charset, Jpmobile::Util::UTF8))
Expand All @@ -351,6 +364,11 @@ def set_charset_with_jpmobile
def mobile=(m)
@mobile = m

if ["base64", "quoted-printable"].include?(self.encoding) and
/text/.match(self.content_type_with_jpmobile)
self.decode_transfer_encoding
end

if self.multipart? and @mobile
self.parts.each do |part|
part.charset = @mobile.mail_charset(part.charset)
Expand All @@ -362,13 +380,9 @@ def mobile=(m)
end

def decode_transfer_encoding
_raw_source = Encodings.get_encoding(encoding).decode(@raw_source)
_extract_charset = Jpmobile::Util.extract_charset(_raw_source)
unless _extract_charset.blank? or _extract_charset == @charset
@charset = Jpmobile::Util.extract_charset(_raw_source)
end
_raw_source = Jpmobile::Util.set_encoding(_raw_source, @charset)
_raw_source = Jpmobile::Util.decode(@raw_source, self.encoding, @charset)
@raw_source = @mobile.decode_transfer_encoding(_raw_source, @charset)
self.encoding = 'text'
end

def preamble_with_jpmobile
Expand Down
15 changes: 15 additions & 0 deletions lib/jpmobile/util.rb
Expand Up @@ -400,5 +400,20 @@ def invert_table(hash)
end
result
end

def decode(str, encoding, charset)
_str = case encoding
when /quoted-printable/i
str.unpack('M').first.strip
when /base64/i
str.unpack('m').first.strip
else
str
end

_extract_charset = Jpmobile::Util.extract_charset(_str)
charset = _extract_charset unless _extract_charset.blank? or _extract_charset == charset
Jpmobile::Util.set_encoding(_str, charset)
end
end
end
27 changes: 27 additions & 0 deletions spec/unit/email-fixtures/iphone-message.eml
@@ -0,0 +1,27 @@
X-Account-Key: account2
X-UIDL: 1345598846.M744553P8903V000000000000FD00I00000000C0120BDF_0.jpjp.jp,S=1186.000031434a023554
X-Mozilla-Status: 0001
X-Mozilla-Status2: 00000000
X-Mozilla-Keys:
Return-Path: <au@ezweb.ne.jp>
Delivered-To: ogawa@jpmobile.jp
Received: (qmail 8893 invoked by SAV 20120821.022 by uid 0); 22 Aug 2012 10:27:26 +0900
Received: from unknown (HELO mmsmta08.ezweb.ne.jp) (59.135.39.241)
by dc6.etius.jp (124.146.201.109) with ESMTPS (DHE-RSA-AES256-SHA encrypted); 22 Aug 2012 10:27:26 +0900
Received-SPF: pass (dc6.etius.jp: SPF record at spf-nm.ezweb.ne.jp designates 59.135.39.241 as permitted sender)
Received: from cm (pl0_4-mms [172.22.116.39])
by mmsmta08.ezweb.ne.jp (Sentrion-MTA-4.1.0/Switch-3.3.4) with SMTP id q7M1RQgt001822
for <info@jpmobile.jp>; Wed, 22 Aug 2012 10:27:26 +0900
From:au@ezweb.ne.jp
To:ogawa@jpmobile.jp
Subject:=?UTF-8?B?aVBob25lIGF1IOODoeODg+OCu+ODvOOCuA==?=
Message-ID: <212212358846052174@-212212358846052175>
Date: Tue, 22 Aug 2012 01:27:26 +0000
MIME-Version:1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64

JVvlnJLlhZDlkI1dJeOBriVb5L+d6K236ICF5ZCNXSUg5qeYCgrmlr3oqK3jgavpgIHkv6HjgIIK
6YG45oqeMeOBryVb44Ki44OJ44Os44K5MV0l44G4CumBuOaKnjLjga8lW+OCouODieODrOOCuTJd
JeOBuArov5Tkv6HjgZfjgabkuIvjgZXjgYTjgIIKCmlQaG9uZSBhdSDjg6Hjg4Pjgrvjg7zjgrg=

36 changes: 36 additions & 0 deletions spec/unit/mail_spec.rb
Expand Up @@ -317,4 +317,40 @@
Mail::TestMailer.deliveries.size
end
end

context 'sending with carrier from' do
before do
@mail = Mail.new
@mail.subject = "万葉"
@mail.to = "ちはやふる <info@jpmobile-rails.org>"
end

it 'should convert content-transfer-encoding' do
mobile = Jpmobile::Mobile::Au.new(nil, nil)
@mail.content_transfer_encoding = 'base64'
@mail.body = ['ほげ'].pack('m')
@mail.charset = 'UTF-8'

@mail.mobile = mobile
@mail.from = '<えーゆー> au@ezweb.ne.jp'

@mail.encoded.should match(/content-transfer-encoding: 7bit/i)
end

it 'should not convert content-transfer-encoding with BINARY' do
mobile = Jpmobile::Mobile::Au.new(nil, nil)
data = ['ほげ'].pack('m').strip

@mail.content_transfer_encoding = 'base64'
@mail.content_type = 'image/jpeg'
@mail.body = data
@mail.charset = 'UTF-8'

@mail.mobile = mobile
@mail.from = '<えーゆー> au@ezweb.ne.jp'

@mail.encoded.should match(/content-transfer-encoding: base64/i)
@mail.encoded.should match(data)
end
end
end
13 changes: 13 additions & 0 deletions spec/unit/receive_mail_spec.rb
Expand Up @@ -242,6 +242,19 @@
@mail = Mail.new(open(File.join(File.expand_path(File.dirname(__FILE__)), "email-fixtures/au-decomail2.eml")).read)
}.should_not raise_error
end

context 'From au iPhone' do
it 'charset should be UTF-8' do
@mail = Mail.new(open(File.join(File.expand_path(File.dirname(__FILE__)), "email-fixtures/iphone-message.eml")).read)
@mail.mobile.should be_a(Jpmobile::Mobile::Au)
@mail.charset.should match(/utf-8/i)
end

it 'should be encoded correctly' do
@mail = Mail.new(open(File.join(File.expand_path(File.dirname(__FILE__)), "email-fixtures/iphone-message.eml")).read)
@mail.encoded
end
end
end

describe "Softbank" do
Expand Down
9 changes: 9 additions & 0 deletions test/rails/overrides/spec/mailers/mobile_mailer_spec.rb
Expand Up @@ -663,6 +663,15 @@
parts.first.body.should match(/テストです&#xe595;/)
parts.last.body.raw_source.should match(/テストです&#xe595;/)
end

context 'iPhone' do
it 'should parse correctly' do
lambda {
@mail = MobileMailer.receive(open(File.join(Rails.root, "../../../spec/unit/email-fixtures/iphone-message.eml")).read)
@mail.encoded
}.should_not raise_error
end
end
end

describe "softbank(sjis) の場合" do
Expand Down

0 comments on commit 68fbf6e

Please sign in to comment.