Skip to content

Commit

Permalink
Merge remote branch 'rails/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
fxn committed May 19, 2010
2 parents b9fcd8d + 61001e7 commit 7f07cc3
Show file tree
Hide file tree
Showing 127 changed files with 1,359 additions and 872 deletions.
17 changes: 9 additions & 8 deletions Gemfile
Expand Up @@ -6,17 +6,18 @@ gem "rails", :path => File.dirname(__FILE__)
gem "rake", ">= 0.8.7"
gem "mocha", ">= 0.9.8"

group :mri do
mri = !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby"
if mri && RUBY_VERSION < '1.9'
gem "system_timer"
gem "ruby-debug", ">= 0.10.3"
end

if mri || RUBY_ENGINE == "rbx"
gem 'json'
gem 'yajl-ruby'
gem "nokogiri", ">= 1.4.0"

if RUBY_VERSION < '1.9'
gem "system_timer"
gem "ruby-debug", ">= 0.10.3"
elsif RUBY_VERSION < '1.9.2' && !ENV['CI']
gem "ruby-debug19"
end
elsif RUBY_ENGINE == "jruby"
gem "jruby-debug"
end

# AR
Expand Down
4 changes: 2 additions & 2 deletions actionmailer/test/base_test.rb
Expand Up @@ -491,8 +491,8 @@ def give_a_greeting

# Class level API with method missing
test "should respond to action methods" do
assert BaseMailer.respond_to?(:welcome)
assert BaseMailer.respond_to?(:implicit_multipart)
assert_respond_to BaseMailer, :welcome
assert_respond_to BaseMailer, :implicit_multipart
assert !BaseMailer.respond_to?(:mail)
assert !BaseMailer.respond_to?(:headers)
end
Expand Down
8 changes: 4 additions & 4 deletions actionmailer/test/old_base/asset_host_test.rb
Expand Up @@ -26,7 +26,7 @@ def teardown

def test_asset_host_as_string
mail = AssetHostMailer.email_with_asset
assert_equal "<img alt=\"Somelogo\" src=\"http://www.example.com/images/somelogo.png\" />", mail.body.to_s.strip
assert_equal %Q{<img alt="Somelogo" src="http://www.example.com/images/somelogo.png" />}, mail.body.to_s.strip
end

def test_asset_host_as_one_arguement_proc
Expand All @@ -38,7 +38,7 @@ def test_asset_host_as_one_arguement_proc
end
}
mail = AssetHostMailer.email_with_asset
assert_equal "<img alt=\"Somelogo\" src=\"http://images.example.com/images/somelogo.png\" />", mail.body.to_s.strip
assert_equal %Q{<img alt="Somelogo" src="http://images.example.com/images/somelogo.png" />}, mail.body.to_s.strip
end

def test_asset_host_as_two_arguement_proc
Expand All @@ -51,6 +51,6 @@ def test_asset_host_as_two_arguement_proc
}
mail = nil
assert_nothing_raised { mail = AssetHostMailer.email_with_asset }
assert_equal "<img alt=\"Somelogo\" src=\"http://www.example.com/images/somelogo.png\" />", mail.body.to_s.strip
assert_equal %Q{<img alt="Somelogo" src="http://www.example.com/images/somelogo.png" />}, mail.body.to_s.strip
end
end
end
2 changes: 1 addition & 1 deletion actionmailer/test/old_base/mail_render_test.rb
Expand Up @@ -117,7 +117,7 @@ def test_file_template

def test_rxml_template
mail = RenderMailer.rxml_template.deliver
assert_equal "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test/>", mail.body.to_s.strip
assert_equal %(<?xml version="1.0" encoding="UTF-8"?>\n<test/>), mail.body.to_s.strip
end

def test_included_subtemplate
Expand Down
27 changes: 14 additions & 13 deletions actionmailer/test/old_base/mail_service_test.rb
Expand Up @@ -281,23 +281,23 @@ def headers_with_nonalpha_chars(recipient)
from "One: Two <test@example.com>"
cc "Three: Four <test@example.com>"
bcc "Five: Six <test@example.com>"
body "testing"
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"
body "testing"
end

def return_path
recipients "no.one@nowhere.test"
subject "return path test"
from "some.one@somewhere.test"
headers["return-path"] = "another@somewhere.test"
body "testing"
body "testing"
end

def subject_with_i18n(recipient)
Expand Down Expand Up @@ -417,7 +417,7 @@ def test_signed_up
end

def test_custom_template
expected = new_mail
expected = new_mail
expected.to = @recipient
expected.subject = "[Signed up] Welcome #{@recipient}"
expected.body = "Hello there, \n\nMr. #{@recipient}"
Expand All @@ -436,7 +436,7 @@ def test_custom_templating_extension
assert ActionView::Template.template_handler_extensions.include?("haml"), "haml extension was not registered"

# N.b., custom_templating_extension.text.plain.haml is expected to be in fixtures/test_mailer directory
expected = new_mail
expected = new_mail
expected.to = @recipient
expected.subject = "[Signed up] Welcome #{@recipient}"
expected.body = "Hello there, \n\nMr. #{@recipient}"
Expand All @@ -453,7 +453,7 @@ def test_custom_templating_extension
end

def test_cancelled_account
expected = new_mail
expected = new_mail
expected.to = @recipient
expected.subject = "[Cancelled] Goodbye #{@recipient}"
expected.body = "Goodbye, Mr. #{@recipient}"
Expand All @@ -477,7 +477,7 @@ def test_cancelled_account
end

def test_cc_bcc
expected = new_mail
expected = new_mail
expected.to = @recipient
expected.subject = "testing bcc/cc"
expected.body = "Nothing to see here."
Expand Down Expand Up @@ -602,7 +602,7 @@ def test_iso_charset

def test_unencoded_subject
TestMailer.delivery_method = :test
expected = new_mail
expected = new_mail
expected.to = @recipient
expected.subject = "testing unencoded subject"
expected.body = "Nothing to see here."
Expand Down Expand Up @@ -1048,8 +1048,9 @@ def test_with_mail_object_deliver
def test_multipart_with_template_path_with_dots
mail = FunkyPathMailer.multipart_with_template_path_with_dots(@recipient)
assert_equal 2, mail.parts.length
assert "text/plain", mail.parts[1].mime_type
assert "UTF-8", mail.parts[1].charset
assert_equal "text/plain", mail.parts[0].mime_type
assert_equal "text/html", mail.parts[1].mime_type
assert_equal "UTF-8", mail.parts[1].charset
end

def test_custom_content_type_attributes
Expand Down Expand Up @@ -1150,15 +1151,15 @@ def teardown
end

def test_should_respond_to_new
assert RespondToMailer.respond_to?(:new)
assert_respond_to RespondToMailer, :new
end

def test_should_respond_to_create_with_template_suffix
assert RespondToMailer.respond_to?(:create_any_old_template)
assert_respond_to RespondToMailer, :create_any_old_template
end

def test_should_respond_to_deliver_with_template_suffix
assert RespondToMailer.respond_to?(:deliver_any_old_template)
assert_respond_to RespondToMailer, :deliver_any_old_template
end

def test_should_not_respond_to_new_with_template_suffix
Expand Down
4 changes: 2 additions & 2 deletions actionmailer/test/test_helper_test.rb
Expand Up @@ -18,7 +18,7 @@ def test_setup_sets_right_action_mailer_options
end

def test_setup_creates_the_expected_mailer
assert @expected.is_a?(Mail::Message)
assert_kind_of Mail::Message, @expected
assert_equal "1.0", @expected.mime_version
assert_equal "text/plain", @expected.mime_type
end
Expand Down Expand Up @@ -121,7 +121,7 @@ def setup
end

def test_setup_shouldnt_conflict_with_mailer_setup
assert @expected.is_a?(Mail::Message)
assert_kind_of Mail::Message, @expected
assert_equal 'a value', @test_var
end
end
2 changes: 2 additions & 0 deletions actionpack/CHANGELOG
@@ -1,5 +1,7 @@
*Rails 3.0.0 [beta 4/release candidate] (unreleased)*

* Make session stores rely on request.cookie_jar and change set_session semantics to return the cookie value instead of a boolean. [José Valim]

* OAuth 2: HTTP Token Authorization support to complement Basic and Digest Authorization. [Rick Olson]

* Fixed inconsistencies in form builder and view helpers #4432 [Neeraj Singh]
Expand Down
2 changes: 1 addition & 1 deletion actionpack/lib/action_controller/metal/helpers.rb
Expand Up @@ -104,7 +104,7 @@ def modules_for_helpers(args)
def all_application_helpers
helpers = []
helpers_path.each do |path|
extract = /^#{Regexp.quote(path)}\/?(.*)_helper.rb$/
extract = /^#{Regexp.quote(path.to_s)}\/?(.*)_helper.rb$/
helpers += Dir["#{path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') }
end
helpers.sort!
Expand Down
35 changes: 2 additions & 33 deletions actionpack/lib/action_dispatch/http/response.rb
Expand Up @@ -140,7 +140,7 @@ def location=(url)
def to_a
assign_default_content_type_and_charset!
handle_conditional_get!
self["Set-Cookie"] = @cookie.join("\n") unless @cookie.blank?
self["Set-Cookie"] = self["Set-Cookie"].join("\n") if self["Set-Cookie"].respond_to?(:join)
self["ETag"] = @_etag if @_etag
super
end
Expand Down Expand Up @@ -170,7 +170,7 @@ def write(str)
# assert_equal 'AuthorOfNewPage', r.cookies['author']
def cookies
cookies = {}
if header = @cookie
if header = self["Set-Cookie"]
header = header.split("\n") if header.respond_to?(:to_str)
header.each do |cookie|
if pair = cookie.split(';').first
Expand All @@ -182,37 +182,6 @@ def cookies
cookies
end

def set_cookie(key, value)
case value
when Hash
domain = "; domain=" + value[:domain] if value[:domain]
path = "; path=" + value[:path] if value[:path]
# According to RFC 2109, we need dashes here.
# N.B.: cgi.rb uses spaces...
expires = "; expires=" + value[:expires].clone.gmtime.
strftime("%a, %d-%b-%Y %H:%M:%S GMT") if value[:expires]
secure = "; secure" if value[:secure]
httponly = "; HttpOnly" if value[:httponly]
value = value[:value]
end
value = [value] unless Array === value
cookie = Rack::Utils.escape(key) + "=" +
value.map { |v| Rack::Utils.escape v }.join("&") +
"#{domain}#{path}#{expires}#{secure}#{httponly}"

@cookie << cookie
end

def delete_cookie(key, value={})
@cookie.reject! { |cookie|
cookie =~ /\A#{Rack::Utils.escape(key)}=/
}

set_cookie(key,
{:value => '', :path => nil, :domain => nil,
:expires => Time.at(0) }.merge(value))
end

private
def assign_default_content_type_and_charset!
return if headers[CONTENT_TYPE].present?
Expand Down
54 changes: 44 additions & 10 deletions actionpack/lib/action_dispatch/middleware/cookies.rb
Expand Up @@ -52,9 +52,15 @@ def cookie_jar
# * <tt>:httponly</tt> - Whether this cookie is accessible via scripting or
# only HTTP. Defaults to +false+.
class Cookies
HTTP_HEADER = "Set-Cookie".freeze
TOKEN_KEY = "action_dispatch.secret_token".freeze

# Raised when storing more than 4K of session data.
class CookieOverflow < StandardError; end

class CookieJar < Hash #:nodoc:
def self.build(request)
secret = request.env["action_dispatch.secret_token"]
secret = request.env[TOKEN_KEY]
new(secret).tap do |hash|
hash.update(request.cookies)
end
Expand Down Expand Up @@ -134,9 +140,9 @@ def signed
@signed ||= SignedCookieJar.new(self, @secret)
end

def write(response)
@set_cookies.each { |k, v| response.set_cookie(k, v) }
@delete_cookies.each { |k, v| response.delete_cookie(k, v) }
def write(headers)
@set_cookies.each { |k, v| ::Rack::Utils.set_cookie_header!(headers, k, v) }
@delete_cookies.each { |k, v| ::Rack::Utils.delete_cookie_header!(headers, k, v) }
end
end

Expand Down Expand Up @@ -166,8 +172,11 @@ def method_missing(method, *arguments, &block)
end

class SignedCookieJar < CookieJar #:nodoc:
MAX_COOKIE_SIZE = 4096 # Cookies can typically store 4096 bytes.
SECRET_MIN_LENGTH = 30 # Characters

def initialize(parent_jar, secret)
raise "You must set config.secret_token in your app's config" if secret.blank?
ensure_secret_secure(secret)
@parent_jar = parent_jar
@verifier = ActiveSupport::MessageVerifier.new(secret)
end
Expand All @@ -176,6 +185,8 @@ def [](name)
if signed_message = @parent_jar[name]
@verifier.verify(signed_message)
end
rescue ActiveSupport::MessageVerifier::InvalidSignature
nil
end

def []=(key, options)
Expand All @@ -186,12 +197,34 @@ def []=(key, options)
options = { :value => @verifier.generate(options) }
end

raise CookieOverflow if options[:value].size > MAX_COOKIE_SIZE
@parent_jar[key] = options
end

def method_missing(method, *arguments, &block)
@parent_jar.send(method, *arguments, &block)
end

protected

# To prevent users from using something insecure like "Password" we make sure that the
# secret they've provided is at least 30 characters in length.
def ensure_secret_secure(secret)
if secret.blank?
raise ArgumentError, "A secret is required to generate an " +
"integrity hash for cookie session data. Use " +
"config.secret_token = \"some secret phrase of at " +
"least #{SECRET_MIN_LENGTH} characters\"" +
"in config/application.rb"
end

if secret.length < SECRET_MIN_LENGTH
raise ArgumentError, "Secret should be something secure, " +
"like \"#{ActiveSupport::SecureRandom.hex(16)}\". The value you " +
"provided, \"#{secret}\", is shorter than the minimum length " +
"of #{SECRET_MIN_LENGTH} characters"
end
end
end

def initialize(app)
Expand All @@ -202,12 +235,13 @@ def call(env)
status, headers, body = @app.call(env)

if cookie_jar = env['action_dispatch.cookies']
response = Rack::Response.new(body, status, headers)
cookie_jar.write(response)
response.to_a
else
[status, headers, body]
cookie_jar.write(headers)
if headers[HTTP_HEADER].respond_to?(:join)
headers[HTTP_HEADER] = headers[HTTP_HEADER].join("\n")
end
end

[status, headers, body]
end
end
end

0 comments on commit 7f07cc3

Please sign in to comment.