Permalink
Browse files

Tagged and branches 1.1

git-svn-id: http://svn-commit.rubyonrails.org/rails/branches/stable@4091 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
2 parents ec20838 + 9babb20 commit 2f4093690b467dbcf79237be486874684743e025 @dhh dhh committed Mar 28, 2006
Showing 496 changed files with 20,680 additions and 7,633 deletions.
View
@@ -1,3 +1,18 @@
+*1.2.0* (March 27th, 2005)
+
+* Nil charset caused subject line to be improperly quoted in implicitly multipart messages #2662 [ehalvorsen+rails@runbox.com]
+
+* 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]
+
+* Make sure anything with content-disposition of "attachment" is passed to the attachment presenter when parsing an email body [Jamis Buck]
+
+* Make sure TMail#attachments includes anything with content-disposition of "attachment", regardless of content-type [Jamis Buck]
+
+
*1.1.5* (December 13th, 2005)
* Become part of Rails 1.0
@@ -7,6 +22,8 @@
* Rename Version constant to VERSION. #2802 [Marcel Molina Jr.]
+* Stricter matching for implicitly multipart filenames excludes files ending in unsupported extensions (such as foo.rhtml.bak) and without a two-part content type (such as foo.text.rhtml or foo.text.really.plain.rhtml). #2398 [Dave Burt <dave@burt.id.au>, Jeremy Kemper]
+
*1.1.3* (November 7th, 2005)
View
@@ -25,14 +25,15 @@ Rake::TestTask.new { |t|
t.libs << "test"
t.pattern = 'test/*_test.rb'
t.verbose = true
+ t.warning = false
}
# Genereate the RDoc documentation
Rake::RDocTask.new { |rdoc|
rdoc.rdoc_dir = 'doc'
rdoc.title = "Action Mailer -- Easy email delivery and testing"
- rdoc.options << '--line-numbers --inline-source --main README --accessor adv_attr_accessor=M'
+ rdoc.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
rdoc.template = "#{ENV['template']}.rb" if ENV['template']
rdoc.rdoc_files.include('README', 'CHANGELOG')
rdoc.rdoc_files.include('lib/action_mailer.rb')
@@ -53,7 +54,7 @@ spec = Gem::Specification.new do |s|
s.rubyforge_project = "actionmailer"
s.homepage = "http://www.rubyonrails.org"
- s.add_dependency('actionpack', '= 1.11.2' + PKG_BUILD)
+ s.add_dependency('actionpack', '= 1.12.0' + PKG_BUILD)
s.has_rdoc = true
s.requirements << 'none'
@@ -8,16 +8,20 @@ def self.append_features(base)
module ClassMethods #:nodoc:
def adv_attr_accessor(*names)
names.each do |name|
+ ivar = "@#{name}"
+
define_method("#{name}=") do |value|
- instance_variable_set("@#{name}", value)
+ instance_variable_set(ivar, value)
end
define_method(name) do |*parameters|
raise ArgumentError, "expected 0 or 1 parameters" unless parameters.length <= 1
if parameters.empty?
- instance_variable_get("@#{name}")
+ if instance_variables.include?(ivar)
+ instance_variable_get(ivar)
+ end
else
- instance_variable_set("@#{name}", parameters.first)
+ instance_variable_set(ivar, parameters.first)
end
end
end
@@ -4,7 +4,7 @@
require 'action_mailer/utils'
require 'tmail/net'
-module ActionMailer
+module ActionMailer #:nodoc:
# Usage:
#
# class ApplicationMailer < ActionMailer::Base
@@ -121,6 +121,10 @@ module ActionMailer
class Base
include AdvAttrAccessor, PartContainer
+ # Action Mailer subclasses should be reloaded by the dispatcher in Rails
+ # when Dependencies.mechanism = :load.
+ include Reloadable::Subclasses
+
private_class_method :new #:nodoc:
cattr_accessor :template_root
@@ -278,15 +282,17 @@ def create!(method_name, *parameters) #:nodoc:
if @parts.empty?
templates = Dir.glob("#{template_path}/#{@template}.*")
templates.each do |path|
- type = (File.basename(path).split(".")[1..-2] || []).join("/")
- next if type.empty?
- @parts << Part.new(:content_type => type,
+ # TODO: don't hardcode rhtml|rxml
+ basename = File.basename(path)
+ next unless md = /^([^\.]+)\.([^\.]+\.[^\+]+)\.(rhtml|rxml)$/.match(basename)
+ template_name = basename
+ content_type = md.captures[1].gsub('.', '/')
+ @parts << Part.new(:content_type => content_type,
:disposition => "inline", :charset => charset,
- :body => render_message(File.basename(path).split(".")[0..-2].join('.'), @body))
+ :body => render_message(template_name, @body))
end
unless @parts.empty?
@content_type = "multipart/alternative"
- @charset = nil
@parts = sort_parts(@parts, @implicit_parts_order)
end
end
@@ -296,7 +302,7 @@ def create!(method_name, *parameters) #:nodoc:
# normal template exists (or if there were no implicit parts) we render
# it.
template_exists = @parts.empty?
- template_exists ||= Dir.glob("#{template_path}/#{@template}.*").any? { |i| i.split(".").length == 2 }
+ template_exists ||= Dir.glob("#{template_path}/#{@template}.*").any? { |i| File.basename(i).split(".").length == 2 }
@body = render_message(@template, @body) if template_exists
# Finally, if there are other message parts and a textual body exists,
@@ -406,14 +412,16 @@ def create_mail
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
@@ -423,7 +431,10 @@ def create_mail
m.parts << part
end
- m.set_content_type(content_type, nil, { "charset" => charset }) if content_type =~ /multipart/
+ if real_content_type =~ /multipart/
+ ctype_attrs.delete "charset"
+ m.set_content_type(real_content_type, nil, ctype_attrs)
+ end
end
@mail = m
@@ -56,6 +56,8 @@ def initialize(params)
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 @@ def to_mail(defaults)
# 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,13 +96,16 @@ def to_mail(defaults)
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 }
+
part
end
private
+
def squish(values={})
values.delete_if { |k,v| v.nil? }
end
@@ -38,5 +38,14 @@ def attachment(params, &block)
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
@@ -7,13 +7,18 @@ class Attachment < StringIO
class Mail
def has_attachments?
- multipart? && parts.any? { |part| part.header["content-type"].main_type != "text" }
+ multipart? && parts.any? { |part| attachment?(part) }
+ end
+
+ def attachment?(part)
+ (part['content-disposition'] && part['content-disposition'].disposition == "attachment") ||
+ part.header['content-type'].main_type != "text"
end
def attachments
if multipart?
parts.collect { |part|
- if part.header["content-type"].main_type != "text"
+ if attachment?(part)
content = part.body # unquoted automatically by TMail#body
file_name = (part['content-location'] &&
part['content-location'].body) ||
@@ -33,7 +33,7 @@ def body(to_charset = 'utf-8', &block)
part.body(to_charset, &attachment_presenter)
elsif header.nil?
""
- elsif header.main_type == "text"
+ elsif !attachment?(part)
part.unquoted_body(to_charset)
else
attachment_presenter.call(header["name"] || "(unnamed)")
@@ -1,8 +1,8 @@
module ActionMailer
module VERSION #:nodoc:
MAJOR = 1
- MINOR = 1
- TINY = 5
+ MINOR = 2
+ TINY = 0
STRING = [MAJOR, MINOR, TINY].join('.')
end
@@ -0,0 +1 @@
+Have a lovely picture, from me. Enjoy!
@@ -0,0 +1,29 @@
+Mime-Version: 1.0 (Apple Message framework v730)
+Content-Type: multipart/mixed; boundary=Apple-Mail-13-196941151
+Message-Id: <9169D984-4E0B-45EF-82D4-8F5E53AD7012@example.com>
+From: foo@example.com
+Subject: testing
+Date: Mon, 6 Jun 2005 22:21:22 +0200
+To: blah@example.com
+
+
+--Apple-Mail-13-196941151
+Content-Transfer-Encoding: quoted-printable
+Content-Type: text/plain;
+ charset=ISO-8859-1;
+ delsp=yes;
+ format=flowed
+
+This is the first part.
+
+--Apple-Mail-13-196941151
+Content-Type: text/x-ruby-script; name="hello.rb"
+Content-Transfer-Encoding: 7bit
+Content-Disposition: attachment;
+ filename="api.rb"
+
+puts "Hello, world!"
+gets
+
+--Apple-Mail-13-196941151--
+
@@ -22,6 +22,16 @@ Content-Type: text/plain;
This is the first part.
--Apple-Mail-12-196940926
+Content-Transfer-Encoding: 7bit
+Content-Type: text/x-ruby-script;
+ x-unix-mode=0666;
+ name="test.rb"
+Content-Disposition: attachment;
+ filename=test.rb
+
+puts "testing, testing"
+
+--Apple-Mail-12-196940926
Content-Transfer-Encoding: base64
Content-Type: application/pdf;
x-unix-mode=0666;
@@ -0,0 +1 @@
+Ignored when searching for implicitly multipart parts.
@@ -0,0 +1 @@
+Ignored when searching for implicitly multipart parts.
Oops, something went wrong.

0 comments on commit 2f40936

Please sign in to comment.