diff options
Diffstat (limited to 'actionpack/lib')
6 files changed, 110 insertions, 79 deletions
diff --git a/actionpack/lib/action_controller/metal/hide_actions.rb b/actionpack/lib/action_controller/metal/hide_actions.rb index 420b22cf56..2aa6b7adaf 100644 --- a/actionpack/lib/action_controller/metal/hide_actions.rb +++ b/actionpack/lib/action_controller/metal/hide_actions.rb @@ -26,20 +26,14 @@ module ActionController self.hidden_actions = hidden_actions.dup.merge(args.map(&:to_s)).freeze end - def inherited(klass) - klass.class_eval { @visible_actions = {} } - super - end - def visible_action?(action_name) - return @visible_actions[action_name] if @visible_actions.key?(action_name) - @visible_actions[action_name] = !hidden_actions.include?(action_name) + action_methods.include?(action_name) end # Overrides AbstractController::Base#action_methods to remove any methods # that are listed as hidden methods. def action_methods - @action_methods ||= Set.new(super.reject { |name| hidden_actions.include?(name) }) + @action_methods ||= Set.new(super.reject { |name| hidden_actions.include?(name) }).freeze end end end diff --git a/actionpack/lib/action_dispatch/http/filter_parameters.rb b/actionpack/lib/action_dispatch/http/filter_parameters.rb index 47cf41cfa3..4a7df6b657 100644 --- a/actionpack/lib/action_dispatch/http/filter_parameters.rb +++ b/actionpack/lib/action_dispatch/http/filter_parameters.rb @@ -1,3 +1,4 @@ +require 'mutex_m' require 'active_support/core_ext/hash/keys' require 'active_support/core_ext/object/duplicable' @@ -20,9 +21,18 @@ module ActionDispatch # end # => reverses the value to all keys matching /secret/i module FilterParameters - extend ActiveSupport::Concern + @@parameter_filter_for = {}.extend(Mutex_m) - @@parameter_filter_for = {} + ENV_MATCH = [/RAW_POST_DATA/, "rack.request.form_vars"] # :nodoc: + NULL_PARAM_FILTER = ParameterFilter.new # :nodoc: + NULL_ENV_FILTER = ParameterFilter.new ENV_MATCH # :nodoc: + + def initialize(env) + super + @filtered_parameters = nil + @filtered_env = nil + @filtered_path = nil + end # Return a hash of parameters with all sensitive data replaced. def filtered_parameters @@ -42,15 +52,24 @@ module ActionDispatch protected def parameter_filter - parameter_filter_for(@env["action_dispatch.parameter_filter"]) + parameter_filter_for @env.fetch("action_dispatch.parameter_filter") { + return NULL_PARAM_FILTER + } end def env_filter - parameter_filter_for(Array(@env["action_dispatch.parameter_filter"]) + [/RAW_POST_DATA/, "rack.request.form_vars"]) + user_key = @env.fetch("action_dispatch.parameter_filter") { + return NULL_ENV_FILTER + } + parameter_filter_for(Array(user_key) + ENV_MATCH) end def parameter_filter_for(filters) - @@parameter_filter_for[filters] ||= ParameterFilter.new(filters) + @@parameter_filter_for.synchronize do + # Do we *actually* need this cache? Constructing ParameterFilters + # doesn't seem too expensive. + @@parameter_filter_for[filters] ||= ParameterFilter.new(filters) + end end KV_RE = '[^&;=]+' diff --git a/actionpack/lib/action_dispatch/http/headers.rb b/actionpack/lib/action_dispatch/http/headers.rb index a3bb25f75a..dc04d4577b 100644 --- a/actionpack/lib/action_dispatch/http/headers.rb +++ b/actionpack/lib/action_dispatch/http/headers.rb @@ -1,32 +1,39 @@ module ActionDispatch module Http - class Headers < ::Hash - @@env_cache = Hash.new { |h,k| h[k] = "HTTP_#{k.upcase.gsub(/-/, '_')}" } + class Headers + include Enumerable - def initialize(*args) - - if args.size == 1 && args[0].is_a?(Hash) - super() - update(args[0]) - else - super - end + def initialize(env = {}) + @headers = env end def [](header_name) - super env_name(header_name) + @headers[env_name(header_name)] + end + + def []=(k,v); @headers[k] = v; end + def key?(k); @headers.key? k; end + alias :include? :key? + + def fetch(header_name, *args, &block) + @headers.fetch env_name(header_name), *args, &block end - def fetch(header_name, default=nil, &block) - super env_name(header_name), default, &block + def each(&block) + @headers.each(&block) end private - # Converts a HTTP header name to an environment variable name if it is - # not contained within the headers hash. - def env_name(header_name) - include?(header_name) ? header_name : @@env_cache[header_name] - end + + # Converts a HTTP header name to an environment variable name if it is + # not contained within the headers hash. + def env_name(header_name) + @headers.include?(header_name) ? header_name : cgi_name(header_name) + end + + def cgi_name(k) + "HTTP_#{k.upcase.gsub(/-/, '_')}" + end end end end diff --git a/actionpack/lib/action_dispatch/http/parameter_filter.rb b/actionpack/lib/action_dispatch/http/parameter_filter.rb index 490b46c990..b655a54865 100644 --- a/actionpack/lib/action_dispatch/http/parameter_filter.rb +++ b/actionpack/lib/action_dispatch/http/parameter_filter.rb @@ -1,74 +1,72 @@ module ActionDispatch module Http class ParameterFilter + FILTERED = '[FILTERED]'.freeze # :nodoc: - def initialize(filters) + def initialize(filters = []) @filters = filters end def filter(params) - if enabled? - compiled_filter.call(params) - else - params.dup - end + compiled_filter.call(params) end private - def enabled? - @filters.present? + def compiled_filter + @compiled_filter ||= CompiledFilter.compile(@filters) end - FILTERED = '[FILTERED]'.freeze + class CompiledFilter # :nodoc: + def self.compile(filters) + return lambda { |params| params.dup } if filters.empty? - def compiled_filter - @compiled_filter ||= begin - regexps, blocks = compile_filter + strings, regexps, blocks = [], [], [] - lambda do |original_params| - filtered_params = {} + filters.each do |item| + case item + when Proc + blocks << item + when Regexp + regexps << item + else + strings << item.to_s + end + end - original_params.each do |key, value| - if regexps.find { |r| key =~ r } - value = FILTERED - elsif value.is_a?(Hash) - value = filter(value) - elsif value.is_a?(Array) - value = value.map { |v| v.is_a?(Hash) ? filter(v) : v } - elsif blocks.present? - key = key.dup - value = value.dup if value.duplicable? - blocks.each { |b| b.call(key, value) } - end + regexps << Regexp.new(strings.join('|'), true) unless strings.empty? + new regexps, blocks + end - filtered_params[key] = value - end + attr_reader :regexps, :blocks - filtered_params - end + def initialize(regexps, blocks) + @regexps = regexps + @blocks = blocks end - end - def compile_filter - strings, regexps, blocks = [], [], [] + def call(original_params) + filtered_params = {} + + original_params.each do |key, value| + if regexps.any? { |r| key =~ r } + value = FILTERED + elsif value.is_a?(Hash) + value = call(value) + elsif value.is_a?(Array) + value = value.map { |v| v.is_a?(Hash) ? call(v) : v } + elsif blocks.any? + key = key.dup + value = value.dup if value.duplicable? + blocks.each { |b| b.call(key, value) } + end - @filters.each do |item| - case item - when NilClass - when Proc - blocks << item - when Regexp - regexps << item - else - strings << item.to_s + filtered_params[key] = value end - end - regexps << Regexp.new(strings.join('|'), true) unless strings.empty? - [regexps, blocks] + filtered_params + end end - end end end diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index b8ebeb408f..fc8825d6d9 100644 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -70,7 +70,13 @@ module ActionDispatch RFC5789 = %w(PATCH) HTTP_METHODS = RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC5789 - HTTP_METHOD_LOOKUP = Hash.new { |h, m| h[m] = m.underscore.to_sym if HTTP_METHODS.include?(m) } + + HTTP_METHOD_LOOKUP = {} + + # Populate the HTTP method lookup cache + HTTP_METHODS.each { |method| + HTTP_METHOD_LOOKUP[method] = method.underscore.to_sym + } # Returns the HTTP \method that the application should see. # In the case where the \method was overridden by a middleware diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 387dfeab17..f43d20c6ed 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -73,13 +73,17 @@ module ActionView options[:include_seconds] ||= !!include_seconds_or_options end + options = { + scope: :'datetime.distance_in_words' + }.merge!(options) + from_time = from_time.to_time if from_time.respond_to?(:to_time) to_time = to_time.to_time if to_time.respond_to?(:to_time) from_time, to_time = to_time, from_time if from_time > to_time distance_in_minutes = ((to_time - from_time)/60.0).round distance_in_seconds = (to_time - from_time).round - I18n.with_options :locale => options[:locale], :scope => :'datetime.distance_in_words' do |locale| + I18n.with_options :locale => options[:locale], :scope => options[:scope] do |locale| case distance_in_minutes when 0..1 return distance_in_minutes == 0 ? @@ -196,6 +200,8 @@ module ActionView # for <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>, <tt>:minute</tt> and <tt>:second</tt>. # Setting this option prepends a select option with a generic prompt (Day, Month, Year, Hour, Minute, Seconds) # or the given prompt string. + # * <tt>:with_css_classes</tt> - Set to true if you want assign different styles for 'select' tags. This option + # automatically set classes 'year', 'month', 'day', 'hour', 'minute' and 'second' for your 'select' tags. # # If anything is passed in the +html_options+ hash it will be applied to every select tag in the set. # @@ -937,6 +943,7 @@ module ActionView :name => input_name_from_type(type) }.merge!(@html_options) select_options[:disabled] = 'disabled' if @options[:disabled] + select_options[:class] = type if @options[:with_css_classes] select_html = "\n" select_html << content_tag(:option, '', :value => '') + "\n" if @options[:include_blank] |