aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/abstract_controller/base.rb2
-rw-r--r--actionpack/lib/abstract_controller/callbacks.rb2
-rw-r--r--actionpack/lib/abstract_controller/collector.rb13
-rw-r--r--actionpack/lib/abstract_controller/rendering.rb6
-rw-r--r--actionpack/lib/action_controller/metal.rb7
-rw-r--r--actionpack/lib/action_controller/metal/data_streaming.rb26
-rw-r--r--actionpack/lib/action_controller/metal/exceptions.rb17
-rw-r--r--actionpack/lib/action_controller/metal/http_authentication.rb4
-rw-r--r--actionpack/lib/action_controller/metal/live.rb9
-rw-r--r--actionpack/lib/action_controller/metal/mime_responds.rb14
-rw-r--r--actionpack/lib/action_controller/metal/renderers.rb14
-rw-r--r--actionpack/lib/action_controller/metal/rendering.rb3
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb2
-rw-r--r--actionpack/lib/action_controller/metal/rescue.rb6
-rw-r--r--actionpack/lib/action_controller/metal/strong_parameters.rb2
-rw-r--r--actionpack/lib/action_controller/metal/testing.rb3
-rw-r--r--actionpack/lib/action_controller/test_case.rb19
-rw-r--r--actionpack/lib/action_dispatch/http/cache.rb23
-rw-r--r--actionpack/lib/action_dispatch/http/filter_parameters.rb4
-rw-r--r--actionpack/lib/action_dispatch/http/headers.rb5
-rw-r--r--actionpack/lib/action_dispatch/http/mime_negotiation.rb16
-rw-r--r--actionpack/lib/action_dispatch/http/mime_type.rb75
-rw-r--r--actionpack/lib/action_dispatch/http/mime_types.rb3
-rw-r--r--actionpack/lib/action_dispatch/http/parameters.rb6
-rw-r--r--actionpack/lib/action_dispatch/http/request.rb11
-rw-r--r--actionpack/lib/action_dispatch/http/response.rb51
-rw-r--r--actionpack/lib/action_dispatch/journey/nodes/node.rb2
-rw-r--r--actionpack/lib/action_dispatch/journey/path/pattern.rb6
-rw-r--r--actionpack/lib/action_dispatch/journey/route.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb4
-rw-r--r--actionpack/lib/action_dispatch/middleware/exception_wrapper.rb10
-rw-r--r--actionpack/lib/action_dispatch/middleware/params_parser.rb22
-rw-r--r--actionpack/lib/action_dispatch/middleware/reloader.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/abstract_store.rb20
-rw-r--r--actionpack/lib/action_dispatch/middleware/static.rb22
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb2
-rw-r--r--actionpack/lib/action_dispatch/request/utils.rb15
-rw-r--r--actionpack/lib/action_dispatch/routing.rb2
-rw-r--r--actionpack/lib/action_dispatch/routing/inspector.rb4
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb9
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb9
-rw-r--r--actionpack/lib/action_dispatch/routing/url_for.rb2
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions.rb2
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/response.rb14
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/routing.rb10
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb12
47 files changed, 283 insertions, 233 deletions
diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb
index 4501202b8c..7f349f2741 100644
--- a/actionpack/lib/abstract_controller/base.rb
+++ b/actionpack/lib/abstract_controller/base.rb
@@ -149,7 +149,7 @@ module AbstractController
# ==== Parameters
# * <tt>action_name</tt> - The name of an action to be tested
def available_action?(action_name)
- _find_action_name(action_name).present?
+ _find_action_name(action_name)
end
# Returns true if the given controller is capable of rendering
diff --git a/actionpack/lib/abstract_controller/callbacks.rb b/actionpack/lib/abstract_controller/callbacks.rb
index 13795f0dd8..287550db42 100644
--- a/actionpack/lib/abstract_controller/callbacks.rb
+++ b/actionpack/lib/abstract_controller/callbacks.rb
@@ -61,7 +61,7 @@ module AbstractController
# impossible to skip a callback defined using an anonymous proc
# using #skip_action_callback
def skip_action_callback(*names)
- ActiveSupport::Deprecation.warn('`skip_action_callback` is deprecated and will be removed in the next major version of Rails. Please use skip_before_action, skip_after_action or skip_around_action instead.')
+ ActiveSupport::Deprecation.warn('`skip_action_callback` is deprecated and will be removed in Rails 5.1. Please use skip_before_action, skip_after_action or skip_around_action instead.')
skip_before_action(*names, raise: false)
skip_after_action(*names, raise: false)
skip_around_action(*names, raise: false)
diff --git a/actionpack/lib/abstract_controller/collector.rb b/actionpack/lib/abstract_controller/collector.rb
index 3b5128cda5..55654be224 100644
--- a/actionpack/lib/abstract_controller/collector.rb
+++ b/actionpack/lib/abstract_controller/collector.rb
@@ -4,11 +4,10 @@ module AbstractController
module Collector
def self.generate_method_for_mime(mime)
sym = mime.is_a?(Symbol) ? mime : mime.to_sym
- const = sym.upcase
class_eval <<-RUBY, __FILE__, __LINE__ + 1
- def #{sym}(*args, &block) # def html(*args, &block)
- custom(Mime::Type[:#{const}], *args, &block) # custom(Mime::Type[:HTML], *args, &block)
- end # end
+ def #{sym}(*args, &block)
+ custom(Mime[:#{sym}], *args, &block)
+ end
RUBY
end
@@ -23,9 +22,7 @@ module AbstractController
protected
def method_missing(symbol, &block)
- const_name = symbol.upcase
-
- unless Mime::Type.registered?(const_name)
+ unless mime_constant = Mime[symbol]
raise NoMethodError, "To respond to a custom format, register it as a MIME type first: " \
"http://guides.rubyonrails.org/action_controller_overview.html#restful-downloads. " \
"If you meant to respond to a variant like :tablet or :phone, not a custom format, " \
@@ -33,8 +30,6 @@ module AbstractController
"format.html { |html| html.tablet { ... } }"
end
- mime_constant = Mime::Type[const_name]
-
if Mime::SET.include?(mime_constant)
AbstractController::Collector.generate_method_for_mime(mime_constant)
send(symbol, &block)
diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb
index 78b43f2fbe..a73f188623 100644
--- a/actionpack/lib/abstract_controller/rendering.rb
+++ b/actionpack/lib/abstract_controller/rendering.rb
@@ -22,13 +22,13 @@ module AbstractController
# :api: public
def render(*args, &block)
options = _normalize_render(*args, &block)
- self.response_body = render_to_body(options)
+ rendered_body = render_to_body(options)
if options[:html]
_set_html_content_type
else
_set_rendered_content_type rendered_format
end
- self.response_body
+ self.response_body = rendered_body
end
# Raw rendering of a template to a string.
@@ -55,7 +55,7 @@ module AbstractController
# Returns Content-Type of rendered content
# :api: public
def rendered_format
- Mime::Type[:TEXT]
+ Mime[:text]
end
DEFAULT_PROTECTED_INSTANCE_VARIABLES = Set.new %i(
diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb
index beeaae9d0c..8e040bb465 100644
--- a/actionpack/lib/action_controller/metal.rb
+++ b/actionpack/lib/action_controller/metal.rb
@@ -1,6 +1,5 @@
require 'active_support/core_ext/array/extract_options'
require 'action_dispatch/middleware/stack'
-require 'active_support/deprecation'
require 'action_dispatch/http/request'
require 'action_dispatch/http/response'
@@ -174,7 +173,11 @@ module ActionController
def response_body=(body)
body = [body] unless body.nil? || body.respond_to?(:each)
- response.body = body
+ response.reset_body!
+ body.each { |part|
+ next if part.empty?
+ response.write part
+ }
super
end
diff --git a/actionpack/lib/action_controller/metal/data_streaming.rb b/actionpack/lib/action_controller/metal/data_streaming.rb
index e6d7f958bb..957e7a3019 100644
--- a/actionpack/lib/action_controller/metal/data_streaming.rb
+++ b/actionpack/lib/action_controller/metal/data_streaming.rb
@@ -72,31 +72,7 @@ module ActionController #:nodoc:
self.status = options[:status] || 200
self.content_type = options[:content_type] if options.key?(:content_type)
- self.response_body = FileBody.new(path)
- end
-
- # Avoid having to pass an open file handle as the response body.
- # Rack::Sendfile will usually intercept the response and uses
- # the path directly, so there is no reason to open the file.
- class FileBody #:nodoc:
- attr_reader :to_path
-
- def initialize(path)
- @to_path = path
- end
-
- def body
- File.binread(to_path)
- end
-
- # Stream the file's contents if Rack::Sendfile isn't present.
- def each
- File.open(to_path, 'rb') do |file|
- while chunk = file.read(16384)
- yield chunk
- end
- end
- end
+ response.send_file path
end
# Sends the given binary data to the browser. This method is similar to
diff --git a/actionpack/lib/action_controller/metal/exceptions.rb b/actionpack/lib/action_controller/metal/exceptions.rb
index 18e003741d..5c0ada37be 100644
--- a/actionpack/lib/action_controller/metal/exceptions.rb
+++ b/actionpack/lib/action_controller/metal/exceptions.rb
@@ -3,14 +3,19 @@ module ActionController
end
class BadRequest < ActionControllerError #:nodoc:
- attr_reader :original_exception
+ def initialize(msg = nil, e = nil)
+ if e
+ ActiveSupport::Deprecation.warn("Passing #original_exception is deprecated and has no effect. " \
+ "Exceptions will automatically capture the original exception.", caller)
+ end
- def initialize(type = nil, e = nil)
- return super() unless type && e
+ super(msg)
+ set_backtrace $!.backtrace if $!
+ end
- super("Invalid #{type} parameters: #{e.message}")
- @original_exception = e
- set_backtrace e.backtrace
+ def original_exception
+ ActiveSupport::Deprecation.warn("#original_exception is deprecated. Use #cause instead.", caller)
+ cause
end
end
diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb
index fe470552b0..0a36fecd27 100644
--- a/actionpack/lib/action_controller/metal/http_authentication.rb
+++ b/actionpack/lib/action_controller/metal/http_authentication.rb
@@ -34,7 +34,7 @@ module ActionController
#
# def authenticate
# case request.format
- # when Mime::Type[:XML], Mime::Type[:ATOM]
+ # when Mime[:xml], Mime[:atom]
# if user = authenticate_with_http_basic { |u, p| @account.users.authenticate(u, p) }
# @current_user = user
# else
@@ -361,7 +361,7 @@ module ActionController
#
# def authenticate
# case request.format
- # when Mime::Type[:XML], Mime::Type[:ATOM]
+ # when Mime[:xml], Mime[:atom]
# if user = authenticate_with_http_token { |t, o| @account.users.authenticate(t, o) }
# @current_user = user
# else
diff --git a/actionpack/lib/action_controller/metal/live.rb b/actionpack/lib/action_controller/metal/live.rb
index 7db8d13e24..27b3eb4e58 100644
--- a/actionpack/lib/action_controller/metal/live.rb
+++ b/actionpack/lib/action_controller/metal/live.rb
@@ -36,8 +36,9 @@ module ActionController
extend ActiveSupport::Concern
module ClassMethods
- def make_response!(request)
- if request.env["HTTP_VERSION"] == "HTTP/1.0"
+ def make_response!(response)
+ request = response.request
+ if request.get_header("HTTP_VERSION") == "HTTP/1.0"
super
else
Live::Response.new.tap do |res|
@@ -293,8 +294,8 @@ module ActionController
response.close if response
end
- def set_response!(request)
- @_response = self.class.make_response! request
+ def set_response!(response)
+ @_response = self.class.make_response! response
end
end
end
diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb
index fc42fe5c07..6e346fadfe 100644
--- a/actionpack/lib/action_controller/metal/mime_responds.rb
+++ b/actionpack/lib/action_controller/metal/mime_responds.rb
@@ -91,11 +91,11 @@ module ActionController #:nodoc:
# and accept Rails' defaults, life will be much easier.
#
# If you need to use a MIME type which isn't supported by default, you can register your own handlers in
- # config/initializers/mime_types.rb as follows.
+ # +config/initializers/mime_types.rb+ as follows.
#
# Mime::Type.register "image/jpg", :jpg
#
- # Respond to also allows you to specify a common block for different formats by using any:
+ # Respond to also allows you to specify a common block for different formats by using +any+:
#
# def index
# @people = Person.all
@@ -151,7 +151,7 @@ module ActionController #:nodoc:
# format.html.none { render "trash" }
# end
#
- # Variants also support common `any`/`all` block that formats have.
+ # Variants also support common +any+/+all+ block that formats have.
#
# It works for both inline:
#
@@ -174,7 +174,7 @@ module ActionController #:nodoc:
# request.variant = [:tablet, :phone]
#
# which will work similarly to formats and MIME types negotiation. If there will be no
- # :tablet variant declared, :phone variant will be picked:
+ # +:tablet+ variant declared, +:phone+ variant will be picked:
#
# respond_to do |format|
# format.html.none
@@ -229,14 +229,14 @@ module ActionController #:nodoc:
@responses = {}
@variant = variant
- mimes.each { |mime| @responses[Mime::Type[mime.upcase.to_sym]] = nil }
+ mimes.each { |mime| @responses[Mime[mime]] = nil }
end
def any(*args, &block)
if args.any?
args.each { |type| send(type, &block) }
else
- custom(Mime::Type[:ALL], &block)
+ custom(Mime::ALL, &block)
end
end
alias :all :any
@@ -251,7 +251,7 @@ module ActionController #:nodoc:
end
def response
- response = @responses.fetch(format, @responses[Mime::Type[:ALL]])
+ response = @responses.fetch(format, @responses[Mime::ALL])
if response.is_a?(VariantCollector) # `format.html.phone` - variant inline syntax
response.variant
elsif response.nil? || response.arity == 0 # `format.html` - just a format, call its block
diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb
index d867c97b46..22e0bb5955 100644
--- a/actionpack/lib/action_controller/metal/renderers.rb
+++ b/actionpack/lib/action_controller/metal/renderers.rb
@@ -68,11 +68,11 @@ module ActionController
# ActionController::Renderers.add :csv do |obj, options|
# filename = options[:filename] || 'data'
# str = obj.respond_to?(:to_csv) ? obj.to_csv : obj.to_s
- # send_data str, type: Mime::Type[:CSV],
+ # send_data str, type: Mime[:csv],
# disposition: "attachment; filename=#{filename}.csv"
# end
#
- # Note that we used Mime::Type[:CSV] for the csv mime type as it comes with Rails.
+ # Note that we used Mime[:csv] for the csv mime type as it comes with Rails.
# For a custom renderer, you'll need to register a mime type with
# <tt>Mime::Type.register</tt>.
#
@@ -116,24 +116,24 @@ module ActionController
json = json.to_json(options) unless json.kind_of?(String)
if options[:callback].present?
- if content_type.nil? || content_type == Mime::Type[:JSON]
- self.content_type = Mime::Type[:JS]
+ if content_type.nil? || content_type == Mime[:json]
+ self.content_type = Mime[:js]
end
"/**/#{options[:callback]}(#{json})"
else
- self.content_type ||= Mime::Type[:JSON]
+ self.content_type ||= Mime[:json]
json
end
end
add :js do |js, options|
- self.content_type ||= Mime::Type[:JS]
+ self.content_type ||= Mime[:js]
js.respond_to?(:to_js) ? js.to_js(options) : js
end
add :xml do |xml, options|
- self.content_type ||= Mime::Type[:XML]
+ self.content_type ||= Mime[:xml]
xml.respond_to?(:to_xml) ? xml.to_xml(options) : xml
end
end
diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb
index 1ecccf9864..cce6fe7787 100644
--- a/actionpack/lib/action_controller/metal/rendering.rb
+++ b/actionpack/lib/action_controller/metal/rendering.rb
@@ -1,4 +1,3 @@
-require 'active_support/deprecation'
require 'active_support/core_ext/string/filters'
module ActionController
@@ -64,7 +63,7 @@ module ActionController
end
def _set_html_content_type
- self.content_type = Mime::Type[:HTML].to_s
+ self.content_type = Mime[:html].to_s
end
def _set_rendered_content_type(format)
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
index 5674eef67b..64f6f7cf51 100644
--- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -90,8 +90,10 @@ module ActionController #:nodoc:
#
# class FooController < ApplicationController
# protect_from_forgery except: :index
+ # end
#
# You can disable forgery protection on controller by skipping the verification before_action:
+ #
# skip_before_action :verify_authenticity_token
#
# Valid Options:
diff --git a/actionpack/lib/action_controller/metal/rescue.rb b/actionpack/lib/action_controller/metal/rescue.rb
index 68cc9a9c9b..81b9a7b9ed 100644
--- a/actionpack/lib/action_controller/metal/rescue.rb
+++ b/actionpack/lib/action_controller/metal/rescue.rb
@@ -7,10 +7,8 @@ module ActionController #:nodoc:
include ActiveSupport::Rescuable
def rescue_with_handler(exception)
- if (exception.respond_to?(:original_exception) &&
- (orig_exception = exception.original_exception) &&
- handler_for_rescue(orig_exception))
- exception = orig_exception
+ if exception.cause && handler_for_rescue(exception.cause)
+ exception = exception.cause
end
super(exception)
end
diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb
index 903dba3eb4..130ba61786 100644
--- a/actionpack/lib/action_controller/metal/strong_parameters.rb
+++ b/actionpack/lib/action_controller/metal/strong_parameters.rb
@@ -540,7 +540,7 @@ module ActionController
end
alias_method :delete_if, :reject!
- # Return values that were assigned to the given +keys+. Note that all the
+ # Returns values that were assigned to the given +keys+. Note that all the
# +Hash+ objects will be converted to <tt>ActionController::Parameters</tt>.
def values_at(*keys)
convert_value_to_parameters(@parameters.values_at(*keys))
diff --git a/actionpack/lib/action_controller/metal/testing.rb b/actionpack/lib/action_controller/metal/testing.rb
index b2b3b4283f..ac37b00010 100644
--- a/actionpack/lib/action_controller/metal/testing.rb
+++ b/actionpack/lib/action_controller/metal/testing.rb
@@ -4,9 +4,6 @@ module ActionController
# Behavior specific to functional tests
module Functional # :nodoc:
- def set_response!(request)
- end
-
def recycle!
@_url_options = nil
self.formats = nil
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index cf78688126..442ffd6d7c 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -34,7 +34,7 @@ module ActionController
self.session = session
self.session_options = TestSession::DEFAULT_OPTIONS
@custom_param_parsers = {
- Mime::Type[:XML] => lambda { |raw_post| Hash.from_xml(raw_post)['hash'] }
+ Mime[:xml] => lambda { |raw_post| Hash.from_xml(raw_post)['hash'] }
}
end
@@ -210,11 +210,11 @@ module ActionController
# # Simulate a POST response with the given HTTP parameters.
# post(:create, params: { book: { title: "Love Hina" }})
#
- # # Assert that the controller tried to redirect us to
+ # # Asserts that the controller tried to redirect us to
# # the created book's URI.
# assert_response :found
#
- # # Assert that the controller really put the book in the database.
+ # # Asserts that the controller really put the book in the database.
# assert_not_nil Book.find_by(title: "Love Hina")
# end
# end
@@ -402,7 +402,7 @@ module ActionController
MSG
@request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
- @request.env['HTTP_ACCEPT'] ||= [Mime::Type[:JS], Mime::Type[:HTML], Mime::Type[:XML], 'text/xml', Mime::Type[:ALL]].join(', ')
+ @request.env['HTTP_ACCEPT'] ||= [Mime[:js], Mime[:html], Mime[:xml], 'text/xml', '*/*'].join(', ')
__send__(*args).tap do
@request.env.delete 'HTTP_X_REQUESTED_WITH'
@request.env.delete 'HTTP_ACCEPT'
@@ -505,24 +505,23 @@ module ActionController
if xhr
@request.set_header 'HTTP_X_REQUESTED_WITH', 'XMLHttpRequest'
@request.fetch_header('HTTP_ACCEPT') do |k|
- @request.set_header k, [Mime::Type[:JS], Mime::Type[:HTML], Mime::Type[:XML], 'text/xml', Mime::Type[:ALL]].join(', ')
+ @request.set_header k, [Mime[:js], Mime[:html], Mime[:xml], 'text/xml', '*/*'].join(', ')
end
end
- @controller.request = @request
- @controller.response = @response
-
@request.fetch_header("SCRIPT_NAME") do |k|
@request.set_header k, @controller.config.relative_url_root
end
@controller.recycle!
- @controller.process(action)
+ @controller.dispatch(action, @request, @response)
+ @request = @controller.request
+ @response = @controller.response
@request.delete_header 'HTTP_COOKIE'
if @request.have_cookie_jar?
- unless @response.committed?
+ unless @request.cookie_jar.committed?
@request.cookie_jar.write(@response)
self.cookies.update(@request.cookie_jar.instance_variable_get(:@cookies))
end
diff --git a/actionpack/lib/action_dispatch/http/cache.rb b/actionpack/lib/action_dispatch/http/cache.rb
index 1d0a6b6eb3..30ade14c26 100644
--- a/actionpack/lib/action_dispatch/http/cache.rb
+++ b/actionpack/lib/action_dispatch/http/cache.rb
@@ -59,7 +59,7 @@ module ActionDispatch
end
def last_modified?
- have_header? LAST_MODIFIED
+ has_header? LAST_MODIFIED
end
def last_modified=(utc_time)
@@ -73,7 +73,7 @@ module ActionDispatch
end
def date?
- have_header? DATE
+ has_header? DATE
end
def date=(utc_time)
@@ -82,24 +82,19 @@ module ActionDispatch
def etag=(etag)
key = ActiveSupport::Cache.expand_cache_key(etag)
- set_header ETAG, %("#{Digest::MD5.hexdigest(key)}")
+ super %("#{Digest::MD5.hexdigest(key)}")
end
- def etag
- get_header ETAG
- end
- alias :etag? :etag
+ def etag?; etag; end
private
DATE = 'Date'.freeze
LAST_MODIFIED = "Last-Modified".freeze
- ETAG = "ETag".freeze
- CACHE_CONTROL = "Cache-Control".freeze
SPECIAL_KEYS = Set.new(%w[extras no-cache max-age public must-revalidate])
def cache_control_segments
- if cache_control = get_header(CACHE_CONTROL)
+ if cache_control = _cache_control
cache_control.delete(' ').split(',')
else
[]
@@ -153,11 +148,11 @@ module ActionDispatch
control.merge! cache_control
if control.empty?
- set_header CACHE_CONTROL, DEFAULT_CACHE_CONTROL
+ self._cache_control = DEFAULT_CACHE_CONTROL
elsif control[:no_cache]
- set_header CACHE_CONTROL, NO_CACHE
+ self._cache_control = NO_CACHE
if control[:extras]
- set_header(CACHE_CONTROL, get_header(CACHE_CONTROL) + ", #{control[:extras].join(', ')}")
+ self._cache_control = _cache_control + ", #{control[:extras].join(', ')}"
end
else
extras = control[:extras]
@@ -169,7 +164,7 @@ module ActionDispatch
options << MUST_REVALIDATE if control[:must_revalidate]
options.concat(extras) if extras
- set_header CACHE_CONTROL, options.join(", ")
+ self._cache_control = options.join(", ")
end
end
end
diff --git a/actionpack/lib/action_dispatch/http/filter_parameters.rb b/actionpack/lib/action_dispatch/http/filter_parameters.rb
index 9c0f39f2e7..9dcab79c3a 100644
--- a/actionpack/lib/action_dispatch/http/filter_parameters.rb
+++ b/actionpack/lib/action_dispatch/http/filter_parameters.rb
@@ -30,12 +30,12 @@ module ActionDispatch
@filtered_path = nil
end
- # Return a hash of parameters with all sensitive data replaced.
+ # Returns a hash of parameters with all sensitive data replaced.
def filtered_parameters
@filtered_parameters ||= parameter_filter.filter(parameters)
end
- # Return a hash of request.env with all sensitive data replaced.
+ # Returns a hash of request.env with all sensitive data replaced.
def filtered_env
@filtered_env ||= env_filter.filter(@env)
end
diff --git a/actionpack/lib/action_dispatch/http/headers.rb b/actionpack/lib/action_dispatch/http/headers.rb
index 9a3aaca3f0..12f81dc1a5 100644
--- a/actionpack/lib/action_dispatch/http/headers.rb
+++ b/actionpack/lib/action_dispatch/http/headers.rb
@@ -49,6 +49,11 @@ module ActionDispatch
@req.set_header env_name(key), value
end
+ # Add a value to a multivalued header like Vary or Accept-Encoding.
+ def add(key, value)
+ @req.add_header env_name(key), value
+ end
+
def key?(key)
@req.has_header? env_name(key)
end
diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
index a966c5e452..7acf91902d 100644
--- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb
+++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
@@ -10,7 +10,7 @@ module ActionDispatch
self.ignore_accept_header = false
end
- # The MIME type of the HTTP request, such as Mime::Type[:XML].
+ # The MIME type of the HTTP request, such as Mime[:xml].
#
# For backward compatibility, the post \format is extracted from the
# X-Post-Data-Format HTTP header if present.
@@ -49,9 +49,9 @@ module ActionDispatch
# Returns the MIME type for the \format used in the request.
#
- # GET /posts/5.xml | request.format => Mime::Type[:XML]
- # GET /posts/5.xhtml | request.format => Mime::Type[:HTML]
- # GET /posts/5 | request.format => Mime::Type[:HTML] or Mime::Type[:JS], or request.accepts.first
+ # GET /posts/5.xml | request.format => Mime[:xml]
+ # GET /posts/5.xhtml | request.format => Mime[:html]
+ # GET /posts/5 | request.format => Mime[:html] or Mime[:js], or request.accepts.first
#
def format(view_path = [])
formats.first || Mime::NullType.instance
@@ -70,9 +70,9 @@ module ActionDispatch
elsif use_accept_header && valid_accept_header
accepts
elsif xhr?
- [Mime::Type[:JS]]
+ [Mime[:js]]
else
- [Mime::Type[:HTML]]
+ [Mime[:html]]
end
set_header k, v
end
@@ -138,14 +138,14 @@ module ActionDispatch
#
def negotiate_mime(order)
formats.each do |priority|
- if priority == Mime::Type[:ALL]
+ if priority == Mime::ALL
return order.first
elsif order.include?(priority)
return priority
end
end
- order.include?(Mime::Type[:ALL]) ? format : nil
+ order.include?(Mime::ALL) ? format : nil
end
protected
diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb
index 36e90e5855..b64f660ec5 100644
--- a/actionpack/lib/action_dispatch/http/mime_type.rb
+++ b/actionpack/lib/action_dispatch/http/mime_type.rb
@@ -1,7 +1,6 @@
require 'singleton'
require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/string/starts_ends_with'
-require 'active_support/deprecation'
module Mime
class Mimes
@@ -46,7 +45,8 @@ module Mime
end
def const_missing(sym)
- if Mime::Type.registered?(sym)
+ ext = sym.downcase
+ if Mime[ext]
ActiveSupport::Deprecation.warn <<-eow
Accessing mime types via constants is deprecated. Please change:
@@ -54,16 +54,17 @@ Accessing mime types via constants is deprecated. Please change:
to:
- `Mime::Type[:#{sym}]`
+ `Mime[:#{ext}]`
eow
- Mime::Type[sym]
+ Mime[ext]
else
super
end
end
def const_defined?(sym, inherit = true)
- if Mime::Type.registered?(sym)
+ ext = sym.downcase
+ if Mime[ext]
ActiveSupport::Deprecation.warn <<-eow
Accessing mime types via constants is deprecated. Please change:
@@ -71,7 +72,7 @@ Accessing mime types via constants is deprecated. Please change:
to:
- `Mime::Type.registered?(:#{sym})`
+ `Mime[:#{ext}]`
eow
true
else
@@ -106,7 +107,7 @@ to:
def initialize(index, name, q = nil)
@index = index
@name = name
- q ||= 0.0 if @name == Mime::Type[:ALL].to_s # default wildcard match to end of list
+ q ||= 0.0 if @name == '*/*'.freeze # default wildcard match to end of list
@q = ((q || 1.0).to_f * 100).to_i
end
@@ -131,7 +132,7 @@ to:
exchange_xml_items if app_xml_idx > text_xml_idx # make sure app_xml is ahead of text_xml in the list
delete_at(text_xml_idx) # delete text_xml from the list
elsif text_xml_idx
- text_xml.name = Mime::Type[:XML].to_s
+ text_xml.name = Mime[:xml].to_s
end
# Look for more specific XML-based types and sort them ahead of app/xml
@@ -160,7 +161,7 @@ to:
end
def app_xml_idx
- @app_xml_idx ||= index(Mime::Type[:XML].to_s)
+ @app_xml_idx ||= index(Mime[:xml].to_s)
end
def text_xml
@@ -177,8 +178,6 @@ to:
end
end
- TYPES = {}
-
class << self
TRAILING_STAR_REGEXP = /(text|application)\/\*/
PARAMETER_SEPARATOR_REGEXP = /;\s*\w+="?\w+"?/
@@ -187,18 +186,6 @@ to:
@register_callbacks << block
end
- def registered?(symbol)
- TYPES.key? symbol
- end
-
- def [](symbol)
- TYPES[symbol]
- end
-
- def add_type(symbol, type)
- TYPES[symbol] = type
- end
-
def lookup(string)
LOOKUP[string]
end
@@ -215,7 +202,6 @@ to:
def register(string, symbol, mime_type_synonyms = [], extension_synonyms = [], skip_lookup = false)
new_mime = Type.new(string, symbol, mime_type_synonyms)
- add_type symbol.upcase, new_mime
SET << new_mime
@@ -255,13 +241,13 @@ to:
parse_data_with_trailing_star($1) if accept_header =~ TRAILING_STAR_REGEXP
end
- # For an input of <tt>'text'</tt>, returns <tt>[Mime::Type[:JSON], Mime::Type[:XML], Mime::Type[:ICS],
- # Mime::Type[:HTML], Mime::Type[:CSS], Mime::Type[:CSV], Mime::Type[:JS], Mime::Type[:YAML], Mime::Type[:TEXT]</tt>.
+ # For an input of <tt>'text'</tt>, returns <tt>[Mime[:json], Mime[:xml], Mime[:ics],
+ # Mime[:html], Mime[:css], Mime[:csv], Mime[:js], Mime[:yaml], Mime[:text]</tt>.
#
- # For an input of <tt>'application'</tt>, returns <tt>[Mime::Type[:HTML], Mime::Type[:JS],
- # Mime::Type[:XML], Mime::Type[:YAML], Mime::Type[:ATOM], Mime::Type[:JSON], Mime::Type[:RSS], Mime::Type[:URL_ENCODED_FORM]</tt>.
- def parse_data_with_trailing_star(input)
- Mime::SET.select { |m| m =~ input }
+ # For an input of <tt>'application'</tt>, returns <tt>[Mime[:html], Mime[:js],
+ # Mime[:xml], Mime[:yaml], Mime[:atom], Mime[:json], Mime[:rss], Mime[:url_encoded_form]</tt>.
+ def parse_data_with_trailing_star(type)
+ Mime::SET.select { |m| m =~ type }
end
# This method is opposite of register method.
@@ -270,12 +256,12 @@ to:
#
# Mime::Type.unregister(:mobile)
def unregister(symbol)
- symbol = symbol.upcase
- mime = TYPES.delete symbol
-
- SET.delete_if { |v| v.eql?(mime) }
- LOOKUP.delete_if { |_,v| v.eql?(mime) }
- EXTENSION_LOOKUP.delete_if { |_,v| v.eql?(mime) }
+ symbol = symbol.downcase
+ if mime = Mime[symbol]
+ SET.delete_if { |v| v.eql?(mime) }
+ LOOKUP.delete_if { |_, v| v.eql?(mime) }
+ EXTENSION_LOOKUP.delete_if { |_, v| v.eql?(mime) }
+ end
end
end
@@ -343,13 +329,24 @@ to:
def respond_to_missing?(method, include_private = false) #:nodoc:
method.to_s.ends_with? '?'
end
+ end
+
+ class AllType < Type
+ include Singleton
- class All < Type
- def all?; true; end
- def html?; true; end
+ def initialize
+ super '*/*', :all
end
+
+ def all?; true; end
+ def html?; true; end
end
+ # ALL isn't a real MIME type, so we don't register it for lookup with the
+ # other concrete types. It's a wildcard match that we use for `respond_to`
+ # negotiation internals.
+ ALL = AllType.instance
+
class NullType
include Singleton
diff --git a/actionpack/lib/action_dispatch/http/mime_types.rb b/actionpack/lib/action_dispatch/http/mime_types.rb
index 04828f7c87..87715205d9 100644
--- a/actionpack/lib/action_dispatch/http/mime_types.rb
+++ b/actionpack/lib/action_dispatch/http/mime_types.rb
@@ -31,6 +31,3 @@ Mime::Type.register "application/json", :json, %w( text/x-json application/jsonr
Mime::Type.register "application/pdf", :pdf, [], %w(pdf)
Mime::Type.register "application/zip", :zip, [], %w(zip)
-
-# Create Mime::Type[:ALL] but do not add it to the SET.
-Mime::Type.add_type :ALL, Mime::Type::All.new("*/*", :all, [])
diff --git a/actionpack/lib/action_dispatch/http/parameters.rb b/actionpack/lib/action_dispatch/http/parameters.rb
index e3c4392760..c9df787351 100644
--- a/actionpack/lib/action_dispatch/http/parameters.rb
+++ b/actionpack/lib/action_dispatch/http/parameters.rb
@@ -4,7 +4,7 @@ module ActionDispatch
PARAMETERS_KEY = 'action_dispatch.request.path_parameters'
DEFAULT_PARSERS = {
- Mime::Type[:JSON] => lambda { |raw_post|
+ Mime[:json] => lambda { |raw_post|
data = ActiveSupport::JSON.decode(raw_post)
data.is_a?(Hash) ? data : {:_json => data}
}
@@ -55,11 +55,11 @@ module ActionDispatch
begin
strategy.call(raw_post)
- rescue => e # JSON or Ruby code block errors
+ rescue # JSON or Ruby code block errors
my_logger = logger || ActiveSupport::Logger.new($stderr)
my_logger.debug "Error occurred while parsing request parameters.\nContents:\n\n#{raw_post}"
- raise ParamsParser::ParseError.new(e.message, e)
+ raise ParamsParser::ParseError
end
end
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index bf20a33d36..ea61ad0c02 100644
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -65,7 +65,7 @@ module ActionDispatch
path_parameters.each do |key, value|
next unless value.respond_to?(:valid_encoding?)
unless value.valid_encoding?
- raise ActionController::BadRequest, "Invalid parameter: #{key} => #{value}"
+ raise ActionController::BadRequest, "Invalid parameter encoding: #{key} => #{value.inspect}"
end
end
end
@@ -338,10 +338,13 @@ module ActionDispatch
# Override Rack's GET method to support indifferent access
def GET
fetch_header("action_dispatch.request.query_parameters") do |k|
- set_header k, Request::Utils.normalize_encode_params(super || {})
+ rack_query_params = super || {}
+ # Check for non UTF-8 parameter values, which would cause errors later
+ Request::Utils.check_param_encoding(rack_query_params)
+ set_header k, Request::Utils.normalize_encode_params(rack_query_params)
end
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
- raise ActionController::BadRequest.new(:query, e)
+ raise ActionController::BadRequest.new("Invalid query parameters: #{e.message}")
end
alias :query_parameters :GET
@@ -357,7 +360,7 @@ module ActionDispatch
self.request_parameters = Request::Utils.normalize_encode_params(super || {})
raise
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
- raise ActionController::BadRequest.new(:request, e)
+ raise ActionController::BadRequest.new("Invalid request parameters: #{e.message}")
end
alias :request_parameters :POST
diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb
index 85d9c3be00..f0127aa276 100644
--- a/actionpack/lib/action_dispatch/http/response.rb
+++ b/actionpack/lib/action_dispatch/http/response.rb
@@ -39,7 +39,7 @@ module ActionDispatch # :nodoc:
end
def []=(k,v)
- if @response.committed?
+ if @response.sending? || @response.sent?
raise ActionDispatch::IllegalStateError, 'header already sent'
end
@@ -78,6 +78,10 @@ module ActionDispatch # :nodoc:
cattr_accessor(:default_headers)
include Rack::Response::Helpers
+ # Aliasing these off because AD::Http::Cache::Response defines them
+ alias :_cache_control :cache_control
+ alias :_cache_control= :cache_control=
+
include ActionDispatch::Http::FilterRedirect
include ActionDispatch::Http::Cache::Response
include MonitorMixin
@@ -145,7 +149,6 @@ module ActionDispatch # :nodoc:
self.body, self.status = body, status
- @blank = false
@cv = new_cond
@committed = false
@sending = false
@@ -156,7 +159,7 @@ module ActionDispatch # :nodoc:
yield self if block_given?
end
- def have_header?(key); headers.key? key; end
+ def has_header?(key); headers.key? key; end
def get_header(key); headers[key]; end
def set_header(key, v); headers[key] = v; end
def delete_header(key); headers.delete key; end
@@ -279,12 +282,12 @@ module ActionDispatch # :nodoc:
@stream.body
end
- EMPTY = " "
+ def write(string)
+ @stream.write string
+ end
# Allows you to manually set or override the response body.
def body=(body)
- @blank = true if body == EMPTY
-
if body.respond_to?(:to_path)
@stream = body
else
@@ -294,6 +297,40 @@ module ActionDispatch # :nodoc:
end
end
+ # Avoid having to pass an open file handle as the response body.
+ # Rack::Sendfile will usually intercept the response and uses
+ # the path directly, so there is no reason to open the file.
+ class FileBody #:nodoc:
+ attr_reader :to_path
+
+ def initialize(path)
+ @to_path = path
+ end
+
+ def body
+ File.binread(to_path)
+ end
+
+ # Stream the file's contents if Rack::Sendfile isn't present.
+ def each
+ File.open(to_path, 'rb') do |file|
+ while chunk = file.read(16384)
+ yield chunk
+ end
+ end
+ end
+ end
+
+ # Send the file stored at +path+ as the response body.
+ def send_file(path)
+ commit!
+ @stream = FileBody.new(path)
+ end
+
+ def reset_body!
+ @stream = build_buffer(self, [])
+ end
+
def body_parts
parts = []
@stream.each { |x| parts << x }
@@ -389,7 +426,7 @@ module ActionDispatch # :nodoc:
return if content_type
ct = parse_content_type
- set_content_type(ct.mime_type || Mime::Type[:HTML].to_s,
+ set_content_type(ct.mime_type || Mime[:html].to_s,
ct.charset || self.class.default_charset)
end
diff --git a/actionpack/lib/action_dispatch/journey/nodes/node.rb b/actionpack/lib/action_dispatch/journey/nodes/node.rb
index d069bf0205..2793c5668d 100644
--- a/actionpack/lib/action_dispatch/journey/nodes/node.rb
+++ b/actionpack/lib/action_dispatch/journey/nodes/node.rb
@@ -42,6 +42,7 @@ module ActionDispatch
def terminal?; false; end
def star?; false; end
def cat?; false; end
+ def group?; false; end
end
class Terminal < Node # :nodoc:
@@ -95,6 +96,7 @@ module ActionDispatch
class Group < Unary # :nodoc:
def type; :GROUP; end
+ def group?; true; end
end
class Star < Unary # :nodoc:
diff --git a/actionpack/lib/action_dispatch/journey/path/pattern.rb b/actionpack/lib/action_dispatch/journey/path/pattern.rb
index e93970046c..5ee8810066 100644
--- a/actionpack/lib/action_dispatch/journey/path/pattern.rb
+++ b/actionpack/lib/action_dispatch/journey/path/pattern.rb
@@ -46,7 +46,7 @@ module ActionDispatch
end
def names
- @names ||= spec.grep(Nodes::Symbol).map(&:name)
+ @names ||= spec.find_all(&:symbol?).map(&:name)
end
def required_names
@@ -54,8 +54,8 @@ module ActionDispatch
end
def optional_names
- @optional_names ||= spec.grep(Nodes::Group).flat_map { |group|
- group.grep(Nodes::Symbol)
+ @optional_names ||= spec.find_all(&:group?).flat_map { |group|
+ group.find_all(&:symbol?)
}.map(&:name).uniq
end
diff --git a/actionpack/lib/action_dispatch/journey/route.rb b/actionpack/lib/action_dispatch/journey/route.rb
index f5c9abf1cc..35c2b1b86e 100644
--- a/actionpack/lib/action_dispatch/journey/route.rb
+++ b/actionpack/lib/action_dispatch/journey/route.rb
@@ -163,7 +163,7 @@ module ActionDispatch
end
def verb
- %r[^#{verbs.join('|')}$]
+ verbs.join('|')
end
private
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index 7ed77352ae..2889acaeb8 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -396,7 +396,9 @@ module ActionDispatch
end
def write(headers)
- headers[HTTP_HEADER] = make_set_cookie_header headers[HTTP_HEADER]
+ if header = make_set_cookie_header(headers[HTTP_HEADER])
+ headers[HTTP_HEADER] = header
+ end
end
mattr_accessor :always_write_cookie
diff --git a/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb b/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb
index 5fd984cd07..3b61824cc9 100644
--- a/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb
+++ b/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb
@@ -37,7 +37,7 @@ module ActionDispatch
@backtrace_cleaner = backtrace_cleaner
@exception = original_exception(exception)
- expand_backtrace if exception.is_a?(SyntaxError) || exception.try(:original_exception).try(:is_a?, SyntaxError)
+ expand_backtrace if exception.is_a?(SyntaxError) || exception.cause.is_a?(SyntaxError)
end
def rescue_template
@@ -106,17 +106,13 @@ module ActionDispatch
end
def original_exception(exception)
- if registered_original_exception?(exception)
- exception.original_exception
+ if @@rescue_responses.has_key?(exception.cause.class.name)
+ exception.cause
else
exception
end
end
- def registered_original_exception?(exception)
- exception.respond_to?(:original_exception) && @@rescue_responses.has_key?(exception.original_exception.class.name)
- end
-
def clean_backtrace(*args)
if backtrace_cleaner
backtrace_cleaner.clean(backtrace, *args)
diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb
index 18af0a583a..c2a4f46e67 100644
--- a/actionpack/lib/action_dispatch/middleware/params_parser.rb
+++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb
@@ -10,11 +10,25 @@ module ActionDispatch
# Raised when raw data from the request cannot be parsed by the parser
# defined for request's content mime type.
class ParseError < StandardError
- attr_reader :original_exception
- def initialize(message, original_exception)
- super(message)
- @original_exception = original_exception
+ def initialize(message = nil, original_exception = nil)
+ if message
+ ActiveSupport::Deprecation.warn("Passing #message is deprecated and has no effect. " \
+ "#{self.class} will automatically capture the message " \
+ "of the original exception.", caller)
+ end
+
+ if original_exception
+ ActiveSupport::Deprecation.warn("Passing #original_exception is deprecated and has no effect. " \
+ "Exceptions will automatically capture the original exception.", caller)
+ end
+
+ super($!.message)
+ end
+
+ def original_exception
+ ActiveSupport::Deprecation.warn("#original_exception is deprecated. Use #cause instead.", caller)
+ cause
end
end
diff --git a/actionpack/lib/action_dispatch/middleware/reloader.rb b/actionpack/lib/action_dispatch/middleware/reloader.rb
index 6c7fba00cb..af9a29eb07 100644
--- a/actionpack/lib/action_dispatch/middleware/reloader.rb
+++ b/actionpack/lib/action_dispatch/middleware/reloader.rb
@@ -1,5 +1,3 @@
-require 'active_support/deprecation/reporting'
-
module ActionDispatch
# ActionDispatch::Reloader provides prepare and cleanup callbacks,
# intended to assist with code reloading during development.
diff --git a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
index 9e50fea3fc..5fb5953811 100644
--- a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
@@ -7,14 +7,22 @@ require 'action_dispatch/request/session'
module ActionDispatch
module Session
class SessionRestoreError < StandardError #:nodoc:
- attr_reader :original_exception
- def initialize(const_error)
- @original_exception = const_error
+ def initialize(const_error = nil)
+ if const_error
+ ActiveSupport::Deprecation.warn("Passing #original_exception is deprecated and has no effect. " \
+ "Exceptions will automatically capture the original exception.", caller)
+ end
super("Session contains objects whose class definition isn't available.\n" +
"Remember to require the classes for all objects kept in the session.\n" +
- "(Original exception: #{const_error.message} [#{const_error.class}])\n")
+ "(Original exception: #{$!.message} [#{$!.class}])\n")
+ set_backtrace $!.backtrace
+ end
+
+ def original_exception
+ ActiveSupport::Deprecation.warn("#original_exception is deprecated. Use #cause instead.", caller)
+ cause
end
end
@@ -59,8 +67,8 @@ module ActionDispatch
begin
# Note that the regexp does not allow $1 to end with a ':'
$1.constantize
- rescue LoadError, NameError => e
- raise ActionDispatch::Session::SessionRestoreError, e, e.backtrace
+ rescue LoadError, NameError
+ raise ActionDispatch::Session::SessionRestoreError
end
retry
else
diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb
index c4344c9609..75f8e05a3f 100644
--- a/actionpack/lib/action_dispatch/middleware/static.rb
+++ b/actionpack/lib/action_dispatch/middleware/static.rb
@@ -3,8 +3,8 @@ require 'active_support/core_ext/uri'
module ActionDispatch
# This middleware returns a file's contents from disk in the body response.
- # When initialized, it can accept an optional 'Cache-Control' header, which
- # will be set when a response containing a file's contents is delivered.
+ # When initialized, it can accept optional HTTP headers, which will be set
+ # when a response containing a file's contents is delivered.
#
# This middleware will render the file specified in `env["PATH_INFO"]`
# where the base path is in the +root+ directory. For example, if the +root+
@@ -13,12 +13,11 @@ module ActionDispatch
# located at `public/assets/application.js` if the file exists. If the file
# does not exist, a 404 "File not Found" response will be returned.
class FileHandler
- def initialize(root, cache_control, index: 'index')
+ def initialize(root, index: 'index', headers: {})
@root = root.chomp('/')
@compiled_root = /^#{Regexp.escape(root)}/
- headers = cache_control && { 'Cache-Control' => cache_control }
- @file_server = ::Rack::File.new(@root, headers)
- @index = index
+ @file_server = ::Rack::File.new(@root, headers)
+ @index = index
end
# Takes a path to a file. If the file is found, has valid encoding, and has
@@ -108,9 +107,16 @@ module ActionDispatch
# produce a directory traversal using this middleware. Only 'GET' and 'HEAD'
# requests will result in a file being returned.
class Static
- def initialize(app, path, cache_control = nil, index: 'index')
+ def initialize(app, path, deprecated_cache_control = :not_set, index: 'index', headers: {})
+ if deprecated_cache_control != :not_set
+ ActiveSupport::Deprecation.warn("The `cache_control` argument is deprecated," \
+ "replaced by `headers: { 'Cache-Control' => #{deprecated_cache_control} }`, " \
+ " and will be removed in Rails 5.1.")
+ headers['Cache-Control'.freeze] = deprecated_cache_control
+ end
+
@app = app
- @file_handler = FileHandler.new(path, cache_control, index: index)
+ @file_handler = FileHandler.new(path, index: index, headers: headers)
end
def call(env)
diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb
index c1e8b6cae3..5060da9369 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb
@@ -1,6 +1,6 @@
<header>
<h1>
- <%= @exception.original_exception.class.to_s %> in
+ <%= @exception.cause.class.to_s %> in
<%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
</h1>
</header>
diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb
index 77bcd26726..78d52acd96 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb
@@ -1,4 +1,4 @@
-<%= @exception.original_exception.class.to_s %> in <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
+<%= @exception.cause.class.to_s %> in <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
Showing <%= @exception.file_name %> where line #<%= @exception.line_number %> raised:
<%= @exception.message %>
diff --git a/actionpack/lib/action_dispatch/request/utils.rb b/actionpack/lib/action_dispatch/request/utils.rb
index a8151a8224..bb3df3c311 100644
--- a/actionpack/lib/action_dispatch/request/utils.rb
+++ b/actionpack/lib/action_dispatch/request/utils.rb
@@ -13,6 +13,21 @@ module ActionDispatch
end
end
+ def self.check_param_encoding(params)
+ case params
+ when Array
+ params.each { |element| check_param_encoding(element) }
+ when Hash
+ params.each_value { |value| check_param_encoding(value) }
+ when String
+ unless params.valid_encoding?
+ # Raise Rack::Utils::InvalidParameterError for consistency with Rack.
+ # ActionDispatch::Request#GET will re-raise as a BadRequest error.
+ raise Rack::Utils::InvalidParameterError, "Non UTF-8 value: #{params}"
+ end
+ end
+ end
+
class ParamEncoder # :nodoc:
# Convert nested Hash to HashWithIndifferentAccess.
#
diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb
index f3c6be864f..59c3f9248f 100644
--- a/actionpack/lib/action_dispatch/routing.rb
+++ b/actionpack/lib/action_dispatch/routing.rb
@@ -53,7 +53,7 @@ module ActionDispatch
# resources :posts, :comments
# end
#
- # Alternately, you can add prefixes to your path without using a separate
+ # Alternatively, you can add prefixes to your path without using a separate
# directory by using +scope+. +scope+ takes additional options which
# apply to all enclosed routes.
#
diff --git a/actionpack/lib/action_dispatch/routing/inspector.rb b/actionpack/lib/action_dispatch/routing/inspector.rb
index 48c10a7d4c..f3a5268d2e 100644
--- a/actionpack/lib/action_dispatch/routing/inspector.rb
+++ b/actionpack/lib/action_dispatch/routing/inspector.rb
@@ -16,10 +16,6 @@ module ActionDispatch
app.app
end
- def verb
- super.source.gsub(/[$^]/, '')
- end
-
def path
super.spec.to_s
end
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 87b826f7d0..7c0404ca62 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -3,7 +3,6 @@ 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/regexp'
-require 'active_support/deprecation'
require 'action_dispatch/routing/redirection'
require 'action_dispatch/routing/endpoint'
@@ -402,7 +401,8 @@ module ActionDispatch
# because this means it will be matched first. As this is the most popular route
# of most Rails applications, this is beneficial.
def root(options = {})
- match '/', { :as => :root, :via => :get }.merge!(options)
+ name = has_named_route?(:root) ? nil : :root
+ match '/', { as: name, via: :get }.merge!(options)
end
# Matches a url pattern to one or more routes.
@@ -482,7 +482,7 @@ module ActionDispatch
# resources :user, param: :name
#
# You can override <tt>ActiveRecord::Base#to_param</tt> of a related
- # model to construct an URL:
+ # model to construct a URL:
#
# class User < ActiveRecord::Base
# def to_param
@@ -665,6 +665,7 @@ module ActionDispatch
super(options)
else
prefix_options = options.slice(*_route.segment_keys)
+ prefix_options[:relative_url_root] = ''.freeze
# we must actually delete prefix segment keys to avoid passing them to next url_for
_route.segment_keys.each { |k| options.delete(k) }
_routes.url_helpers.send("#{name}_path", prefix_options)
@@ -1866,7 +1867,7 @@ to this:
# and return nil in case it isn't. Otherwise, we pass the invalid name
# forward so the underlying router engine treats it and raises an exception.
if as.nil?
- candidate unless candidate !~ /\A[_a-z]/i || @set.named_routes.key?(candidate)
+ candidate unless candidate !~ /\A[_a-z]/i || has_named_route?(candidate)
else
candidate
end
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index e4b8d5993e..5f54ea130b 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -1,5 +1,4 @@
require 'action_dispatch/journey'
-require 'forwardable'
require 'active_support/concern'
require 'active_support/core_ext/object/to_query'
require 'active_support/core_ext/hash/slice'
@@ -656,14 +655,18 @@ module ActionDispatch
RESERVED_OPTIONS = [:host, :protocol, :port, :subdomain, :domain, :tld_length,
:trailing_slash, :anchor, :params, :only_path, :script_name,
- :original_script_name]
+ :original_script_name, :relative_url_root]
def optimize_routes_generation?
default_url_options.empty?
end
def find_script_name(options)
- options.delete(:script_name) || relative_url_root || ''
+ options.delete(:script_name) || find_relative_url_root(options) || ''
+ end
+
+ def find_relative_url_root(options)
+ options.delete(:relative_url_root) || relative_url_root
end
def path_for(options, route_name = nil)
diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb
index 883cd9c2c3..b6c031dcf4 100644
--- a/actionpack/lib/action_dispatch/routing/url_for.rb
+++ b/actionpack/lib/action_dispatch/routing/url_for.rb
@@ -1,7 +1,7 @@
module ActionDispatch
module Routing
# In <tt>config/routes.rb</tt> you define URL-to-controller mappings, but the reverse
- # is also possible: an URL can be generated from one of your routing definitions.
+ # is also possible: a URL can be generated from one of your routing definitions.
# URL generation functionality is centralized in this module.
#
# See ActionDispatch::Routing for general information about routing and routes.rb.
diff --git a/actionpack/lib/action_dispatch/testing/assertions.rb b/actionpack/lib/action_dispatch/testing/assertions.rb
index 81fa10a613..fae266273e 100644
--- a/actionpack/lib/action_dispatch/testing/assertions.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions.rb
@@ -12,7 +12,7 @@ module ActionDispatch
include Rails::Dom::Testing::Assertions
def html_document
- @html_document ||= if @response.content_type === Mime::Type[:XML]
+ @html_document ||= if @response.content_type.to_s =~ /xml\z/
Nokogiri::XML::Document.parse(@response.body)
else
Nokogiri::HTML::Document.parse(@response.body)
diff --git a/actionpack/lib/action_dispatch/testing/assertions/response.rb b/actionpack/lib/action_dispatch/testing/assertions/response.rb
index b6e21b0d28..eab20b075d 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/response.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/response.rb
@@ -21,10 +21,10 @@ module ActionDispatch
# or its symbolic equivalent <tt>assert_response(:not_implemented)</tt>.
# See Rack::Utils::SYMBOL_TO_STATUS_CODE for a full list.
#
- # # assert that the response was a redirection
+ # # Asserts that the response was a redirection
# assert_response :redirect
#
- # # assert that the response code was status code 401 (unauthorized)
+ # # Asserts that the response code was status code 401 (unauthorized)
# assert_response 401
def assert_response(type, message = nil)
if Symbol === type
@@ -42,20 +42,20 @@ module ActionDispatch
end
end
- # Assert that the redirection options passed in match those of the redirect called in the latest action.
+ # Asserts that the redirection options passed in match those of the redirect called in the latest action.
# This match can be partial, such that <tt>assert_redirected_to(controller: "weblog")</tt> will also
# match the redirection of <tt>redirect_to(controller: "weblog", action: "show")</tt> and so on.
#
- # # assert that the redirection was to the "index" action on the WeblogController
+ # # Asserts that the redirection was to the "index" action on the WeblogController
# assert_redirected_to controller: "weblog", action: "index"
#
- # # assert that the redirection was to the named route login_url
+ # # Asserts that the redirection was to the named route login_url
# assert_redirected_to login_url
#
- # # assert that the redirection was to the url for @customer
+ # # Asserts that the redirection was to the url for @customer
# assert_redirected_to @customer
#
- # # asserts that the redirection matches the regular expression
+ # # Asserts that the redirection matches the regular expression
# assert_redirected_to %r(\Ahttp://example.org)
def assert_redirected_to(options = {}, message=nil)
assert_response(:redirect, message)
diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
index 54e24ed6bf..78ef860548 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
@@ -14,14 +14,14 @@ module ActionDispatch
# requiring a specific HTTP method. The hash should contain a :path with the incoming request path
# and a :method containing the required HTTP verb.
#
- # # assert that POSTing to /items will call the create action on ItemsController
+ # # Asserts that POSTing to /items will call the create action on ItemsController
# assert_recognizes({controller: 'items', action: 'create'}, {path: 'items', method: :post})
#
# You can also pass in +extras+ with a hash containing URL parameters that would normally be in the query string. This can be used
- # to assert that values in the query string string will end up in the params hash correctly. To test query strings you must use the
+ # to assert that values in the query string will end up in the params hash correctly. To test query strings you must use the
# extras argument, appending the query string on the path directly will not work. For example:
#
- # # assert that a path of '/items/list/1?view=print' returns the correct options
+ # # Asserts that a path of '/items/list/1?view=print' returns the correct options
# assert_recognizes({controller: 'items', action: 'list', id: '1', view: 'print'}, 'items/list/1', { view: "print" })
#
# The +message+ parameter allows you to pass in an error message that is displayed upon failure.
@@ -104,13 +104,13 @@ module ActionDispatch
# The +extras+ hash allows you to specify options that would normally be provided as a query string to the action. The
# +message+ parameter allows you to specify a custom error message to display upon failure.
#
- # # Assert a basic route: a controller with the default action (index)
+ # # Asserts a basic route: a controller with the default action (index)
# assert_routing '/home', controller: 'home', action: 'index'
#
# # Test a route generated with a specific controller, action, and parameter (id)
# assert_routing '/entries/show/23', controller: 'entries', action: 'show', id: 23
#
- # # Assert a basic route (controller + default action), with an error message if it fails
+ # # Asserts a basic route (controller + default action), with an error message if it fails
# assert_routing '/store', { controller: 'store', action: 'index' }, {}, {}, 'Route for store index not generated properly'
#
# # Tests a route, providing a defaults hash
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index 753cd2073b..790f9ea5d2 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -131,35 +131,35 @@ module ActionDispatch
# Performs a GET request, following any subsequent redirect.
# See +request_via_redirect+ for more information.
def get_via_redirect(path, *args)
- ActiveSupport::Deprecation.warn('`get_via_redirect` is deprecated and will be removed in the next version of Rails. Please use follow_redirect! manually after the request call for the same behavior.')
+ ActiveSupport::Deprecation.warn('`get_via_redirect` is deprecated and will be removed in Rails 5.1. Please use follow_redirect! manually after the request call for the same behavior.')
request_via_redirect(:get, path, *args)
end
# Performs a POST request, following any subsequent redirect.
# See +request_via_redirect+ for more information.
def post_via_redirect(path, *args)
- ActiveSupport::Deprecation.warn('`post_via_redirect` is deprecated and will be removed in the next version of Rails. Please use follow_redirect! manually after the request call for the same behavior.')
+ ActiveSupport::Deprecation.warn('`post_via_redirect` is deprecated and will be removed in Rails 5.1. Please use follow_redirect! manually after the request call for the same behavior.')
request_via_redirect(:post, path, *args)
end
# Performs a PATCH request, following any subsequent redirect.
# See +request_via_redirect+ for more information.
def patch_via_redirect(path, *args)
- ActiveSupport::Deprecation.warn('`patch_via_redirect` is deprecated and will be removed in the next version of Rails. Please use follow_redirect! manually after the request call for the same behavior.')
+ ActiveSupport::Deprecation.warn('`patch_via_redirect` is deprecated and will be removed in Rails 5.1. Please use follow_redirect! manually after the request call for the same behavior.')
request_via_redirect(:patch, path, *args)
end
# Performs a PUT request, following any subsequent redirect.
# See +request_via_redirect+ for more information.
def put_via_redirect(path, *args)
- ActiveSupport::Deprecation.warn('`put_via_redirect` is deprecated and will be removed in the next version of Rails. Please use follow_redirect! manually after the request call for the same behavior.')
+ ActiveSupport::Deprecation.warn('`put_via_redirect` is deprecated and will be removed in Rails 5.1. Please use follow_redirect! manually after the request call for the same behavior.')
request_via_redirect(:put, path, *args)
end
# Performs a DELETE request, following any subsequent redirect.
# See +request_via_redirect+ for more information.
def delete_via_redirect(path, *args)
- ActiveSupport::Deprecation.warn('`delete_via_redirect` is deprecated and will be removed in the next version of Rails. Please use follow_redirect! manually after the request call for the same behavior.')
+ ActiveSupport::Deprecation.warn('`delete_via_redirect` is deprecated and will be removed in Rails 5.1. Please use follow_redirect! manually after the request call for the same behavior.')
request_via_redirect(:delete, path, *args)
end
end
@@ -354,7 +354,7 @@ module ActionDispatch
if xhr
headers ||= {}
headers['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
- headers['HTTP_ACCEPT'] ||= [Mime::Type[:JS], Mime::Type[:HTML], Mime::Type[:XML], 'text/xml', Mime::Type[:ALL]].join(', ')
+ headers['HTTP_ACCEPT'] ||= [Mime[:js], Mime[:html], Mime[:xml], 'text/xml', '*/*'].join(', ')
end
# this modifies the passed request_env directly