aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/lib/abstract_controller.rb2
-rw-r--r--actionpack/lib/abstract_controller/base.rb2
-rw-r--r--actionpack/lib/abstract_controller/rendering.rb4
-rw-r--r--actionpack/lib/action_controller/base.rb4
-rw-r--r--actionpack/lib/action_controller/metal/helpers.rb4
-rw-r--r--actionpack/lib/action_controller/metal/http_authentication.rb6
-rw-r--r--actionpack/lib/action_controller/metal/strong_parameters.rb49
-rw-r--r--actionpack/lib/action_controller/test_case.rb1
-rw-r--r--actionpack/lib/action_dispatch/http/cache.rb1
-rw-r--r--actionpack/lib/action_dispatch/http/filter_parameters.rb2
-rw-r--r--actionpack/lib/action_dispatch/http/parameters.rb11
-rw-r--r--actionpack/lib/action_dispatch/http/request.rb10
-rw-r--r--actionpack/lib/action_dispatch/http/url.rb3
-rw-r--r--actionpack/lib/action_dispatch/journey/formatter.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb7
-rw-r--r--actionpack/lib/action_dispatch/routing.rb3
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb4
-rw-r--r--actionpack/test/controller/new_base/render_html_test.rb1
-rw-r--r--actionpack/test/controller/required_params_test.rb17
-rw-r--r--actionpack/test/controller/url_for_integration_test.rb1
-rw-r--r--actionpack/test/dispatch/cookies_test.rb9
-rw-r--r--actionpack/test/dispatch/routing/ipv6_redirect_test.rb45
22 files changed, 142 insertions, 46 deletions
diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb
index fe9802e395..56c4033387 100644
--- a/actionpack/lib/abstract_controller.rb
+++ b/actionpack/lib/abstract_controller.rb
@@ -1,7 +1,5 @@
require 'action_pack'
require 'active_support/rails'
-require 'active_support/core_ext/module/attr_internal'
-require 'active_support/core_ext/module/anonymous'
require 'active_support/i18n'
module AbstractController
diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb
index 784092867c..4501202b8c 100644
--- a/actionpack/lib/abstract_controller/base.rb
+++ b/actionpack/lib/abstract_controller/base.rb
@@ -1,8 +1,8 @@
require 'erubis'
-require 'set'
require 'active_support/configurable'
require 'active_support/descendants_tracker'
require 'active_support/core_ext/module/anonymous'
+require 'active_support/core_ext/module/attr_internal'
module AbstractController
class Error < StandardError #:nodoc:
diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb
index 2bb7c2139e..6db0941b52 100644
--- a/actionpack/lib/abstract_controller/rendering.rb
+++ b/actionpack/lib/abstract_controller/rendering.rb
@@ -23,8 +23,8 @@ module AbstractController
def render(*args, &block)
options = _normalize_render(*args, &block)
self.response_body = render_to_body(options)
- if options[:plain]
- _set_content_type Mime::TEXT.to_s
+ if options[:html]
+ _set_content_type Mime::HTML.to_s
else
_set_content_type _get_content_type(rendered_format)
end
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 6c644862d5..0727bb8369 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -258,10 +258,6 @@ module ActionController
PROTECTED_IVARS
end
- def self.protected_instance_variables
- PROTECTED_IVARS
- end
-
ActiveSupport.run_load_hooks(:action_controller, self)
end
end
diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb
index fcaf3e6425..d3853e2e83 100644
--- a/actionpack/lib/action_controller/metal/helpers.rb
+++ b/actionpack/lib/action_controller/metal/helpers.rb
@@ -7,8 +7,8 @@ module ActionController
# extract complicated logic or reusable functionality is strongly encouraged. By default, each controller
# will include all helpers. These helpers are only accessible on the controller through <tt>.helpers</tt>
#
- # In previous versions of \Rails the controller will include a helper whose
- # name matches that of the controller, e.g., <tt>MyController</tt> will automatically
+ # In previous versions of \Rails the controller will include a helper which
+ # matches the name of the controller, e.g., <tt>MyController</tt> will automatically
# include <tt>MyHelper</tt>. To return old behavior set +config.action_controller.include_all_helpers+ to +false+.
#
# Additional helpers can be specified using the +helper+ class method in ActionController::Base or any
diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb
index bbb38cf8fc..15d4562abb 100644
--- a/actionpack/lib/action_controller/metal/http_authentication.rb
+++ b/actionpack/lib/action_controller/metal/http_authentication.rb
@@ -203,7 +203,7 @@ module ActionController
password = password_procedure.call(credentials[:username])
return false unless password
- method = request.env['rack.methodoverride.original_method'] || request.env['REQUEST_METHOD']
+ method = request.get_header('rack.methodoverride.original_method') || request.get_header('REQUEST_METHOD')
uri = credentials[:uri]
[true, false].any? do |trailing_question_mark|
@@ -260,8 +260,8 @@ module ActionController
end
def secret_token(request)
- key_generator = request.env["action_dispatch.key_generator"]
- http_auth_salt = request.env["action_dispatch.http_auth_salt"]
+ key_generator = request.key_generator
+ http_auth_salt = request.http_auth_salt
key_generator.generate_key(http_auth_salt)
end
diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb
index fc8e345d43..bf5c7003ff 100644
--- a/actionpack/lib/action_controller/metal/strong_parameters.rb
+++ b/actionpack/lib/action_controller/metal/strong_parameters.rb
@@ -240,19 +240,58 @@ module ActionController
self
end
- # Ensures that a parameter is present. If it's present, returns
- # the parameter at the given +key+, otherwise raises an
- # <tt>ActionController::ParameterMissing</tt> error.
+ # This method accepts both a single key and an array of keys.
+ #
+ # When passed a single key, if it exists and its associated value is
+ # either present or the singleton +false+, returns said value:
#
# ActionController::Parameters.new(person: { name: 'Francesco' }).require(:person)
# # => {"name"=>"Francesco"}
#
+ # Otherwise raises <tt>ActionController::ParameterMissing</tt>:
+ #
+ # ActionController::Parameters.new.require(:person)
+ # # ActionController::ParameterMissing: param is missing or the value is empty: person
+ #
# ActionController::Parameters.new(person: nil).require(:person)
- # # => ActionController::ParameterMissing: param is missing or the value is empty: person
+ # # ActionController::ParameterMissing: param is missing or the value is empty: person
+ #
+ # ActionController::Parameters.new(person: "\t").require(:person)
+ # # ActionController::ParameterMissing: param is missing or the value is empty: person
#
# ActionController::Parameters.new(person: {}).require(:person)
- # # => ActionController::ParameterMissing: param is missing or the value is empty: person
+ # # ActionController::ParameterMissing: param is missing or the value is empty: person
+ #
+ # When given an array of keys, the method tries to require each one of them
+ # in order. If it succeeds, an array with the respective return values is
+ # returned:
+ #
+ # params = ActionController::Parameters.new(user: { ... }, profile: { ... })
+ # user_params, profile_params = params.require(:user, :profile)
+ #
+ # Otherwise, the method reraises the first exception found:
+ #
+ # params = ActionController::Parameters.new(user: {}, profile: {})
+ # user_params, profile_params = params.require(:user, :profile)
+ # # ActionController::ParameterMissing: param is missing or the value is empty: user
+ #
+ # Technically this method can be used to fetch terminal values:
+ #
+ # # CAREFUL
+ # params = ActionController::Parameters.new(person: { name: 'Finn' })
+ # name = params.require(:person).require(:name) # CAREFUL
+ #
+ # but take into account that at some point those ones have to be permitted:
+ #
+ # def person_params
+ # params.require(:person).permit(:name).tap do |person_params|
+ # person_params.require(:name) # SAFER
+ # end
+ # end
+ #
+ # for example.
def require(key)
+ return key.map { |k| require(k) } if key.is_a?(Array)
value = self[key]
if value.present? || value == false
value
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index 39cbc0cd70..ebb4ebdd46 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -476,6 +476,7 @@ module ActionController
end
self.cookies.update @request.cookies
+ self.cookies.update_cookies_from_jar
@request.set_header 'HTTP_COOKIE', cookies.to_header
@request.delete_header 'action_dispatch.cookies'
diff --git a/actionpack/lib/action_dispatch/http/cache.rb b/actionpack/lib/action_dispatch/http/cache.rb
index 08ebd2e8b2..1d0a6b6eb3 100644
--- a/actionpack/lib/action_dispatch/http/cache.rb
+++ b/actionpack/lib/action_dispatch/http/cache.rb
@@ -1,4 +1,3 @@
-
module ActionDispatch
module Http
module Cache
diff --git a/actionpack/lib/action_dispatch/http/filter_parameters.rb b/actionpack/lib/action_dispatch/http/filter_parameters.rb
index e70e90018c..3f2c6ceba3 100644
--- a/actionpack/lib/action_dispatch/http/filter_parameters.rb
+++ b/actionpack/lib/action_dispatch/http/filter_parameters.rb
@@ -1,5 +1,3 @@
-require 'active_support/core_ext/hash/keys'
-require 'active_support/core_ext/object/duplicable'
require 'action_dispatch/http/parameter_filter'
module ActionDispatch
diff --git a/actionpack/lib/action_dispatch/http/parameters.rb b/actionpack/lib/action_dispatch/http/parameters.rb
index 277207ae6e..3c9f8cd9e4 100644
--- a/actionpack/lib/action_dispatch/http/parameters.rb
+++ b/actionpack/lib/action_dispatch/http/parameters.rb
@@ -1,6 +1,3 @@
-require 'active_support/core_ext/hash/keys'
-require 'active_support/core_ext/hash/indifferent_access'
-
module ActionDispatch
module Http
module Parameters
@@ -34,14 +31,6 @@ module ActionDispatch
def path_parameters
get_header(PARAMETERS_KEY) || {}
end
-
- private
-
- # Convert nested Hash to HashWithIndifferentAccess.
- #
- def normalize_encode_params(params)
- ActionDispatch::Request::Utils.normalize_encode_params params
- end
end
end
end
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index e6387768de..df621f1074 100644
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -158,6 +158,10 @@ module ActionDispatch
set_header('action_controller.instance'.freeze, controller)
end
+ def http_auth_salt
+ get_header "action_dispatch.http_auth_salt"
+ end
+
def show_exceptions? # :nodoc:
# We're treating `nil` as "unset", and we want the default setting to be
# `true`. This logic should be extracted to `env_config` and calculated
@@ -332,7 +336,7 @@ module ActionDispatch
# Override Rack's GET method to support indifferent access
def GET
get_header("action_dispatch.request.query_parameters") do |k|
- set_header k, normalize_encode_params(super || {})
+ set_header k, Request::Utils.normalize_encode_params(super || {})
end
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
raise ActionController::BadRequest.new(:query, e)
@@ -342,7 +346,7 @@ module ActionDispatch
# Override Rack's POST method to support indifferent access
def POST
get_header("action_dispatch.request.request_parameters") do
- self.request_parameters = normalize_encode_params(super || {})
+ self.request_parameters = Request::Utils.normalize_encode_params(super || {})
end
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
raise ActionController::BadRequest.new(:request, e)
@@ -358,7 +362,7 @@ module ActionDispatch
get_header('REDIRECT_X_HTTP_AUTHORIZATION')
end
- # True if the request came from localhost, 127.0.0.1.
+ # True if the request came from localhost, 127.0.0.1, or ::1.
def local?
LOCALHOST =~ remote_addr && LOCALHOST =~ remote_ip
end
diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb
index e413954066..54e64f892a 100644
--- a/actionpack/lib/action_dispatch/http/url.rb
+++ b/actionpack/lib/action_dispatch/http/url.rb
@@ -1,11 +1,10 @@
require 'active_support/core_ext/module/attribute_accessors'
-require 'active_support/core_ext/hash/slice'
module ActionDispatch
module Http
module URL
IP_HOST_REGEXP = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/
- HOST_REGEXP = /(^[^:]+:\/\/)?([^:]+)(?::(\d+$))?/
+ HOST_REGEXP = /(^[^:]+:\/\/)?(\[[^\]]+\]|[^:]+)(?::(\d+$))?/
PROTOCOL_REGEXP = /^([^:]+)(:)?(\/\/)?$/
mattr_accessor :tld_length
diff --git a/actionpack/lib/action_dispatch/journey/formatter.rb b/actionpack/lib/action_dispatch/journey/formatter.rb
index c19ff0f4db..0323360faa 100644
--- a/actionpack/lib/action_dispatch/journey/formatter.rb
+++ b/actionpack/lib/action_dispatch/journey/formatter.rb
@@ -33,7 +33,7 @@ module ActionDispatch
defaults = route.defaults
required_parts = route.required_parts
parameterized_parts.keep_if do |key, value|
- defaults[key].nil? || value.to_s != defaults[key].to_s || required_parts.include?(key)
+ (defaults[key].nil? && value.present?) || value.to_s != defaults[key].to_s || required_parts.include?(key)
end
return [route.format(parameterized_parts), params]
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index 6d0387cf74..f958a88e4b 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -319,6 +319,13 @@ module ActionDispatch
self
end
+ def update_cookies_from_jar
+ request_jar = @request.cookie_jar.instance_variable_get(:@cookies)
+ set_cookies = request_jar.reject { |k,_| @delete_cookies.key?(k) }
+
+ @cookies.update set_cookies if set_cookies
+ end
+
def to_header
@cookies.map { |k,v| "#{k}=#{v}" }.join ';'
end
diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb
index a42cf72f60..8757c9ea7f 100644
--- a/actionpack/lib/action_dispatch/routing.rb
+++ b/actionpack/lib/action_dispatch/routing.rb
@@ -1,7 +1,4 @@
# encoding: UTF-8
-require 'active_support/core_ext/object/to_param'
-require 'active_support/core_ext/regexp'
-require 'active_support/dependencies/autoload'
module ActionDispatch
# The routing module provides URL rewriting in native Ruby. It's a way to
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 1acfb2bfe8..87b826f7d0 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -1,10 +1,8 @@
-require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/hash/reverse_merge'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/enumerable'
require 'active_support/core_ext/array/extract_options'
-require 'active_support/core_ext/module/remove_method'
-require 'active_support/inflector'
+require 'active_support/core_ext/regexp'
require 'active_support/deprecation'
require 'action_dispatch/routing/redirection'
require 'action_dispatch/routing/endpoint'
diff --git a/actionpack/test/controller/new_base/render_html_test.rb b/actionpack/test/controller/new_base/render_html_test.rb
index 49c1b67d04..e9ea57e329 100644
--- a/actionpack/test/controller/new_base/render_html_test.rb
+++ b/actionpack/test/controller/new_base/render_html_test.rb
@@ -4,7 +4,6 @@ module RenderHtml
class MinimalController < ActionController::Metal
include AbstractController::Rendering
include ActionController::Rendering
- include ActionView::Rendering
def index
render html: "Hello World!"
diff --git a/actionpack/test/controller/required_params_test.rb b/actionpack/test/controller/required_params_test.rb
index a901e56332..168f64ce41 100644
--- a/actionpack/test/controller/required_params_test.rb
+++ b/actionpack/test/controller/required_params_test.rb
@@ -48,4 +48,21 @@ class ParametersRequireTest < ActiveSupport::TestCase
ActionController::Parameters.new(person: {}).require(:person)
end
end
+
+ test "require array when all required params are present" do
+ safe_params = ActionController::Parameters.new(person: {first_name: 'Gaurish', title: 'Mjallo', city: 'Barcelona'})
+ .require(:person)
+ .require([:first_name, :title])
+
+ assert_kind_of Array, safe_params
+ assert_equal ['Gaurish', 'Mjallo'], safe_params
+ end
+
+ test "require array when a required param is missing" do
+ assert_raises(ActionController::ParameterMissing) do
+ ActionController::Parameters.new(person: {first_name: 'Gaurish', title: nil})
+ .require(:person)
+ .require([:first_name, :title])
+ end
+ end
end
diff --git a/actionpack/test/controller/url_for_integration_test.rb b/actionpack/test/controller/url_for_integration_test.rb
index 0e4c2b7c32..dfc2712e3e 100644
--- a/actionpack/test/controller/url_for_integration_test.rb
+++ b/actionpack/test/controller/url_for_integration_test.rb
@@ -158,6 +158,7 @@ module ActionPack
['/posts/ping',[ { :controller => 'posts', :action => 'ping' }]],
['/posts/show/1',[ { :controller => 'posts', :action => 'show', :id => '1' }]],
+ ['/posts/show/1',[ { :controller => 'posts', :action => 'show', :id => '1', :format => '' }]],
['/posts',[ { :controller => 'posts' }]],
['/posts',[ { :controller => 'posts', :action => 'index' }]],
['/posts/create',[ { :action => 'create' }, {:day=>nil, :month=>nil, :controller=>"posts", :action=>"show_date"}, '/blog']],
diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb
index 3454e60697..e9b2fe3214 100644
--- a/actionpack/test/dispatch/cookies_test.rb
+++ b/actionpack/test/dispatch/cookies_test.rb
@@ -653,6 +653,15 @@ class CookiesTest < ActionController::TestCase
end
end
+ def test_cookie_jar_mutated_by_request_persists_on_future_requests
+ get :authenticate
+ cookie_jar = @request.cookie_jar
+ cookie_jar.signed[:user_id] = 123
+ assert_equal ["user_name", "user_id"], @request.cookie_jar.instance_variable_get(:@cookies).keys
+ get :get_signed_cookie
+ assert_equal ["user_name", "user_id"], @request.cookie_jar.instance_variable_get(:@cookies).keys
+ end
+
def test_raises_argument_error_if_missing_secret
assert_raise(ArgumentError, nil.inspect) {
@request.env["action_dispatch.key_generator"] = ActiveSupport::LegacyKeyGenerator.new(nil)
diff --git a/actionpack/test/dispatch/routing/ipv6_redirect_test.rb b/actionpack/test/dispatch/routing/ipv6_redirect_test.rb
new file mode 100644
index 0000000000..f1b2e8cfc7
--- /dev/null
+++ b/actionpack/test/dispatch/routing/ipv6_redirect_test.rb
@@ -0,0 +1,45 @@
+require 'abstract_unit'
+
+class IPv6IntegrationTest < ActionDispatch::IntegrationTest
+ Routes = ActionDispatch::Routing::RouteSet.new
+ include Routes.url_helpers
+
+ class ::BadRouteRequestController < ActionController::Base
+ include Routes.url_helpers
+ def index
+ render :text => foo_path
+ end
+
+ def foo
+ redirect_to :action => :index
+ end
+ end
+
+ Routes.draw do
+ get "/", :to => 'bad_route_request#index', :as => :index
+ get "/foo", :to => "bad_route_request#foo", :as => :foo
+ end
+
+ def _routes
+ Routes
+ end
+
+ APP = build_app Routes
+ def app
+ APP
+ end
+
+ test "bad IPv6 redirection" do
+ # def test_simple_redirect
+ request_env = {
+ 'REMOTE_ADDR' => 'fd07:2fa:6cff:2112:225:90ff:fec7:22aa',
+ 'HTTP_HOST' => '[fd07:2fa:6cff:2112:225:90ff:fec7:22aa]:3000',
+ 'SERVER_NAME' => '[fd07:2fa:6cff:2112:225:90ff:fec7:22aa]',
+ 'SERVER_PORT' => 3000 }
+
+ get '/foo', env: request_env
+ assert_response :redirect
+ assert_equal 'http://[fd07:2fa:6cff:2112:225:90ff:fec7:22aa]:3000/', redirect_to_url
+ end
+
+end