aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/lib/abstract_controller/rendering.rb2
-rw-r--r--actionpack/lib/action_controller/log_subscriber.rb6
-rw-r--r--actionpack/lib/action_controller/metal.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/callbacks.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb21
-rw-r--r--actionpack/lib/action_dispatch/middleware/reloader.rb8
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb16
-rw-r--r--actionpack/lib/action_view/partials.rb2
-rw-r--r--actionpack/lib/action_view/renderer/partial_renderer.rb4
-rw-r--r--actionpack/test/controller/log_subscriber_test.rb15
-rw-r--r--actionpack/test/controller/render_json_test.rb10
-rw-r--r--actionpack/test/controller/webservice_test.rb2
-rw-r--r--actionpack/test/dispatch/cookies_test.rb81
-rw-r--r--actionpack/test/template/render_test.rb7
-rw-r--r--actionpack/test/template/text_helper_test.rb8
-rw-r--r--actionpack/test/template/url_helper_test.rb8
17 files changed, 169 insertions, 27 deletions
diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb
index ec1160c31e..691310d5d2 100644
--- a/actionpack/lib/abstract_controller/rendering.rb
+++ b/actionpack/lib/abstract_controller/rendering.rb
@@ -113,7 +113,7 @@ module AbstractController
def render_to_string(*args, &block)
options = _normalize_args(*args, &block)
_normalize_options(options)
- render_to_body(options)
+ render_to_body(options).tap { self.response_body = nil }
end
# Raw rendering of a template to a Rack-compatible body.
diff --git a/actionpack/lib/action_controller/log_subscriber.rb b/actionpack/lib/action_controller/log_subscriber.rb
index 3b19310a69..3fae697cc3 100644
--- a/actionpack/lib/action_controller/log_subscriber.rb
+++ b/actionpack/lib/action_controller/log_subscriber.rb
@@ -16,7 +16,11 @@ module ActionController
payload = event.payload
additions = ActionController::Base.log_process_action(payload)
- message = "Completed #{payload[:status]} #{Rack::Utils::HTTP_STATUS_CODES[payload[:status]]} in %.0fms" % event.duration
+ status = payload[:status]
+ if status.nil? && payload[:exception].present?
+ status = Rack::Utils.status_code(ActionDispatch::ShowExceptions.rescue_responses[payload[:exception].first]) rescue nil
+ end
+ message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in %.0fms" % event.duration
message << " (#{additions.join(" | ")})" unless additions.blank?
info(message)
diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb
index 0caf37b8cd..032769a5c6 100644
--- a/actionpack/lib/action_controller/metal.rb
+++ b/actionpack/lib/action_controller/metal.rb
@@ -183,7 +183,7 @@ module ActionController
end
def response_body=(val)
- body = val.respond_to?(:each) ? val : [val]
+ body = val.nil? ? nil : (val.respond_to?(:each) ? val : [val])
super body
end
diff --git a/actionpack/lib/action_dispatch/middleware/callbacks.rb b/actionpack/lib/action_dispatch/middleware/callbacks.rb
index 4d038c29f2..1bb2ad7f67 100644
--- a/actionpack/lib/action_dispatch/middleware/callbacks.rb
+++ b/actionpack/lib/action_dispatch/middleware/callbacks.rb
@@ -25,7 +25,7 @@ module ActionDispatch
end
def call(env)
- _run_call_callbacks do
+ run_callbacks :call do
@app.call(env)
end
end
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index f369d2d3c2..7ac608f0a8 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -90,17 +90,14 @@ module ActionDispatch
# **.**, ***.** style TLDs like co.uk or com.au
#
# www.example.co.uk gives:
- # $1 => example
- # $2 => co.uk
+ # $& => example.co.uk
#
# example.com gives:
- # $1 => example
- # $2 => com
+ # $& => example.com
#
# lots.of.subdomains.example.local gives:
- # $1 => example
- # $2 => local
- DOMAIN_REGEXP = /([^.]*)\.([^.]*|..\...|...\...)$/
+ # $& => example.local
+ DOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/
def self.build(request)
secret = request.env[TOKEN_KEY]
@@ -131,11 +128,17 @@ module ActionDispatch
options[:path] ||= "/"
if options[:domain] == :all
+ # if there is a provided tld length then we use it otherwise default domain regexp
+ domain_regexp = options[:tld_length] ? /([^.]+\.?){#{options[:tld_length]}}$/ : DOMAIN_REGEXP
+
# if host is not ip and matches domain regexp
# (ip confirms to domain regexp so we explicitly check for ip)
- options[:domain] = if (@host !~ /^[\d.]+$/) && (@host =~ DOMAIN_REGEXP)
- ".#{$1}.#{$2}"
+ options[:domain] = if (@host !~ /^[\d.]+$/) && (@host =~ domain_regexp)
+ ".#{$&}"
end
+ elsif options[:domain].is_a? Array
+ # if host matches one of the supplied domains without a dot in front of it
+ options[:domain] = options[:domain].find {|domain| @host.include? domain[/^\.?(.*)$/, 1] }
end
end
diff --git a/actionpack/lib/action_dispatch/middleware/reloader.rb b/actionpack/lib/action_dispatch/middleware/reloader.rb
index f6ab368ad8..29289a76b4 100644
--- a/actionpack/lib/action_dispatch/middleware/reloader.rb
+++ b/actionpack/lib/action_dispatch/middleware/reloader.rb
@@ -43,12 +43,12 @@ module ActionDispatch
# Execute all prepare callbacks.
def self.prepare!
- new(nil).send(:_run_prepare_callbacks)
+ new(nil).run_callbacks :prepare
end
# Execute all cleanup callbacks.
def self.cleanup!
- new(nil).send(:_run_cleanup_callbacks)
+ new(nil).run_callbacks :cleanup
end
def initialize(app)
@@ -64,12 +64,12 @@ module ActionDispatch
end
def call(env)
- _run_prepare_callbacks
+ run_callbacks :prepare
response = @app.call(env)
response[2].extend(CleanupOnClose)
response
rescue Exception
- _run_cleanup_callbacks
+ run_callbacks :cleanup
raise
end
end
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index 3d276000a1..4f7f5c454f 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -459,7 +459,7 @@ module ActionView
end
AUTO_LINK_RE = %r{
- (?: ([\w+.:-]+:)// | www\. )
+ (?: ([0-9A-Za-z+.:-]+:)// | www\. )
[^\s<]+
}x
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index c23315b344..cfa88c91e3 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -253,8 +253,9 @@ module ActionView
# using the +link_to+ method with the <tt>:method</tt> modifier as described in
# the +link_to+ documentation.
#
- # The generated form element has a class name of <tt>button_to</tt>
- # to allow styling of the form itself and its children. You can control
+ # By default, the generated form element has a class name of <tt>button_to</tt>
+ # to allow styling of the form itself and its children. This can be changed
+ # using the <tt>:form_class</tt> modifier within +html_options+. You can control
# the form submission and input element behavior using +html_options+.
# This method accepts the <tt>:method</tt> and <tt>:confirm</tt> modifiers
# described in the +link_to+ documentation. If no <tt>:method</tt> modifier
@@ -275,6 +276,8 @@ module ActionView
# processed normally, otherwise no action is taken.
# * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the
# submit behaviour. By default this behaviour is an ajax submit.
+ # * <tt>:form_class</tt> - This controls the class of the form within which the submit button will
+ # be placed
#
# ==== Examples
# <%= button_to "New", :action => "new" %>
@@ -283,6 +286,12 @@ module ActionView
# # </form>"
#
#
+ # <%= button_to "New", :action => "new", :form_class => "new-thing" %>
+ # # => "<form method="post" action="/controller/new" class="new-thing">
+ # # <div><input value="New" type="submit" /></div>
+ # # </form>"
+ #
+ #
# <%= button_to "Delete Image", { :action => "delete", :id => @image.id },
# :confirm => "Are you sure?", :method => :delete %>
# # => "<form method="post" action="/images/delete/1" class="button_to">
@@ -312,6 +321,7 @@ module ActionView
end
form_method = method.to_s == 'get' ? 'get' : 'post'
+ form_class = html_options.delete('form_class') || 'button_to'
remote = html_options.delete('remote')
@@ -327,7 +337,7 @@ module ActionView
html_options.merge!("type" => "submit", "value" => name)
- ("<form method=\"#{form_method}\" action=\"#{ERB::Util.html_escape(url)}\" #{"data-remote=\"true\"" if remote} class=\"button_to\"><div>" +
+ ("<form method=\"#{form_method}\" action=\"#{ERB::Util.html_escape(url)}\" #{"data-remote=\"true\"" if remote} class=\"#{ERB::Util.html_escape(form_class)}\"><div>" +
method_tag + tag("input", html_options) + request_token_tag + "</div></form>").html_safe
end
diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb
index 56c661c00c..c181689e62 100644
--- a/actionpack/lib/action_view/partials.rb
+++ b/actionpack/lib/action_view/partials.rb
@@ -40,7 +40,7 @@ module ActionView
# With the <tt>:as</tt> option we can specify a different name for said local variable. For example, if we
# wanted it to be +agreement+ instead of +contract+ we'd do:
#
- # <%= render :partial => "contract", :as => :agreement %>
+ # <%= render :partial => "contract", :as => 'agreement' %>
#
# The <tt>:object</tt> option can be used to directly specify which object is rendered into the partial;
# useful when the template's object is elsewhere, in a different ivar or in a local variable for instance.
diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb
index 3fdea23a4a..94c0a8a8fb 100644
--- a/actionpack/lib/action_view/renderer/partial_renderer.rb
+++ b/actionpack/lib/action_view/renderer/partial_renderer.rb
@@ -108,7 +108,7 @@ module ActionView
locals << @variable_counter if @collection
find_template(path, locals)
end
- end
+ end
def find_template(path=@path, locals=@locals.keys)
prefixes = path.include?(?/) ? [] : @view.controller_prefixes
@@ -159,7 +159,7 @@ module ActionView
end
def retrieve_variable(path)
- variable = @options[:as] || path[%r'_?(\w+)(\.\w+)*$', 1].to_sym
+ variable = @options[:as].try(:to_sym) || path[%r'_?(\w+)(\.\w+)*$', 1].to_sym
variable_counter = :"#{variable}_counter" if @collection
[variable, variable_counter]
end
diff --git a/actionpack/test/controller/log_subscriber_test.rb b/actionpack/test/controller/log_subscriber_test.rb
index cac0881133..21bbd83653 100644
--- a/actionpack/test/controller/log_subscriber_test.rb
+++ b/actionpack/test/controller/log_subscriber_test.rb
@@ -32,6 +32,11 @@ module Another
cache_page("Super soaker", "/index.html")
render :nothing => true
end
+
+ def with_exception
+ raise Exception
+ end
+
end
end
@@ -168,6 +173,16 @@ class ACLogSubscriberTest < ActionController::TestCase
ensure
@controller.config.perform_caching = true
end
+
+ def test_process_action_with_exception_includes_http_status_code
+ begin
+ get :with_exception
+ wait
+ rescue Exception => e
+ end
+ assert_equal 2, logs.size
+ assert_match(/Completed 500/, logs.last)
+ end
def logs
@logs ||= @logger.logged(:info)
diff --git a/actionpack/test/controller/render_json_test.rb b/actionpack/test/controller/render_json_test.rb
index 6dd2a9f23d..fc604a2db3 100644
--- a/actionpack/test/controller/render_json_test.rb
+++ b/actionpack/test/controller/render_json_test.rb
@@ -26,6 +26,10 @@ class RenderJsonTest < ActionController::TestCase
render :json => nil
end
+ def render_json_render_to_string
+ render :text => render_to_string(:json => '[]')
+ end
+
def render_json_hello_world
render :json => ActiveSupport::JSON.encode(:hello => 'world')
end
@@ -76,6 +80,12 @@ class RenderJsonTest < ActionController::TestCase
assert_equal 'application/json', @response.content_type
end
+ def test_render_json_render_to_string
+ get :render_json_render_to_string
+ assert_equal '[]', @response.body
+ end
+
+
def test_render_json
get :render_json_hello_world
assert_equal '{"hello":"world"}', @response.body
diff --git a/actionpack/test/controller/webservice_test.rb b/actionpack/test/controller/webservice_test.rb
index 6ba4c6c48d..621fb79915 100644
--- a/actionpack/test/controller/webservice_test.rb
+++ b/actionpack/test/controller/webservice_test.rb
@@ -216,7 +216,7 @@ class WebServiceTest < ActionDispatch::IntegrationTest
def test_typecast_as_yaml
with_test_route_set do
with_params_parsers Mime::YAML => :yaml do
- yaml = <<-YAML
+ yaml = (<<-YAML).strip
---
data:
a: 15
diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb
index e2040401c7..1cfea6aa12 100644
--- a/actionpack/test/dispatch/cookies_test.rb
+++ b/actionpack/test/dispatch/cookies_test.rb
@@ -95,6 +95,26 @@ class CookiesTest < ActionController::TestCase
head :ok
end
+ def set_cookie_with_domain_and_tld
+ cookies[:user_name] = {:value => "rizwanreza", :domain => :all, :tld_length => 2}
+ head :ok
+ end
+
+ def delete_cookie_with_domain_and_tld
+ cookies.delete(:user_name, :domain => :all, :tld_length => 2)
+ head :ok
+ end
+
+ def set_cookie_with_domains
+ cookies[:user_name] = {:value => "rizwanreza", :domain => %w(example1.com example2.com .example3.com)}
+ head :ok
+ end
+
+ def delete_cookie_with_domains
+ cookies.delete(:user_name, :domain => %w(example1.com example2.com .example3.com))
+ head :ok
+ end
+
def symbol_key
cookies[:user_name] = "david"
head :ok
@@ -322,6 +342,67 @@ class CookiesTest < ActionController::TestCase
assert_cookie_header "user_name=; domain=.nextangle.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"
end
+ def test_cookie_with_all_domain_option_and_tld_length
+ get :set_cookie_with_domain_and_tld
+ assert_response :success
+ assert_cookie_header "user_name=rizwanreza; domain=.nextangle.com; path=/"
+ end
+
+ def test_cookie_with_all_domain_option_using_a_non_standard_tld_and_tld_length
+ @request.host = "two.subdomains.nextangle.local"
+ get :set_cookie_with_domain_and_tld
+ assert_response :success
+ assert_cookie_header "user_name=rizwanreza; domain=.nextangle.local; path=/"
+ end
+
+ def test_cookie_with_all_domain_option_using_host_with_port_and_tld_length
+ @request.host = "nextangle.local:3000"
+ get :set_cookie_with_domain_and_tld
+ assert_response :success
+ assert_cookie_header "user_name=rizwanreza; domain=.nextangle.local; path=/"
+ end
+
+ def test_deleting_cookie_with_all_domain_option_and_tld_length
+ get :delete_cookie_with_domain_and_tld
+ assert_response :success
+ assert_cookie_header "user_name=; domain=.nextangle.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"
+ end
+
+ def test_cookie_with_several_preset_domains_using_one_of_these_domains
+ @request.host = "example1.com"
+ get :set_cookie_with_domains
+ assert_response :success
+ assert_cookie_header "user_name=rizwanreza; domain=example1.com; path=/"
+ end
+
+ def test_cookie_with_several_preset_domains_using_other_domain
+ @request.host = "other-domain.com"
+ get :set_cookie_with_domains
+ assert_response :success
+ assert_cookie_header "user_name=rizwanreza; path=/"
+ end
+
+ def test_cookie_with_several_preset_domains_using_shared_domain
+ @request.host = "example3.com"
+ get :set_cookie_with_domains
+ assert_response :success
+ assert_cookie_header "user_name=rizwanreza; domain=.example3.com; path=/"
+ end
+
+ def test_deletings_cookie_with_several_preset_domains_using_one_of_these_domains
+ @request.host = "example2.com"
+ get :delete_cookie_with_domains
+ assert_response :success
+ assert_cookie_header "user_name=; domain=example2.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"
+ end
+
+ def test_deletings_cookie_with_several_preset_domains_using_other_domain
+ @request.host = "other-domain.com"
+ get :delete_cookie_with_domains
+ assert_response :success
+ assert_cookie_header "user_name=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"
+ end
+
def test_cookies_hash_is_indifferent_access
[:symbol_key, :string_key].each do |cookie_key|
get cookie_key
diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb
index 38bedd2e4e..e02d69231f 100644
--- a/actionpack/test/template/render_test.rb
+++ b/actionpack/test/template/render_test.rb
@@ -146,7 +146,12 @@ module RenderTestCases
assert_equal "Hello: davidHello: mary", @view.render(:partial => "test/customer", :collection => [ Customer.new("david"), Customer.new("mary") ])
end
- def test_render_partial_collection_as
+ def test_render_partial_collection_as_by_string
+ assert_equal "david david davidmary mary mary",
+ @view.render(:partial => "test/customer_with_var", :collection => [ Customer.new("david"), Customer.new("mary") ], :as => 'customer')
+ end
+
+ def test_render_partial_collection_as_by_symbol
assert_equal "david david davidmary mary mary",
@view.render(:partial => "test/customer_with_var", :collection => [ Customer.new("david"), Customer.new("mary") ], :as => :customer)
end
diff --git a/actionpack/test/template/text_helper_test.rb b/actionpack/test/template/text_helper_test.rb
index 9e9ed9120d..d0d4286393 100644
--- a/actionpack/test/template/text_helper_test.rb
+++ b/actionpack/test/template/text_helper_test.rb
@@ -1,4 +1,4 @@
-# encoding: us-ascii
+# encoding: utf-8
require 'abstract_unit'
require 'testing_sandbox'
@@ -415,6 +415,12 @@ class TextHelperTest < ActionView::TestCase
link10_raw = 'http://www.mail-archive.com/ruby-talk@ruby-lang.org/'
link10_result = generate_result(link10_raw)
assert_equal %(<p>#{link10_result} Link</p>), auto_link("<p>#{link10_raw} Link</p>")
+
+ link11_raw = 'http://asakusa.rubyist.net/'
+ link11_result = generate_result(link11_raw)
+ with_kcode 'u' do
+ assert_equal %(浅草.rbの公式サイトはこちら#{link11_result}), auto_link("浅草.rbの公式サイトはこちら#{link11_raw}")
+ end
end
def test_auto_link_should_sanitize_input_when_sanitize_option_is_not_false
diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb
index 4a8cea36d4..2e1661a0ac 100644
--- a/actionpack/test/template/url_helper_test.rb
+++ b/actionpack/test/template/url_helper_test.rb
@@ -50,6 +50,14 @@ class UrlHelperTest < ActiveSupport::TestCase
assert_dom_equal "<form method=\"post\" action=\"http://www.example.com\" class=\"button_to\"><div><input type=\"submit\" value=\"Hello\" /></div></form>", button_to("Hello", "http://www.example.com")
end
+ def test_button_to_with_form_class
+ assert_dom_equal "<form method=\"post\" action=\"http://www.example.com\" class=\"custom-class\"><div><input type=\"submit\" value=\"Hello\" /></div></form>", button_to("Hello", "http://www.example.com", :form_class => 'custom-class')
+ end
+
+ def test_button_to_with_form_class_escapes
+ assert_dom_equal "<form method=\"post\" action=\"http://www.example.com\" class=\"&lt;script&gt;evil_js&lt;/script&gt;\"><div><input type=\"submit\" value=\"Hello\" /></div></form>", button_to("Hello", "http://www.example.com", :form_class => '<script>evil_js</script>')
+ end
+
def test_button_to_with_query
assert_dom_equal "<form method=\"post\" action=\"http://www.example.com/q1=v1&amp;q2=v2\" class=\"button_to\"><div><input type=\"submit\" value=\"Hello\" /></div></form>", button_to("Hello", "http://www.example.com/q1=v1&q2=v2")
end