activesupport 4.1.15 → 4.2.11.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (111) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +395 -574
  3. data/README.rdoc +7 -2
  4. data/lib/active_support.rb +19 -0
  5. data/lib/active_support/backtrace_cleaner.rb +4 -4
  6. data/lib/active_support/cache.rb +17 -19
  7. data/lib/active_support/cache/file_store.rb +5 -0
  8. data/lib/active_support/cache/mem_cache_store.rb +1 -1
  9. data/lib/active_support/cache/strategy/local_cache.rb +5 -4
  10. data/lib/active_support/cache/strategy/local_cache_middleware.rb +5 -0
  11. data/lib/active_support/callbacks.rb +41 -33
  12. data/lib/active_support/concern.rb +10 -2
  13. data/lib/active_support/core_ext/array/access.rb +9 -1
  14. data/lib/active_support/core_ext/array/grouping.rb +5 -0
  15. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +2 -0
  16. data/lib/active_support/core_ext/class/delegating_attributes.rb +4 -0
  17. data/lib/active_support/core_ext/class/subclasses.rb +0 -2
  18. data/lib/active_support/core_ext/date/conversions.rb +6 -0
  19. data/lib/active_support/core_ext/date_and_time/calculations.rb +11 -0
  20. data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
  21. data/lib/active_support/core_ext/date_time.rb +1 -0
  22. data/lib/active_support/core_ext/date_time/calculations.rb +34 -4
  23. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  24. data/lib/active_support/core_ext/date_time/conversions.rb +2 -2
  25. data/lib/active_support/core_ext/digest/uuid.rb +51 -0
  26. data/lib/active_support/core_ext/enumerable.rb +16 -0
  27. data/lib/active_support/core_ext/file/atomic.rb +1 -1
  28. data/lib/active_support/core_ext/hash.rb +1 -0
  29. data/lib/active_support/core_ext/hash/compact.rb +20 -16
  30. data/lib/active_support/core_ext/hash/conversions.rb +3 -5
  31. data/lib/active_support/core_ext/hash/except.rb +8 -2
  32. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
  33. data/lib/active_support/core_ext/hash/keys.rb +10 -6
  34. data/lib/active_support/core_ext/hash/slice.rb +8 -2
  35. data/lib/active_support/core_ext/hash/transform_values.rb +23 -0
  36. data/lib/active_support/core_ext/integer/time.rb +0 -15
  37. data/lib/active_support/core_ext/kernel.rb +3 -2
  38. data/lib/active_support/core_ext/kernel/concern.rb +10 -0
  39. data/lib/active_support/core_ext/kernel/debugger.rb +1 -1
  40. data/lib/active_support/core_ext/kernel/reporting.rb +15 -0
  41. data/lib/active_support/core_ext/load_error.rb +4 -1
  42. data/lib/active_support/core_ext/marshal.rb +8 -5
  43. data/lib/active_support/core_ext/module/aliasing.rb +2 -2
  44. data/lib/active_support/core_ext/module/delegation.rb +34 -18
  45. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -1
  46. data/lib/active_support/core_ext/numeric/conversions.rb +11 -3
  47. data/lib/active_support/core_ext/numeric/time.rb +1 -34
  48. data/lib/active_support/core_ext/object.rb +1 -0
  49. data/lib/active_support/core_ext/object/blank.rb +2 -2
  50. data/lib/active_support/core_ext/object/duplicable.rb +62 -33
  51. data/lib/active_support/core_ext/object/itself.rb +15 -0
  52. data/lib/active_support/core_ext/object/json.rb +2 -2
  53. data/lib/active_support/core_ext/object/to_query.rb +2 -1
  54. data/lib/active_support/core_ext/object/try.rb +35 -13
  55. data/lib/active_support/core_ext/object/with_options.rb +30 -3
  56. data/lib/active_support/core_ext/string/access.rb +5 -5
  57. data/lib/active_support/core_ext/string/conversions.rb +1 -1
  58. data/lib/active_support/core_ext/string/filters.rb +44 -6
  59. data/lib/active_support/core_ext/string/inflections.rb +4 -1
  60. data/lib/active_support/core_ext/string/output_safety.rb +33 -14
  61. data/lib/active_support/core_ext/thread.rb +7 -0
  62. data/lib/active_support/core_ext/time.rb +1 -0
  63. data/lib/active_support/core_ext/time/calculations.rb +31 -7
  64. data/lib/active_support/core_ext/time/compatibility.rb +14 -0
  65. data/lib/active_support/core_ext/time/conversions.rb +1 -1
  66. data/lib/active_support/dependencies.rb +32 -18
  67. data/lib/active_support/dependencies/autoload.rb +1 -1
  68. data/lib/active_support/deprecation.rb +1 -1
  69. data/lib/active_support/deprecation/behaviors.rb +1 -1
  70. data/lib/active_support/duration.rb +47 -5
  71. data/lib/active_support/gem_version.rb +4 -4
  72. data/lib/active_support/hash_with_indifferent_access.rb +35 -7
  73. data/lib/active_support/i18n_railtie.rb +1 -7
  74. data/lib/active_support/inflector/inflections.rb +2 -2
  75. data/lib/active_support/inflector/methods.rb +43 -19
  76. data/lib/active_support/json/decoding.rb +1 -1
  77. data/lib/active_support/json/encoding.rb +3 -2
  78. data/lib/active_support/logger.rb +36 -0
  79. data/lib/active_support/logger_silence.rb +4 -22
  80. data/lib/active_support/logger_thread_safe_level.rb +32 -0
  81. data/lib/active_support/message_encryptor.rb +10 -2
  82. data/lib/active_support/message_verifier.rb +11 -12
  83. data/lib/active_support/multibyte/chars.rb +1 -1
  84. data/lib/active_support/multibyte/unicode.rb +5 -4
  85. data/lib/active_support/notifications.rb +8 -3
  86. data/lib/active_support/notifications/fanout.rb +12 -7
  87. data/lib/active_support/number_helper.rb +12 -13
  88. data/lib/active_support/number_helper/number_to_currency_converter.rb +1 -1
  89. data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
  90. data/lib/active_support/number_helper/number_to_rounded_converter.rb +1 -1
  91. data/lib/active_support/per_thread_registry.rb +5 -3
  92. data/lib/active_support/test_case.rb +46 -12
  93. data/lib/active_support/testing/assertions.rb +1 -1
  94. data/lib/active_support/testing/constant_lookup.rb +1 -5
  95. data/lib/active_support/testing/declarative.rb +1 -25
  96. data/lib/active_support/testing/isolation.rb +16 -6
  97. data/lib/active_support/testing/tagged_logging.rb +1 -1
  98. data/lib/active_support/testing/time_helpers.rb +23 -16
  99. data/lib/active_support/time.rb +0 -2
  100. data/lib/active_support/time_with_zone.rb +48 -29
  101. data/lib/active_support/values/time_zone.rb +81 -75
  102. data/lib/active_support/values/unicode_tables.dat +0 -0
  103. data/lib/active_support/xml_mini.rb +30 -15
  104. data/lib/active_support/xml_mini/libxml.rb +1 -3
  105. data/lib/active_support/xml_mini/libxmlsax.rb +1 -4
  106. data/lib/active_support/xml_mini/nokogiri.rb +1 -3
  107. data/lib/active_support/xml_mini/nokogirisax.rb +1 -3
  108. data/lib/active_support/xml_mini/rexml.rb +1 -3
  109. metadata +21 -36
  110. data/lib/active_support/core_ext/object/to_json.rb +0 -5
  111. data/lib/active_support/file_watcher.rb +0 -36
@@ -1,14 +1,14 @@
1
1
  module ActiveSupport
2
- # Returns the version of the currently loaded ActiveSupport as a <tt>Gem::Version</tt>
2
+ # Returns the version of the currently loaded Active Support as a <tt>Gem::Version</tt>
3
3
  def self.gem_version
4
4
  Gem::Version.new VERSION::STRING
5
5
  end
6
6
 
7
7
  module VERSION
8
8
  MAJOR = 4
9
- MINOR = 1
10
- TINY = 15
11
- PRE = nil
9
+ MINOR = 2
10
+ TINY = 11
11
+ PRE = "3"
12
12
 
13
13
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
14
14
  end
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext/hash/keys'
2
+ require 'active_support/core_ext/hash/reverse_merge'
2
3
 
3
4
  module ActiveSupport
4
5
  # Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
@@ -55,7 +56,7 @@ module ActiveSupport
55
56
  end
56
57
 
57
58
  def initialize(constructor = {})
58
- if constructor.is_a?(Hash)
59
+ if constructor.respond_to?(:to_hash)
59
60
  super()
60
61
  update(constructor)
61
62
  else
@@ -75,6 +76,7 @@ module ActiveSupport
75
76
  hash = hash.to_hash
76
77
  new(hash).tap do |new_hash|
77
78
  new_hash.default = hash.default
79
+ new_hash.default_proc = hash.default_proc if hash.default_proc
78
80
  end
79
81
  end
80
82
 
@@ -176,10 +178,17 @@ module ActiveSupport
176
178
  indices.collect { |key| self[convert_key(key)] }
177
179
  end
178
180
 
179
- # Returns an exact copy of the hash.
181
+ # Returns a shallow copy of the hash.
182
+ #
183
+ # hash = ActiveSupport::HashWithIndifferentAccess.new({ a: { b: 'b' } })
184
+ # dup = hash.dup
185
+ # dup[:a][:c] = 'c'
186
+ #
187
+ # hash[:a][:c] # => nil
188
+ # dup[:a][:c] # => "c"
180
189
  def dup
181
190
  self.class.new(self).tap do |new_hash|
182
- new_hash.default = default
191
+ set_defaults(new_hash)
183
192
  end
184
193
  end
185
194
 
@@ -236,13 +245,24 @@ module ActiveSupport
236
245
  dup.tap { |hash| hash.reject!(*args, &block) }
237
246
  end
238
247
 
248
+ def transform_values(*args, &block)
249
+ return to_enum(:transform_values) unless block_given?
250
+ dup.tap { |hash| hash.transform_values!(*args, &block) }
251
+ end
252
+
253
+ def compact
254
+ dup.tap(&:compact!)
255
+ end
256
+
239
257
  # Convert to a regular hash with string keys.
240
258
  def to_hash
241
- _new_hash= {}
259
+ _new_hash = Hash.new
260
+ set_defaults(_new_hash)
261
+
242
262
  each do |key, value|
243
- _new_hash[convert_key(key)] = convert_value(value, for: :to_hash)
263
+ _new_hash[key] = convert_value(value, for: :to_hash)
244
264
  end
245
- Hash.new(default).merge!(_new_hash)
265
+ _new_hash
246
266
  end
247
267
 
248
268
  protected
@@ -258,7 +278,7 @@ module ActiveSupport
258
278
  value.nested_under_indifferent_access
259
279
  end
260
280
  elsif value.is_a?(Array)
261
- unless options[:for] == :assignment
281
+ if options[:for] != :assignment || value.frozen?
262
282
  value = value.dup
263
283
  end
264
284
  value.map! { |e| convert_value(e, options) }
@@ -266,6 +286,14 @@ module ActiveSupport
266
286
  value
267
287
  end
268
288
  end
289
+
290
+ def set_defaults(target)
291
+ if default_proc
292
+ target.default_proc = default_proc.dup
293
+ else
294
+ target.default = default
295
+ end
296
+ end
269
297
  end
270
298
  end
271
299
 
@@ -8,8 +8,6 @@ module I18n
8
8
  config.i18n.railties_load_path = []
9
9
  config.i18n.load_path = []
10
10
  config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
11
- # Enforce I18n to check the available locales when setting a locale.
12
- config.i18n.enforce_available_locales = true
13
11
 
14
12
  # Set the i18n configuration after initialization since a lot of
15
13
  # configuration is still usually done in application initializers.
@@ -36,11 +34,7 @@ module I18n
36
34
  # Avoid issues with setting the default_locale by disabling available locales
37
35
  # check while configuring.
38
36
  enforce_available_locales = app.config.i18n.delete(:enforce_available_locales)
39
-
40
- if enforce_available_locales.nil?
41
- enforce_available_locales = I18n.enforce_available_locales
42
- end
43
-
37
+ enforce_available_locales = I18n.enforce_available_locales if enforce_available_locales.nil?
44
38
  I18n.enforce_available_locales = false
45
39
 
46
40
  app.config.i18n.each do |setting, value|
@@ -154,13 +154,13 @@ module ActiveSupport
154
154
  end
155
155
  end
156
156
 
157
- # Add uncountable words that shouldn't be attempted inflected.
157
+ # Specifies words that are uncountable and should not be inflected.
158
158
  #
159
159
  # uncountable 'money'
160
160
  # uncountable 'money', 'information'
161
161
  # uncountable %w( money information rice )
162
162
  def uncountable(*words)
163
- (@uncountables << words).flatten!
163
+ @uncountables += words.flatten.map(&:downcase)
164
164
  end
165
165
 
166
166
  # Specifies a humanized form of a string by a regular expression rule or
@@ -73,7 +73,7 @@ module ActiveSupport
73
73
  string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase }
74
74
  end
75
75
  string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }
76
- string.gsub!('/', '::')
76
+ string.gsub!(/\//, '::')
77
77
  string
78
78
  end
79
79
 
@@ -89,8 +89,9 @@ module ActiveSupport
89
89
  #
90
90
  # 'SSLError'.underscore.camelize # => "SslError"
91
91
  def underscore(camel_cased_word)
92
- word = camel_cased_word.to_s.gsub('::', '/')
93
- word.gsub!(/(?:([A-Za-z\d])|^)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
92
+ return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/
93
+ word = camel_cased_word.to_s.gsub(/::/, '/')
94
+ word.gsub!(/(?:(?<=([A-Za-z\d]))|\b)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1 && '_'}#{$2.downcase}" }
94
95
  word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
95
96
  word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
96
97
  word.tr!("-", "_")
@@ -98,26 +99,46 @@ module ActiveSupport
98
99
  word
99
100
  end
100
101
 
101
- # Capitalizes the first word, turns underscores into spaces, and strips a
102
- # trailing '_id' if present.
103
- # Like +titleize+, this is meant for creating pretty output.
102
+ # Tweaks an attribute name for display to end users.
103
+ #
104
+ # Specifically, +humanize+ performs these transformations:
105
+ #
106
+ # * Applies human inflection rules to the argument.
107
+ # * Deletes leading underscores, if any.
108
+ # * Removes a "_id" suffix if present.
109
+ # * Replaces underscores with spaces, if any.
110
+ # * Downcases all words except acronyms.
111
+ # * Capitalizes the first word.
104
112
  #
105
113
  # The capitalization of the first word can be turned off by setting the
106
- # optional parameter +capitalize+ to false.
107
- # By default, this parameter is true.
114
+ # +:capitalize+ option to false (default is true).
108
115
  #
109
116
  # humanize('employee_salary') # => "Employee salary"
110
117
  # humanize('author_id') # => "Author"
111
118
  # humanize('author_id', capitalize: false) # => "author"
119
+ # humanize('_id') # => "Id"
120
+ #
121
+ # If "SSL" was defined to be an acronym:
122
+ #
123
+ # humanize('ssl_error') # => "SSL error"
124
+ #
112
125
  def humanize(lower_case_and_underscored_word, options = {})
113
126
  result = lower_case_and_underscored_word.to_s.dup
127
+
114
128
  inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
115
- result.gsub!(/_id$/, "")
129
+
130
+ result.sub!(/\A_+/, '')
131
+ result.sub!(/_id\z/, '')
116
132
  result.tr!('_', ' ')
117
- result.gsub!(/([a-z\d]*)/i) { |match|
133
+
134
+ result.gsub!(/([a-z\d]*)/i) do |match|
118
135
  "#{inflections.acronyms[match] || match.downcase}"
119
- }
120
- result.gsub!(/^\w/) { |match| match.upcase } if options.fetch(:capitalize, true)
136
+ end
137
+
138
+ if options.fetch(:capitalize, true)
139
+ result.sub!(/\A\w/) { |match| match.upcase }
140
+ end
141
+
121
142
  result
122
143
  end
123
144
 
@@ -132,7 +153,7 @@ module ActiveSupport
132
153
  # 'TheManWithoutAPast'.titleize # => "The Man Without A Past"
133
154
  # 'raiders_of_the_lost_ark'.titleize # => "Raiders Of The Lost Ark"
134
155
  def titleize(word)
135
- humanize(underscore(word)).gsub(/\b(?<!['’`])[a-z]/) { $&.capitalize }
156
+ humanize(underscore(word)).gsub(/\b(?<!['’`])[a-z]/) { |match| match.capitalize }
136
157
  end
137
158
 
138
159
  # Create the name of a table like Rails does for models to table names. This
@@ -171,6 +192,8 @@ module ActiveSupport
171
192
  #
172
193
  # 'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections"
173
194
  # 'Inflections'.demodulize # => "Inflections"
195
+ # '::Inflections'.demodulize # => "Inflections"
196
+ # ''.demodulize # => ""
174
197
  #
175
198
  # See also +deconstantize+.
176
199
  def demodulize(path)
@@ -227,7 +250,7 @@ module ActiveSupport
227
250
  def constantize(camel_cased_word)
228
251
  names = camel_cased_word.split('::')
229
252
 
230
- # Trigger a builtin NameError exception including the ill-formed constant in the message.
253
+ # Trigger a built-in NameError exception including the ill-formed constant in the message.
231
254
  Object.const_get(camel_cased_word) if names.empty?
232
255
 
233
256
  # Remove the first blank element in case of '::ClassName' notation.
@@ -241,8 +264,8 @@ module ActiveSupport
241
264
  next candidate if constant.const_defined?(name, false)
242
265
  next candidate unless Object.const_defined?(name)
243
266
 
244
- # Go down the ancestors to check it it's owned
245
- # directly before we reach Object or the end of ancestors.
267
+ # Go down the ancestors to check if it is owned directly. The check
268
+ # stops when we reach Object or the end of ancestors tree.
246
269
  constant = constant.ancestors.inject do |const, ancestor|
247
270
  break const if ancestor == Object
248
271
  break ancestor if ancestor.const_defined?(name, false)
@@ -325,10 +348,11 @@ module ActiveSupport
325
348
 
326
349
  private
327
350
 
328
- # Mount a regular expression that will match part by part of the constant.
351
+ # Mounts a regular expression, returned as a string to ease interpolation,
352
+ # that will match part by part the given constant.
329
353
  #
330
- # const_regexp("Foo::Bar::Baz") # => /Foo(::Bar(::Baz)?)?/
331
- # const_regexp("::") # => /::/
354
+ # const_regexp("Foo::Bar::Baz") # => "Foo(::Bar(::Baz)?)?"
355
+ # const_regexp("::") # => "::"
332
356
  def const_regexp(camel_cased_word) #:nodoc:
333
357
  parts = camel_cased_word.split("::")
334
358
 
@@ -12,7 +12,7 @@ module ActiveSupport
12
12
 
13
13
  class << self
14
14
  # Parses a JSON string (JavaScript Object Notation) into a hash.
15
- # See www.json.org for more info.
15
+ # See http://www.json.org for more info.
16
16
  #
17
17
  # ActiveSupport::JSON.decode("{\"team\":\"rails\",\"players\":\"36\"}")
18
18
  # => {"team" => "rails", "players" => "36"}
@@ -1,5 +1,6 @@
1
1
  require 'active_support/core_ext/object/json'
2
2
  require 'active_support/core_ext/module/delegation'
3
+ require 'active_support/deprecation'
3
4
 
4
5
  module ActiveSupport
5
6
  class << self
@@ -13,7 +14,7 @@ module ActiveSupport
13
14
 
14
15
  module JSON
15
16
  # Dumps objects in JSON (JavaScript Object Notation).
16
- # See www.json.org for more info.
17
+ # See http://www.json.org for more info.
17
18
  #
18
19
  # ActiveSupport::JSON.encode({ team: 'rails', players: '36' })
19
20
  # # => "{\"team\":\"rails\",\"players\":\"36\"}"
@@ -135,7 +136,7 @@ module ActiveSupport
135
136
  "The JSON encoder in Rails 4.1 no longer supports encoding BigDecimals as JSON numbers. Instead, " \
136
137
  "the new encoder will always encode them as strings.\n\n" \
137
138
  "You are seeing this error because you are trying to check the value of the related configuration, " \
138
- "'active_support.encode_big_decimal_as_string'. If your application depends on this option, you should " \
139
+ "`active_support.encode_big_decimal_as_string`. If your application depends on this option, you should " \
139
140
  "add the 'activesupport-json_encoder' gem to your Gemfile. For now, this option will always be true. " \
140
141
  "In the future, it will be removed from Rails, so you should stop checking its value."
141
142
 
@@ -1,11 +1,24 @@
1
1
  require 'active_support/core_ext/module/attribute_accessors'
2
2
  require 'active_support/logger_silence'
3
+ require 'active_support/logger_thread_safe_level'
3
4
  require 'logger'
4
5
 
5
6
  module ActiveSupport
6
7
  class Logger < ::Logger
8
+ include ActiveSupport::LoggerThreadSafeLevel
7
9
  include LoggerSilence
8
10
 
11
+ # Returns true if the logger destination matches one of the sources
12
+ #
13
+ # logger = Logger.new(STDOUT)
14
+ # ActiveSupport::Logger.logger_outputs_to?(logger, STDOUT)
15
+ # # => true
16
+ def self.logger_outputs_to?(logger, *sources)
17
+ logdev = logger.instance_variable_get("@logdev")
18
+ logger_source = logdev.dev if logdev.respond_to?(:dev)
19
+ sources.any? { |source| source == logger_source }
20
+ end
21
+
9
22
  # Broadcasts logs to multiple loggers.
10
23
  def self.broadcast(logger) # :nodoc:
11
24
  Module.new do
@@ -38,6 +51,29 @@ module ActiveSupport
38
51
  logger.level = level
39
52
  super(level)
40
53
  end
54
+
55
+ define_method(:local_level=) do |level|
56
+ logger.local_level = level if logger.respond_to?(:local_level=)
57
+ super(level) if respond_to?(:local_level=)
58
+ end
59
+
60
+ define_method(:silence) do |level = Logger::ERROR, &block|
61
+ if logger.respond_to?(:silence) && logger.method(:silence).owner != ::Kernel
62
+ logger.silence(level) do
63
+ if respond_to?(:silence) && method(:silence).owner != ::Kernel
64
+ super(level, &block)
65
+ else
66
+ block.call(self)
67
+ end
68
+ end
69
+ else
70
+ if respond_to?(:silence) && method(:silence).owner != ::Kernel
71
+ super(level, &block)
72
+ else
73
+ block.call(self)
74
+ end
75
+ end
76
+ end
41
77
  end
42
78
  end
43
79
 
@@ -3,40 +3,22 @@ require 'thread_safe'
3
3
 
4
4
  module LoggerSilence
5
5
  extend ActiveSupport::Concern
6
-
6
+
7
7
  included do
8
8
  cattr_accessor :silencer
9
- attr_reader :local_levels
10
9
  self.silencer = true
11
10
  end
12
11
 
13
-
14
- def after_initialize
15
- @local_levels = ThreadSafe::Cache.new(:initial_capacity => 2)
16
- end
17
-
18
- def local_log_id
19
- Thread.current.__id__
20
- end
21
-
22
- def level
23
- local_levels[local_log_id] || super
24
- end
25
-
26
12
  # Silences the logger for the duration of the block.
27
13
  def silence(temporary_level = Logger::ERROR)
28
14
  if silencer
29
15
  begin
30
- old_local_level = local_levels[local_log_id]
31
- local_levels[local_log_id] = temporary_level
16
+ old_local_level = local_level
17
+ self.local_level = temporary_level
32
18
 
33
19
  yield self
34
20
  ensure
35
- if old_local_level
36
- local_levels[local_log_id] = old_local_level
37
- else
38
- local_levels.delete(local_log_id)
39
- end
21
+ self.local_level = old_local_level
40
22
  end
41
23
  else
42
24
  yield self
@@ -0,0 +1,32 @@
1
+ require 'active_support/concern'
2
+ require 'thread_safe'
3
+
4
+ module ActiveSupport
5
+ module LoggerThreadSafeLevel
6
+ extend ActiveSupport::Concern
7
+
8
+ def after_initialize
9
+ @local_levels = ThreadSafe::Cache.new
10
+ end
11
+
12
+ def local_log_id
13
+ Thread.current.__id__
14
+ end
15
+
16
+ def local_level
17
+ @local_levels[local_log_id]
18
+ end
19
+
20
+ def local_level=(level)
21
+ if level
22
+ @local_levels[local_log_id] = level
23
+ else
24
+ @local_levels.delete(local_log_id)
25
+ end
26
+ end
27
+
28
+ def level
29
+ local_level || super
30
+ end
31
+ end
32
+ end
@@ -18,6 +18,8 @@ module ActiveSupport
18
18
  # encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
19
19
  # crypt.decrypt_and_verify(encrypted_data) # => "my secret data"
20
20
  class MessageEncryptor
21
+ DEFAULT_CIPHER = "aes-256-cbc"
22
+
21
23
  module NullSerializer #:nodoc:
22
24
  def self.load(value)
23
25
  value
@@ -40,6 +42,7 @@ module ActiveSupport
40
42
  # Options:
41
43
  # * <tt>:cipher</tt> - Cipher to use. Can be any cipher returned by
42
44
  # <tt>OpenSSL::Cipher.ciphers</tt>. Default is 'aes-256-cbc'.
45
+ # * <tt>:digest</tt> - String of digest to use for signing. Default is +SHA1+.
43
46
  # * <tt>:serializer</tt> - Object serializer to use. Default is +Marshal+.
44
47
  def initialize(secret, *signature_key_or_options)
45
48
  options = signature_key_or_options.extract_options!
@@ -47,7 +50,7 @@ module ActiveSupport
47
50
  @secret = secret
48
51
  @sign_secret = sign_secret
49
52
  @cipher = options[:cipher] || 'aes-256-cbc'
50
- @verifier = MessageVerifier.new(@sign_secret || @secret, :serializer => NullSerializer)
53
+ @verifier = MessageVerifier.new(@sign_secret || @secret, digest: options[:digest] || 'SHA1', serializer: NullSerializer)
51
54
  @serializer = options[:serializer] || Marshal
52
55
  end
53
56
 
@@ -63,6 +66,11 @@ module ActiveSupport
63
66
  _decrypt(verifier.verify(value))
64
67
  end
65
68
 
69
+ # Given a cipher, returns the key length of the cipher to help generate the key of desired size
70
+ def self.key_len(cipher = DEFAULT_CIPHER)
71
+ OpenSSL::Cipher.new(cipher).key_len
72
+ end
73
+
66
74
  private
67
75
 
68
76
  def _encrypt(value)
@@ -96,7 +104,7 @@ module ActiveSupport
96
104
  end
97
105
 
98
106
  def new_cipher
99
- OpenSSL::Cipher::Cipher.new(@cipher)
107
+ OpenSSL::Cipher.new(@cipher)
100
108
  end
101
109
 
102
110
  def verifier