diff options
Diffstat (limited to 'actionpack/lib/action_dispatch')
-rw-r--r-- | actionpack/lib/action_dispatch/http/cache.rb | 49 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/http/filter_redirect.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/http/parameters.rb | 11 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/http/request.rb | 35 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/http/response.rb | 32 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/http/url.rb | 6 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/cookies.rb | 4 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/params_parser.rb | 6 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/stack.rb | 4 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/mapper.rb | 16 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/route_set.rb | 51 |
11 files changed, 112 insertions, 104 deletions
diff --git a/actionpack/lib/action_dispatch/http/cache.rb b/actionpack/lib/action_dispatch/http/cache.rb index cc1cb3f0f0..08ebd2e8b2 100644 --- a/actionpack/lib/action_dispatch/http/cache.rb +++ b/actionpack/lib/action_dispatch/http/cache.rb @@ -8,13 +8,13 @@ module ActionDispatch HTTP_IF_NONE_MATCH = 'HTTP_IF_NONE_MATCH'.freeze def if_modified_since - if since = env[HTTP_IF_MODIFIED_SINCE] + if since = get_header(HTTP_IF_MODIFIED_SINCE) Time.rfc2822(since) rescue nil end end def if_none_match - env[HTTP_IF_NONE_MATCH] + get_header HTTP_IF_NONE_MATCH end def if_none_match_etags @@ -51,41 +51,45 @@ module ActionDispatch end module Response - attr_reader :cache_control, :etag - alias :etag? :etag + attr_reader :cache_control def last_modified - if last = headers[LAST_MODIFIED] + if last = get_header(LAST_MODIFIED) Time.httpdate(last) end end def last_modified? - headers.include?(LAST_MODIFIED) + have_header? LAST_MODIFIED end def last_modified=(utc_time) - headers[LAST_MODIFIED] = utc_time.httpdate + set_header LAST_MODIFIED, utc_time.httpdate end def date - if date_header = headers[DATE] + if date_header = get_header(DATE) Time.httpdate(date_header) end end def date? - headers.include?(DATE) + have_header? DATE end def date=(utc_time) - headers[DATE] = utc_time.httpdate + set_header DATE, utc_time.httpdate end def etag=(etag) key = ActiveSupport::Cache.expand_cache_key(etag) - @etag = self[ETAG] = %("#{Digest::MD5.hexdigest(key)}") + set_header ETAG, %("#{Digest::MD5.hexdigest(key)}") + end + + def etag + get_header ETAG end + alias :etag? :etag private @@ -96,7 +100,7 @@ module ActionDispatch SPECIAL_KEYS = Set.new(%w[extras no-cache max-age public must-revalidate]) def cache_control_segments - if cache_control = self[CACHE_CONTROL] + if cache_control = get_header(CACHE_CONTROL) cache_control.delete(' ').split(',') else [] @@ -123,12 +127,11 @@ module ActionDispatch def prepare_cache_control! @cache_control = cache_control_headers - @etag = self[ETAG] end def handle_conditional_get! if etag? || last_modified? || !@cache_control.empty? - set_conditional_cache_control! + set_conditional_cache_control!(@cache_control) end end @@ -138,24 +141,24 @@ module ActionDispatch PRIVATE = "private".freeze MUST_REVALIDATE = "must-revalidate".freeze - def set_conditional_cache_control! + def set_conditional_cache_control!(cache_control) control = {} cc_headers = cache_control_headers if extras = cc_headers.delete(:extras) - @cache_control[:extras] ||= [] - @cache_control[:extras] += extras - @cache_control[:extras].uniq! + cache_control[:extras] ||= [] + cache_control[:extras] += extras + cache_control[:extras].uniq! end control.merge! cc_headers - control.merge! @cache_control + control.merge! cache_control if control.empty? - self[CACHE_CONTROL] = DEFAULT_CACHE_CONTROL + set_header CACHE_CONTROL, DEFAULT_CACHE_CONTROL elsif control[:no_cache] - self[CACHE_CONTROL] = NO_CACHE + set_header CACHE_CONTROL, NO_CACHE if control[:extras] - self[CACHE_CONTROL] += ", #{control[:extras].join(', ')}" + set_header(CACHE_CONTROL, get_header(CACHE_CONTROL) + ", #{control[:extras].join(', ')}") end else extras = control[:extras] @@ -167,7 +170,7 @@ module ActionDispatch options << MUST_REVALIDATE if control[:must_revalidate] options.concat(extras) if extras - self[CACHE_CONTROL] = options.join(", ") + set_header CACHE_CONTROL, options.join(", ") end end end diff --git a/actionpack/lib/action_dispatch/http/filter_redirect.rb b/actionpack/lib/action_dispatch/http/filter_redirect.rb index 94c1f2b41f..f4b806b8b5 100644 --- a/actionpack/lib/action_dispatch/http/filter_redirect.rb +++ b/actionpack/lib/action_dispatch/http/filter_redirect.rb @@ -16,7 +16,7 @@ module ActionDispatch def location_filters if request - request.env['action_dispatch.redirect_filter'] || [] + request.get_header('action_dispatch.redirect_filter') || [] else [] end diff --git a/actionpack/lib/action_dispatch/http/parameters.rb b/actionpack/lib/action_dispatch/http/parameters.rb index 277207ae6e..3c9f8cd9e4 100644 --- a/actionpack/lib/action_dispatch/http/parameters.rb +++ b/actionpack/lib/action_dispatch/http/parameters.rb @@ -1,6 +1,3 @@ -require 'active_support/core_ext/hash/keys' -require 'active_support/core_ext/hash/indifferent_access' - module ActionDispatch module Http module Parameters @@ -34,14 +31,6 @@ module ActionDispatch def path_parameters get_header(PARAMETERS_KEY) || {} end - - private - - # Convert nested Hash to HashWithIndifferentAccess. - # - def normalize_encode_params(params) - ActionDispatch::Request::Utils.normalize_encode_params params - end end end end diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 4748a54550..45600d0a61 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -35,7 +35,8 @@ module ActionDispatch HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM HTTP_NEGOTIATE HTTP_PRAGMA HTTP_CLIENT_IP HTTP_X_FORWARDED_FOR HTTP_VERSION - HTTP_X_REQUEST_ID + HTTP_X_REQUEST_ID HTTP_X_FORWARDED_HOST + SERVER_ADDR ].freeze ENV_METHODS.each do |env| @@ -67,16 +68,23 @@ module ActionDispatch end end + PASS_NOT_FOUND = Class.new { # :nodoc: + def self.action(_); self; end + def self.call(_); [404, {'X-Cascade' => 'pass'}, []]; end + } + def controller_class check_path_parameters! params = path_parameters - controller_param = params[:controller].underscore if params.key?(:controller) - params[:action] ||= 'index' - - yield unless controller_param - const_name = "#{controller_param.camelize}Controller" - ActiveSupport::Dependencies.constantize(const_name) + if params.key?(:controller) + controller_param = params[:controller].underscore + params[:action] ||= 'index' + const_name = "#{controller_param.camelize}Controller" + ActiveSupport::Dependencies.constantize(const_name) + else + PASS_NOT_FOUND + end end def key?(key) @@ -150,6 +158,10 @@ module ActionDispatch set_header('action_controller.instance'.freeze, controller) end + def http_auth_salt + get_header "action_dispatch.http_auth_salt" + end + def show_exceptions? # :nodoc: # We're treating `nil` as "unset", and we want the default setting to be # `true`. This logic should be extracted to `env_config` and calculated @@ -323,7 +335,9 @@ module ActionDispatch # Override Rack's GET method to support indifferent access def GET - @env["action_dispatch.request.query_parameters"] ||= normalize_encode_params(super || {}) + get_header("action_dispatch.request.query_parameters") do |k| + set_header k, Request::Utils.normalize_encode_params(super || {}) + end rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e raise ActionController::BadRequest.new(:query, e) end @@ -331,7 +345,9 @@ module ActionDispatch # Override Rack's POST method to support indifferent access def POST - @env["action_dispatch.request.request_parameters"] ||= normalize_encode_params(super || {}) + get_header("action_dispatch.request.request_parameters") do + self.request_parameters = Request::Utils.normalize_encode_params(super || {}) + end rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e raise ActionController::BadRequest.new(:request, e) end @@ -352,6 +368,7 @@ module ActionDispatch end def request_parameters=(params) + raise if params.nil? set_header("action_dispatch.request.request_parameters".freeze, params) end diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index fd92e89231..4aee489912 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -65,7 +65,7 @@ module ActionDispatch # :nodoc: CONTENT_TYPE = "Content-Type".freeze SET_COOKIE = "Set-Cookie".freeze LOCATION = "Location".freeze - NO_CONTENT_CODES = [204, 304] + NO_CONTENT_CODES = [100, 101, 102, 204, 205, 304] cattr_accessor(:default_charset) { "utf-8" } cattr_accessor(:default_headers) @@ -150,6 +150,11 @@ module ActionDispatch # :nodoc: yield self if block_given? end + def have_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 + def await_commit synchronize do @cv.wait_until { @committed } @@ -256,25 +261,9 @@ module ActionDispatch # :nodoc: parts end - def set_cookie(key, value) - ::Rack::Utils.set_cookie_header!(header, key, value) - end - - def delete_cookie(key, value={}) - ::Rack::Utils.delete_cookie_header!(header, key, value) - end - # The location header we'll be responding with. - def location - headers[LOCATION] - end alias_method :redirect_url, :location - # Sets the location header we'll be responding with. - def location=(url) - headers[LOCATION] = url - end - def close stream.close if stream.respond_to?(:close) end @@ -305,7 +294,7 @@ module ActionDispatch # :nodoc: # assert_equal 'AuthorOfNewPage', r.cookies['author'] def cookies cookies = {} - if header = self[SET_COOKIE] + if header = get_header(SET_COOKIE) header = header.split("\n") if header.respond_to?(:to_str) header.each do |cookie| if pair = cookie.split(';').first @@ -341,14 +330,14 @@ module ActionDispatch # :nodoc: end def assign_default_content_type_and_charset! - return if self[CONTENT_TYPE].present? + return if get_header(CONTENT_TYPE).present? @content_type ||= Mime::HTML type = @content_type.to_s.dup type << "; charset=#{charset}" if append_charset? - self[CONTENT_TYPE] = type + set_header CONTENT_TYPE, type end def append_charset? @@ -392,10 +381,9 @@ module ActionDispatch # :nodoc: end def rack_response(status, header) - header[SET_COOKIE] = header[SET_COOKIE].join("\n") if header[SET_COOKIE].respond_to?(:join) - if NO_CONTENT_CODES.include?(@status) header.delete CONTENT_TYPE + header.delete 'Content-Length' [status, header, []] else [status, header, RackBody.new(self)] diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 6fcf49030b..e413954066 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -229,10 +229,10 @@ module ActionDispatch # req = Request.new 'HTTP_HOST' => 'example.com:8080' # req.raw_host_with_port # => "example.com:8080" def raw_host_with_port - if forwarded = env["HTTP_X_FORWARDED_HOST"].presence + if forwarded = x_forwarded_host.presence forwarded.split(/,\s?/).last else - env['HTTP_HOST'] || "#{env['SERVER_NAME'] || env['SERVER_ADDR']}:#{env['SERVER_PORT']}" + get_header('HTTP_HOST') || "#{server_name || server_addr}:#{get_header('SERVER_PORT')}" end end @@ -348,7 +348,7 @@ module ActionDispatch end def server_port - @env['SERVER_PORT'].to_i + get_header('SERVER_PORT').to_i end # Returns the \domain part of a \host, such as "rubyonrails.org" in "www.rubyonrails.org". You can specify diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index e4c5b0bd29..6d0387cf74 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -1,6 +1,4 @@ require 'active_support/core_ext/hash/keys' -require 'active_support/core_ext/module/attribute_accessors' -require 'active_support/core_ext/object/blank' require 'active_support/key_generator' require 'active_support/message_verifier' require 'active_support/json' @@ -8,7 +6,7 @@ require 'active_support/json' module ActionDispatch class Request < Rack::Request def cookie_jar - get_header('action_dispatch.cookies'.freeze) do |k| + get_header('action_dispatch.cookies'.freeze) do self.cookie_jar = Cookies::CookieJar.build(self, cookies) end end diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb index 402ad778fa..9cde9c9b98 100644 --- a/actionpack/lib/action_dispatch/middleware/params_parser.rb +++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb @@ -37,7 +37,9 @@ module ActionDispatch def call(env) request = Request.new(env) - request.request_parameters = parse_formatted_parameters(request, @parsers) + parse_formatted_parameters(request, @parsers) do |params| + request.request_parameters = params + end @app.call(env) end @@ -48,7 +50,7 @@ module ActionDispatch strategy = parsers.fetch(request.content_mime_type) { return nil } - strategy.call(request.raw_post) + yield strategy.call(request.raw_post) rescue => e # JSON or Ruby code block errors logger(request).debug "Error occurred while parsing request parameters.\nContents:\n\n#{request.raw_post}" diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb index 0430ce3b9a..90e2ae6802 100644 --- a/actionpack/lib/action_dispatch/middleware/stack.rb +++ b/actionpack/lib/action_dispatch/middleware/stack.rb @@ -87,7 +87,7 @@ module ActionDispatch middlewares.freeze.reverse.inject(app) { |a, e| e.build(a) } end - protected + private def assert_index(index, where) index = get_class index @@ -96,8 +96,6 @@ module ActionDispatch i end - private - def get_class(klass) if klass.is_a?(String) || klass.is_a?(Symbol) classcache = ActiveSupport::Dependencies::Reference diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 51bafb539f..1acfb2bfe8 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -283,12 +283,16 @@ module ActionDispatch end def app(blocks) - if to.respond_to?(:call) - Constraints.new(to, blocks, Constraints::CALL) - elsif blocks.any? - Constraints.new(dispatcher(defaults.key?(:controller)), blocks, Constraints::SERVE) + if to.is_a?(Class) && to < ActionController::Metal + Routing::RouteSet::StaticDispatcher.new to else - dispatcher(defaults.key?(:controller)) + 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 end end @@ -368,7 +372,7 @@ module ActionDispatch end def dispatcher(raise_on_name_error) - @set.dispatcher raise_on_name_error + Routing::RouteSet::Dispatcher.new raise_on_name_error end end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index af6f0de556..e4b8d5993e 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -27,11 +27,10 @@ module ActionDispatch def dispatcher?; true; end def serve(req) - params = req.path_parameters - controller = controller_reference(req) do - return [404, {'X-Cascade' => 'pass'}, []] - end - dispatch(controller, params[:action], req) + params = req.path_parameters + controller = controller req + res = controller.make_response! req + dispatch(controller, params[:action], req, res) rescue NameError => e if @raise_on_name_error raise ActionController::RoutingError, e.message, e.backtrace @@ -40,16 +39,26 @@ module ActionDispatch end end - protected - def controller_reference(req, &block) - req.controller_class(&block) + private + + def controller(req) + req.controller_class end - private + def dispatch(controller, action, req, res) + controller.dispatch(action, req, res) + end + end - def dispatch(controller, action, req) - controller.action(action).call(req.env) + class StaticDispatcher < Dispatcher + def initialize(controller_class) + super(false) + @controller_class = controller_class end + + private + + def controller(_); @controller_class; end end # A NamedRouteCollection instance is a collection of named routes, and also @@ -171,9 +180,9 @@ module ActionDispatch private def optimized_helper(args) - params = parameterize_args(args) { |k| + params = parameterize_args(args) do raise_generation_error(args) - } + end @route.format params end @@ -285,7 +294,7 @@ module ActionDispatch attr_accessor :formatter, :set, :named_routes, :default_scope, :router attr_accessor :disable_clear_and_finalize, :resources_path_names - attr_accessor :default_url_options, :dispatcher_class + attr_accessor :default_url_options attr_reader :env_key alias :routes :set @@ -328,7 +337,6 @@ module ActionDispatch @set = Journey::Routes.new @router = Journey::Router.new @set @formatter = Journey::Formatter.new self - @dispatcher_class = Routing::RouteSet::Dispatcher end def relative_url_root @@ -343,6 +351,11 @@ module ActionDispatch ActionDispatch::Request end + def make_request(env) + request_class.new env + end + private :make_request + def draw(&block) clear! unless @disable_clear_and_finalize eval_block(block) @@ -386,10 +399,6 @@ module ActionDispatch @prepend.each { |blk| eval_block(blk) } end - def dispatcher(raise_on_name_error) - dispatcher_class.new(raise_on_name_error) - end - module MountedHelpers extend ActiveSupport::Concern include UrlFor @@ -700,7 +709,7 @@ module ActionDispatch end def call(env) - req = request_class.new(env) + req = make_request(env) req.path_info = Journey::Router::Utils.normalize_path(req.path_info) @router.serve(req) end @@ -716,7 +725,7 @@ module ActionDispatch raise ActionController::RoutingError, e.message end - req = request_class.new(env) + req = make_request(env) @router.recognize(req) do |route, params| params.merge!(extras) params.each do |key, value| |