aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch')
-rw-r--r--actionpack/lib/action_dispatch/http/cache.rb19
-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.rb2
-rw-r--r--actionpack/lib/action_dispatch/http/request.rb11
-rw-r--r--actionpack/lib/action_dispatch/http/response.rb49
-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/reloader.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/static.rb22
-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/integration.rb12
20 files changed, 157 insertions, 107 deletions
diff --git a/actionpack/lib/action_dispatch/http/cache.rb b/actionpack/lib/action_dispatch/http/cache.rb
index 6b25ee9a70..30ade14c26 100644
--- a/actionpack/lib/action_dispatch/http/cache.rb
+++ b/actionpack/lib/action_dispatch/http/cache.rb
@@ -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/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..248ecfd676 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}
}
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index bf20a33d36..35e3ac304f 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}", e)
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}", e)
end
alias :request_parameters :POST
diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb
index a27ff67114..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
@@ -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/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/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/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/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