diff options
Diffstat (limited to 'actionpack/lib/action_dispatch')
24 files changed, 95 insertions, 95 deletions
diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb index 6b718e3682..1583a8f87f 100644 --- a/actionpack/lib/action_dispatch/http/mime_type.rb +++ b/actionpack/lib/action_dispatch/http/mime_type.rb @@ -1,7 +1,6 @@ # -*- frozen-string-literal: true -*- require "singleton" -require "active_support/core_ext/module/attribute_accessors" require "active_support/core_ext/string/starts_ends_with" module Mime @@ -298,7 +297,7 @@ module Mime end def respond_to_missing?(method, include_private = false) - method.to_s.ends_with? "?" + (method.to_s.ends_with? "?") || super end end diff --git a/actionpack/lib/action_dispatch/http/parameters.rb b/actionpack/lib/action_dispatch/http/parameters.rb index ad4aadacf5..8f21eca440 100644 --- a/actionpack/lib/action_dispatch/http/parameters.rb +++ b/actionpack/lib/action_dispatch/http/parameters.rb @@ -22,6 +22,7 @@ module ActionDispatch included do class << self + # Returns the parameter parsers. attr_reader :parameter_parsers end @@ -29,7 +30,16 @@ module ActionDispatch end module ClassMethods - def parameter_parsers=(parsers) # :nodoc: + # Configure the parameter parser for a given mime type. + # + # It accepts a hash where the key is the symbol of the mime type + # and the value is a proc. + # + # original_parsers = ActionDispatch::Request.parameter_parsers + # xml_parser = -> (raw_post) { Hash.from_xml(raw_post) || {} } + # new_parsers = original_parsers.merge(xml: xml_parser) + # ActionDispatch::Request.parameter_parsers = new_parsers + def parameter_parsers=(parsers) @parameter_parsers = parsers.transform_keys { |key| key.respond_to?(:symbol) ? key.symbol : key } end end diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index a886358399..19fa42ce12 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -85,6 +85,9 @@ module ActionDispatch end end + # Returns true if the request has a header matching the given key parameter. + # + # request.key? :ip_spoofing_check # => true def key?(key) has_header? key end diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 516a2af69a..dc159596c4 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -425,7 +425,7 @@ module ActionDispatch # :nodoc: def set_content_type(content_type, charset) type = (content_type || "").dup - type << "; charset=#{charset}" if charset + type << "; charset=#{charset.to_s.downcase}" if charset set_header CONTENT_TYPE, type end diff --git a/actionpack/lib/action_dispatch/journey/formatter.rb b/actionpack/lib/action_dispatch/journey/formatter.rb index 20ff4441a0..f3b8e82d32 100644 --- a/actionpack/lib/action_dispatch/journey/formatter.rb +++ b/actionpack/lib/action_dispatch/journey/formatter.rb @@ -36,7 +36,7 @@ module ActionDispatch route.parts.reverse_each do |key| break if defaults[key].nil? && parameterized_parts[key].present? - break if parameterized_parts[key].to_s != defaults[key].to_s + next if parameterized_parts[key].to_s != defaults[key].to_s break if required_parts.include?(key) parameterized_parts.delete(key) @@ -92,7 +92,11 @@ module ActionDispatch else routes = non_recursive(cache, options) - hash = routes.group_by { |_, r| r.score(options) } + supplied_keys = options.each_with_object({}) do |(k, v), h| + h[k.to_s] = true if v + end + + hash = routes.group_by { |_, r| r.score(supplied_keys) } hash.keys.sort.reverse_each do |score| break if score < 0 diff --git a/actionpack/lib/action_dispatch/journey/parser.rb b/actionpack/lib/action_dispatch/journey/parser.rb index db42b64c4b..e002755bcf 100644 --- a/actionpack/lib/action_dispatch/journey/parser.rb +++ b/actionpack/lib/action_dispatch/journey/parser.rb @@ -1,7 +1,7 @@ # # DO NOT MODIFY!!!! # This file is automatically generated by Racc 1.4.14 -# from Racc grammer file "". +# from Racc grammar file "". # require 'racc/parser.rb' diff --git a/actionpack/lib/action_dispatch/journey/path/pattern.rb b/actionpack/lib/action_dispatch/journey/path/pattern.rb index 0902b9233e..cf0108ec32 100644 --- a/actionpack/lib/action_dispatch/journey/path/pattern.rb +++ b/actionpack/lib/action_dispatch/journey/path/pattern.rb @@ -31,6 +31,13 @@ module ActionDispatch Visitors::FormatBuilder.new.accept(spec) end + def eager_load! + required_names + offsets + to_regexp + nil + end + def ast @spec.find_all(&:symbol?).each do |node| re = @requirements[node.to_sym] diff --git a/actionpack/lib/action_dispatch/journey/route.rb b/actionpack/lib/action_dispatch/journey/route.rb index 0cc8d83ac8..927fd369c4 100644 --- a/actionpack/lib/action_dispatch/journey/route.rb +++ b/actionpack/lib/action_dispatch/journey/route.rb @@ -73,6 +73,14 @@ module ActionDispatch @internal = internal end + def eager_load! + path.eager_load! + ast + parts + required_defaults + nil + end + def ast @decorated_ast ||= begin decorated_ast = path.ast @@ -96,13 +104,18 @@ module ActionDispatch required_parts + required_defaults.keys end - def score(constraints) + def score(supplied_keys) required_keys = path.required_names - supplied_keys = constraints.map { |k, v| v && k.to_s }.compact - return -1 unless (required_keys - supplied_keys).empty? + required_keys.each do |k| + return -1 unless supplied_keys.include?(k) + end + + score = 0 + path.names.each do |k| + score += 1 if supplied_keys.include?(k) + end - score = (supplied_keys & path.names).length score + (required_defaults.length * 2) end diff --git a/actionpack/lib/action_dispatch/journey/router.rb b/actionpack/lib/action_dispatch/journey/router.rb index 084ae9325e..d55e1399e4 100644 --- a/actionpack/lib/action_dispatch/journey/router.rb +++ b/actionpack/lib/action_dispatch/journey/router.rb @@ -22,6 +22,13 @@ module ActionDispatch @routes = routes end + def eager_load! + # Eagerly trigger the simulator's initialization so + # it doesn't happen during a request cycle. + simulator + nil + end + def serve(req) find_routes(req).each do |match, parameters, route| set_params = req.path_parameters diff --git a/actionpack/lib/action_dispatch/journey/visitors.rb b/actionpack/lib/action_dispatch/journey/visitors.rb index cda859cba4..1c50192867 100644 --- a/actionpack/lib/action_dispatch/journey/visitors.rb +++ b/actionpack/lib/action_dispatch/journey/visitors.rb @@ -5,7 +5,7 @@ module ActionDispatch ESCAPE_PATH = ->(value) { Router::Utils.escape_path(value) } ESCAPE_SEGMENT = ->(value) { Router::Utils.escape_segment(value) } - class Parameter < Struct.new(:name, :escaper) + Parameter = Struct.new(:name, :escaper) do def escape(value); escaper.call value; end end diff --git a/actionpack/lib/action_dispatch/middleware/callbacks.rb b/actionpack/lib/action_dispatch/middleware/callbacks.rb index fef246532b..ff129cf96a 100644 --- a/actionpack/lib/action_dispatch/middleware/callbacks.rb +++ b/actionpack/lib/action_dispatch/middleware/callbacks.rb @@ -1,4 +1,3 @@ - module ActionDispatch # Provides callbacks to be executed before and after dispatching the request. class Callbacks @@ -7,17 +6,6 @@ module ActionDispatch define_callbacks :call class << self - def to_prepare(*args, &block) - ActiveSupport::Reloader.to_prepare(*args, &block) - end - - def to_cleanup(*args, &block) - ActiveSupport::Reloader.to_complete(*args, &block) - end - - deprecate to_prepare: "use ActiveSupport::Reloader.to_prepare instead", - to_cleanup: "use ActiveSupport::Reloader.to_complete instead" - def before(*args, &block) set_callback(:call, :before, *args, &block) end diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index 956c53e813..c61cb3fd68 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -572,7 +572,7 @@ module ActionDispatch super if ActiveSupport::LegacyKeyGenerator === key_generator - raise "You didn't set secrets.secret_key_base, which is required for this cookie jar. " + + raise "You didn't set secrets.secret_key_base, which is required for this cookie jar. " \ "Read the upgrade documentation to learn more about this new config option." end diff --git a/actionpack/lib/action_dispatch/middleware/reloader.rb b/actionpack/lib/action_dispatch/middleware/reloader.rb index 90c64037aa..6d64b1424b 100644 --- a/actionpack/lib/action_dispatch/middleware/reloader.rb +++ b/actionpack/lib/action_dispatch/middleware/reloader.rb @@ -1,54 +1,10 @@ module ActionDispatch - # ActionDispatch::Reloader provides prepare and cleanup callbacks, - # intended to assist with code reloading during development. - # - # Prepare callbacks are run before each request, and cleanup callbacks - # after each request. In this respect they are analogs of ActionDispatch::Callback's - # before and after callbacks. However, cleanup callbacks are not called until the - # request is fully complete -- that is, after #close has been called on - # the response body. This is important for streaming responses such as the - # following: - # - # self.response_body = -> (response, output) do - # # code here which refers to application models - # end - # - # Cleanup callbacks will not be called until after the response_body lambda - # is evaluated, ensuring that it can refer to application models and other - # classes before they are unloaded. + # ActionDispatch::Reloader wraps the request with callbacks provided by ActiveSupport::Reloader + # callbacks, intended to assist with code reloading during development. # # By default, ActionDispatch::Reloader is included in the middleware stack # only in the development environment; specifically, when +config.cache_classes+ - # is false. Callbacks may be registered even when it is not included in the - # middleware stack, but are executed only when <tt>ActionDispatch::Reloader.prepare!</tt> - # or <tt>ActionDispatch::Reloader.cleanup!</tt> are called manually. - # + # is false. class Reloader < Executor - def self.to_prepare(*args, &block) - ActiveSupport::Reloader.to_prepare(*args, &block) - end - - def self.to_cleanup(*args, &block) - ActiveSupport::Reloader.to_complete(*args, &block) - end - - def self.prepare! - default_reloader.prepare! - end - - def self.cleanup! - default_reloader.reload! - end - - class << self - attr_accessor :default_reloader # :nodoc: - - deprecate to_prepare: "use ActiveSupport::Reloader.to_prepare instead", - to_cleanup: "use ActiveSupport::Reloader.to_complete instead", - prepare!: "use Rails.application.reloader.prepare! instead", - cleanup!: "use Rails.application.reloader.reload! instead of cleanup + prepare" - end - - self.default_reloader = ActiveSupport::Reloader end end diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb index 9f1ae80b97..8bae5bfeff 100644 --- a/actionpack/lib/action_dispatch/middleware/remote_ip.rb +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -131,8 +131,8 @@ module ActionDispatch should_check_ip = @check_ip && client_ips.last && forwarded_ips.last if should_check_ip && !forwarded_ips.include?(client_ips.last) # We don't know which came from the proxy, and which from the user - raise IpSpoofAttackError, "IP spoofing attack?! " + - "HTTP_CLIENT_IP=#{@req.client_ip.inspect} " + + raise IpSpoofAttackError, "IP spoofing attack?! " \ + "HTTP_CLIENT_IP=#{@req.client_ip.inspect} " \ "HTTP_X_FORWARDED_FOR=#{@req.x_forwarded_for.inspect}" end diff --git a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb index 97c937b0b1..d9f018c8ac 100644 --- a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb @@ -8,8 +8,8 @@ module ActionDispatch module Session class SessionRestoreError < StandardError #:nodoc: def initialize - super("Session contains objects whose class definition isn't available.\n" + - "Remember to require the classes for all objects kept in the session.\n" + + 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: #{$!.message} [#{$!.class}])\n") set_backtrace $!.backtrace end diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb index 5c71f0fc48..5d10129d21 100644 --- a/actionpack/lib/action_dispatch/middleware/static.rb +++ b/actionpack/lib/action_dispatch/middleware/static.rb @@ -33,7 +33,7 @@ module ActionDispatch paths = [path, "#{path}#{ext}", "#{path}/#{@index}#{ext}"] if match = paths.detect { |p| - path = File.join(@root, p.force_encoding("UTF-8".freeze)) + path = File.join(@root, p.force_encoding(Encoding::UTF_8)) begin File.file?(path) && File.readable?(path) rescue SystemCallError diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb index 48cc91bbfa..16a18a7f25 100644 --- a/actionpack/lib/action_dispatch/railtie.rb +++ b/actionpack/lib/action_dispatch/railtie.rb @@ -39,8 +39,6 @@ module ActionDispatch config.action_dispatch.always_write_cookie = Rails.env.development? if config.action_dispatch.always_write_cookie.nil? ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie - ActionDispatch::Reloader.default_reloader = app.reloader - ActionDispatch.test_app = app end end diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb index fe8bf6a35c..c554ce98bc 100644 --- a/actionpack/lib/action_dispatch/routing.rb +++ b/actionpack/lib/action_dispatch/routing.rb @@ -1,4 +1,4 @@ -require 'active_support/core_ext/string/filters' +require "active_support/core_ext/string/filters" 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 089aa9f78e..8d9f70e3c6 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1,6 +1,7 @@ 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 "action_dispatch/routing/redirection" require "action_dispatch/routing/endpoint" @@ -238,7 +239,7 @@ module ActionDispatch options[:controller] ||= /.+?/ end - if to.respond_to? :call + if to.respond_to?(:action) || to.respond_to?(:call) options else to_endpoint = split_to to @@ -290,16 +291,14 @@ module ActionDispatch end def app(blocks) - if to.is_a?(Class) && to < ActionController::Metal + if to.respond_to?(:action) Routing::RouteSet::StaticDispatcher.new to + elsif to.respond_to?(:call) + Constraints.new(to, blocks, Constraints::CALL) + elsif blocks.any? + Constraints.new(dispatcher(defaults.key?(:controller)), blocks, Constraints::SERVE) else - if to.respond_to?(:call) - Constraints.new(to, blocks, Constraints::CALL) - elsif blocks.any? - Constraints.new(dispatcher(defaults.key?(:controller)), blocks, Constraints::SERVE) - else - dispatcher(defaults.key?(:controller)) - end + dispatcher(defaults.key?(:controller)) end end diff --git a/actionpack/lib/action_dispatch/routing/redirection.rb b/actionpack/lib/action_dispatch/routing/redirection.rb index 4e2318a45e..dabc045007 100644 --- a/actionpack/lib/action_dispatch/routing/redirection.rb +++ b/actionpack/lib/action_dispatch/routing/redirection.rb @@ -137,6 +137,9 @@ module ActionDispatch # # get "/stories" => redirect("/posts") # + # This will redirect the user, while ignoring certain parts of the request, including query string, etc. + # `/stories`, `/stories?foo=bar`, etc all redirect to `/posts`. + # # You can also use interpolation in the supplied redirect argument: # # get 'docs/:article', to: redirect('/wiki/%{article}') @@ -165,6 +168,11 @@ module ActionDispatch # # get 'stores/:name', to: redirect(subdomain: 'stores', path: '/%{name}') # get 'stores/:name(*all)', to: redirect(subdomain: 'stores', path: '/%{name}%{all}') + # get '/stories', to: redirect(path: '/posts') + # + # This will redirect the user, while changing only the specified parts of the request, + # for example the `path` option in the last example. + # `/stories`, `/stories?foo=bar`, redirect to `/posts` and `/posts?foo=bar` respectively. # # Finally, an object which responds to call can be supplied to redirect, allowing you to reuse # common redirect routes. The call method must accept two arguments, params and request, and return diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 5853adb110..5b873aeab7 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -349,6 +349,12 @@ module ActionDispatch @formatter = Journey::Formatter.new self end + def eager_load! + router.eager_load! + routes.each(&:eager_load!) + nil + end + def relative_url_root @config.relative_url_root end diff --git a/actionpack/lib/action_dispatch/testing/assertions.rb b/actionpack/lib/action_dispatch/testing/assertions.rb index b362931ef7..4ea18d671d 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.to_s =~ /xml\z/ + @html_document ||= if @response.content_type.to_s.end_with?("xml") Nokogiri::XML::Document.parse(@response.body) else Nokogiri::HTML::Document.parse(@response.body) diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb index 454dcb9307..37c1ca02b6 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb @@ -152,8 +152,11 @@ module ActionDispatch _routes = @routes @controller.singleton_class.include(_routes.url_helpers) - @controller.view_context_class = Class.new(@controller.view_context_class) do - include _routes.url_helpers + + if @controller.respond_to? :view_context_class + @controller.view_context_class = Class.new(@controller.view_context_class) do + include _routes.url_helpers + end end end yield @routes diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 021ffec862..5fa0b727ab 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -2,7 +2,6 @@ require "stringio" require "uri" require "active_support/core_ext/kernel/singleton_class" require "active_support/core_ext/object/try" -require "active_support/core_ext/string/strip" require "rack/test" require "minitest" @@ -145,8 +144,8 @@ module ActionDispatch self.host = DEFAULT_HOST self.remote_addr = "127.0.0.1" - self.accept = "text/xml,application/xml,application/xhtml+xml," + - "text/html;q=0.9,text/plain;q=0.8,image/png," + + self.accept = "text/xml,application/xml,application/xhtml+xml," \ + "text/html;q=0.9,text/plain;q=0.8,image/png," \ "*/*;q=0.5" unless defined? @named_routes_configured |