aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionmailer/CHANGELOG2
-rw-r--r--actionmailer/lib/action_mailer/base.rb8
-rw-r--r--actionmailer/lib/action_mailer/part.rb19
-rw-r--r--actionmailer/lib/action_mailer/part_container.rb9
-rwxr-xr-xactionmailer/test/mail_service_test.rb14
5 files changed, 41 insertions, 11 deletions
diff --git a/actionmailer/CHANGELOG b/actionmailer/CHANGELOG
index 28c5803535..82497e324e 100644
--- a/actionmailer/CHANGELOG
+++ b/actionmailer/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Parse content-type apart before using it so that sub-parts of the header can be set correctly #2918 [Jamis Buck]
+
* Make custom headers work in subparts #4034 [elan@bluemandrill.com]
* Template paths with dot chars in them no longer mess up implicit template selection for multipart messages #3332 [Chad Fowler]
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index 237e56ed0c..42d48fd5a6 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -413,14 +413,16 @@ module ActionMailer
m.date = sent_on.to_time rescue sent_on if sent_on
headers.each { |k, v| m[k] = v }
+ real_content_type, ctype_attrs = parse_content_type
+
if @parts.empty?
- m.set_content_type content_type, nil, { "charset" => charset }
+ m.set_content_type(real_content_type, nil, ctype_attrs)
m.body = Utils.normalize_new_lines(body)
else
if String === body
part = TMail::Mail.new
part.body = Utils.normalize_new_lines(body)
- part.set_content_type content_type, nil, { "charset" => charset }
+ part.set_content_type(real_content_type, nil, ctype_attrs)
part.set_content_disposition "inline"
m.parts << part
end
@@ -430,7 +432,7 @@ module ActionMailer
m.parts << part
end
- m.set_content_type(content_type, nil, { "charset" => charset }) if content_type =~ /multipart/
+ m.set_content_type(real_content_type, nil, ctype_attrs) if real_content_type =~ /multipart/
end
@mail = m
diff --git a/actionmailer/lib/action_mailer/part.rb b/actionmailer/lib/action_mailer/part.rb
index 7bdbf5345d..31f5b441e3 100644
--- a/actionmailer/lib/action_mailer/part.rb
+++ b/actionmailer/lib/action_mailer/part.rb
@@ -56,6 +56,8 @@ module ActionMailer
def to_mail(defaults)
part = TMail::Mail.new
+ real_content_type, ctype_attrs = parse_content_type(defaults)
+
if @parts.empty?
part.content_transfer_encoding = transfer_encoding || "quoted-printable"
case (transfer_encoding || "").downcase
@@ -71,20 +73,20 @@ module ActionMailer
# Also don't set filename and name when there is none (like in
# non-attachment parts)
if content_disposition == "attachment"
- part.set_content_type(content_type || defaults.content_type, nil,
- squish("charset" => nil, "name" => filename))
+ ctype_attrs.delete "charset"
+ part.set_content_type(real_content_type, nil,
+ squish("name" => filename).merge(ctype_attrs))
part.set_content_disposition(content_disposition,
- squish("filename" => filename))
+ squish("filename" => filename).merge(ctype_attrs))
else
- part.set_content_type(content_type || defaults.content_type, nil,
- "charset" => (charset || defaults.charset))
+ part.set_content_type(real_content_type, nil, ctype_attrs)
part.set_content_disposition(content_disposition)
end
else
if String === body
part = TMail::Mail.new
part.body = body
- part.set_content_type content_type, nil, { "charset" => charset }
+ part.set_content_type(real_content_type, nil, ctype_attrs)
part.set_content_disposition "inline"
m.parts << part
end
@@ -94,15 +96,16 @@ module ActionMailer
part.parts << prt
end
- part.set_content_type(content_type, nil, { "charset" => charset }) if content_type =~ /multipart/
+ part.set_content_type(real_content_type, nil, ctype_attrs) if real_content_type =~ /multipart/
end
- @headers.each { |k,v| part[k] = v }
+ headers.each { |k,v| part[k] = v }
part
end
private
+
def squish(values={})
values.delete_if { |k,v| v.nil? }
end
diff --git a/actionmailer/lib/action_mailer/part_container.rb b/actionmailer/lib/action_mailer/part_container.rb
index 6199fe0b6e..3e3d6b9d4f 100644
--- a/actionmailer/lib/action_mailer/part_container.rb
+++ b/actionmailer/lib/action_mailer/part_container.rb
@@ -38,5 +38,14 @@ module ActionMailer
part(params, &block)
end
+ private
+
+ def parse_content_type(defaults=nil)
+ return [defaults && defaults.content_type, {}] if content_type.blank?
+ ctype, *attrs = content_type.split(/;\s*/)
+ attrs = attrs.inject({}) { |h,s| k,v = s.split(/=/, 2); h[k] = v; h }
+ [ctype, {"charset" => charset || defaults && defaults.charset}.merge(attrs)]
+ end
+
end
end
diff --git a/actionmailer/test/mail_service_test.rb b/actionmailer/test/mail_service_test.rb
index b60b1c1b8b..0689bf6728 100755
--- a/actionmailer/test/mail_service_test.rb
+++ b/actionmailer/test/mail_service_test.rb
@@ -246,6 +246,14 @@ class TestMailer < ActionMailer::Base
body "testing"
end
+ def custom_content_type_attributes
+ recipients "no.one@nowhere.test"
+ subject "custom content types"
+ from "some.one@somewhere.test"
+ content_type "text/plain; format=flowed"
+ body "testing"
+ end
+
class <<self
attr_accessor :received_body
end
@@ -787,5 +795,11 @@ EOF
mail = FunkyPathMailer.create_multipart_with_template_path_with_dots(@recipient)
assert_equal 2, mail.parts.length
end
+
+ def test_custom_content_type_attributes
+ mail = TestMailer.create_custom_content_type_attributes
+ assert_match %r{format=flowed}, mail['content-type'].to_s
+ assert_match %r{charset=utf-8}, mail['content-type'].to_s
+ end
end