honeybadger 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/Gemfile +13 -0
  2. data/Gemfile.lock +114 -0
  3. data/Guardfile +5 -0
  4. data/MIT-LICENSE +22 -0
  5. data/README.md +271 -0
  6. data/Rakefile +261 -0
  7. data/SUPPORTED_RAILS_VERSIONS +26 -0
  8. data/TESTING.md +33 -0
  9. data/features/metal.feature +18 -0
  10. data/features/rack.feature +56 -0
  11. data/features/rails.feature +211 -0
  12. data/features/rake.feature +27 -0
  13. data/features/sinatra.feature +29 -0
  14. data/features/step_definitions/file_steps.rb +10 -0
  15. data/features/step_definitions/metal_steps.rb +23 -0
  16. data/features/step_definitions/rack_steps.rb +23 -0
  17. data/features/step_definitions/rails_application_steps.rb +394 -0
  18. data/features/step_definitions/rake_steps.rb +17 -0
  19. data/features/support/env.rb +17 -0
  20. data/features/support/honeybadger_shim.rb.template +8 -0
  21. data/features/support/rails.rb +201 -0
  22. data/features/support/rake/Rakefile +68 -0
  23. data/features/support/terminal.rb +107 -0
  24. data/generators/honeybadger/honeybadger_generator.rb +94 -0
  25. data/generators/honeybadger/lib/insert_commands.rb +34 -0
  26. data/generators/honeybadger/lib/rake_commands.rb +24 -0
  27. data/generators/honeybadger/templates/capistrano_hook.rb +6 -0
  28. data/generators/honeybadger/templates/honeybadger_tasks.rake +25 -0
  29. data/generators/honeybadger/templates/initializer.rb +6 -0
  30. data/honeybadger.gemspec +109 -0
  31. data/lib/honeybadger.rb +162 -0
  32. data/lib/honeybadger/backtrace.rb +123 -0
  33. data/lib/honeybadger/capistrano.rb +43 -0
  34. data/lib/honeybadger/configuration.rb +273 -0
  35. data/lib/honeybadger/notice.rb +314 -0
  36. data/lib/honeybadger/rack.rb +55 -0
  37. data/lib/honeybadger/rails.rb +34 -0
  38. data/lib/honeybadger/rails/action_controller_catcher.rb +30 -0
  39. data/lib/honeybadger/rails/controller_methods.rb +69 -0
  40. data/lib/honeybadger/rails/middleware/exceptions_catcher.rb +29 -0
  41. data/lib/honeybadger/rails3_tasks.rb +84 -0
  42. data/lib/honeybadger/railtie.rb +45 -0
  43. data/lib/honeybadger/rake_handler.rb +65 -0
  44. data/lib/honeybadger/sender.rb +120 -0
  45. data/lib/honeybadger/shared_tasks.rb +36 -0
  46. data/lib/honeybadger/tasks.rb +82 -0
  47. data/lib/honeybadger_tasks.rb +65 -0
  48. data/lib/rails/generators/honeybadger/honeybadger_generator.rb +99 -0
  49. data/rails/init.rb +1 -0
  50. data/resources/README.md +34 -0
  51. data/resources/ca-bundle.crt +3376 -0
  52. data/script/integration_test.rb +38 -0
  53. data/test/test_helper.rb +143 -0
  54. data/test/unit/backtrace_test.rb +180 -0
  55. data/test/unit/capistrano_test.rb +34 -0
  56. data/test/unit/configuration_test.rb +201 -0
  57. data/test/unit/honeybadger_tasks_test.rb +163 -0
  58. data/test/unit/logger_test.rb +72 -0
  59. data/test/unit/notice_test.rb +406 -0
  60. data/test/unit/notifier_test.rb +245 -0
  61. data/test/unit/rack_test.rb +56 -0
  62. data/test/unit/rails/action_controller_catcher_test.rb +300 -0
  63. data/test/unit/rails_test.rb +35 -0
  64. data/test/unit/sender_test.rb +257 -0
  65. metadata +315 -0
@@ -0,0 +1,43 @@
1
+ # Defines deploy:notify_honeybadger which will send information about the deploy to Honeybadger.
2
+ require 'capistrano'
3
+
4
+ module Honeybadger
5
+ module Capistrano
6
+ def self.load_into(configuration)
7
+ configuration.load do
8
+ after "deploy", "honeybadger:deploy"
9
+ after "deploy:migrations", "honeybadger:deploy"
10
+
11
+ namespace :honeybadger do
12
+ desc <<-DESC
13
+ Notify Honeybadger of the deployment by running the notification on the REMOTE machine.
14
+ - Run remotely so we use remote API keys, environment, etc.
15
+ DESC
16
+ task :deploy, :except => { :no_release => true } do
17
+ rails_env = fetch(:rails_env, "production")
18
+ honeybadger_env = fetch(:honeybadger_env, fetch(:rails_env, "production"))
19
+ local_user = ENV['USER'] || ENV['USERNAME']
20
+ executable = RUBY_PLATFORM.downcase.include?('mswin') ? fetch(:rake, 'rake.bat') : fetch(:rake, 'rake')
21
+ directory = configuration.current_release
22
+ notify_command = "cd #{directory}; #{executable} RAILS_ENV=#{rails_env} honeybadger:deploy TO=#{honeybadger_env} REVISION=#{current_revision} REPO=#{repository} USER=#{local_user}"
23
+ notify_command << " DRY_RUN=true" if dry_run
24
+ notify_command << " API_KEY=#{ENV['API_KEY']}" if ENV['API_KEY']
25
+ logger.info "Notifying Honeybadger of Deploy (#{notify_command})"
26
+ if configuration.dry_run
27
+ logger.info "DRY RUN: Notification not actually run."
28
+ else
29
+ result = ""
30
+ run(notify_command, :once => true) { |ch, stream, data| result << data }
31
+ # TODO: Check if SSL is active on account via result content.
32
+ end
33
+ logger.info "Honeybadger Notification Complete."
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ if Capistrano::Configuration.instance
42
+ Honeybadger::Capistrano.load_into(Capistrano::Configuration.instance)
43
+ end
@@ -0,0 +1,273 @@
1
+ module Honeybadger
2
+ class Configuration
3
+ OPTIONS = [:api_key, :backtrace_filters, :development_environments, :environment_name,
4
+ :host, :http_open_timeout, :http_read_timeout, :ignore, :ignore_by_filters,
5
+ :ignore_user_agent, :notifier_name, :notifier_url, :notifier_version,
6
+ :params_filters, :project_root, :port, :protocol, :proxy_host, :proxy_pass,
7
+ :proxy_port, :proxy_user, :secure, :use_system_ssl_cert_chain, :framework,
8
+ :user_information, :rescue_rake_exceptions].freeze
9
+
10
+ # The API key for your project, found on the project edit form.
11
+ attr_accessor :api_key
12
+
13
+ # The host to connect to (defaults to honeybadger.io).
14
+ attr_accessor :host
15
+
16
+ # The port on which your Honeybadger server runs (defaults to 443 for secure
17
+ # connections, 80 for insecure connections).
18
+ attr_accessor :port
19
+
20
+ # +true+ for https connections, +false+ for http connections.
21
+ attr_accessor :secure
22
+
23
+ # +true+ to use whatever CAs OpenSSL has installed on your system. +false+ to use the ca-bundle.crt file included in Honeybadger itself (reccomended and default)
24
+ attr_accessor :use_system_ssl_cert_chain
25
+
26
+ # The HTTP open timeout in seconds (defaults to 2).
27
+ attr_accessor :http_open_timeout
28
+
29
+ # The HTTP read timeout in seconds (defaults to 5).
30
+ attr_accessor :http_read_timeout
31
+
32
+ # The hostname of your proxy server (if using a proxy)
33
+ attr_accessor :proxy_host
34
+
35
+ # The port of your proxy server (if using a proxy)
36
+ attr_accessor :proxy_port
37
+
38
+ # The username to use when logging into your proxy server (if using a proxy)
39
+ attr_accessor :proxy_user
40
+
41
+ # The password to use when logging into your proxy server (if using a proxy)
42
+ attr_accessor :proxy_pass
43
+
44
+ # A list of parameters that should be filtered out of what is sent to Honeybadger.
45
+ # By default, all "password" attributes will have their contents replaced.
46
+ attr_reader :params_filters
47
+
48
+ # A list of filters for cleaning and pruning the backtrace. See #filter_backtrace.
49
+ attr_reader :backtrace_filters
50
+
51
+ # A list of filters for ignoring exceptions. See #ignore_by_filter.
52
+ attr_reader :ignore_by_filters
53
+
54
+ # A list of exception classes to ignore. The array can be appended to.
55
+ attr_reader :ignore
56
+
57
+ # A list of user agents that are being ignored. The array can be appended to.
58
+ attr_reader :ignore_user_agent
59
+
60
+ # A list of environments in which notifications should not be sent.
61
+ attr_accessor :development_environments
62
+
63
+ # The name of the environment the application is running in
64
+ attr_accessor :environment_name
65
+
66
+ # The path to the project in which the error occurred, such as the Rails.root
67
+ attr_accessor :project_root
68
+
69
+ # The name of the notifier library being used to send notifications (such as "Honeybadger Notifier")
70
+ attr_accessor :notifier_name
71
+
72
+ # The version of the notifier library being used to send notifications (such as "1.0.2")
73
+ attr_accessor :notifier_version
74
+
75
+ # The url of the notifier library being used to send notifications
76
+ attr_accessor :notifier_url
77
+
78
+ # The logger used by Honeybadger
79
+ attr_accessor :logger
80
+
81
+ # The text that the placeholder is replaced with. {{error_id}} is the actual error number.
82
+ attr_accessor :user_information
83
+
84
+ # The framework Honeybadger is configured to use
85
+ attr_accessor :framework
86
+
87
+ # Should Honeybadger catch exceptions from Rake tasks?
88
+ # (boolean or nil; set to nil to catch exceptions when rake isn't running from a terminal; default is nil)
89
+ attr_accessor :rescue_rake_exceptions
90
+
91
+ DEFAULT_PARAMS_FILTERS = %w(password password_confirmation).freeze
92
+
93
+ DEFAULT_BACKTRACE_FILTERS = [
94
+ lambda { |line|
95
+ if defined?(Honeybadger.configuration.project_root) && Honeybadger.configuration.project_root.to_s != ''
96
+ line.sub(/#{Honeybadger.configuration.project_root}/, "[PROJECT_ROOT]")
97
+ else
98
+ line
99
+ end
100
+ },
101
+ lambda { |line| line.gsub(/^\.\//, "") },
102
+ lambda { |line|
103
+ if defined?(Gem)
104
+ Gem.path.inject(line) do |line, path|
105
+ line.gsub(/#{path}/, "[GEM_ROOT]")
106
+ end
107
+ end
108
+ },
109
+ lambda { |line| line if line !~ %r{lib/honeybadger} }
110
+ ].freeze
111
+
112
+ IGNORE_DEFAULT = ['ActiveRecord::RecordNotFound',
113
+ 'ActionController::RoutingError',
114
+ 'ActionController::InvalidAuthenticityToken',
115
+ 'CGI::Session::CookieStore::TamperedWithCookie',
116
+ 'ActionController::UnknownAction',
117
+ 'AbstractController::ActionNotFound',
118
+ 'Mongoid::Errors::DocumentNotFound']
119
+
120
+ alias_method :secure?, :secure
121
+ alias_method :use_system_ssl_cert_chain?, :use_system_ssl_cert_chain
122
+
123
+ def initialize
124
+ @secure = false
125
+ @use_system_ssl_cert_chain= false
126
+ @host = 'api.honeybadger.io'
127
+ @http_open_timeout = 2
128
+ @http_read_timeout = 5
129
+ @params_filters = DEFAULT_PARAMS_FILTERS.dup
130
+ @backtrace_filters = DEFAULT_BACKTRACE_FILTERS.dup
131
+ @ignore_by_filters = []
132
+ @ignore = IGNORE_DEFAULT.dup
133
+ @ignore_user_agent = []
134
+ @development_environments = %w(development test cucumber)
135
+ @notifier_name = 'Honeybadger Notifier'
136
+ @notifier_version = VERSION
137
+ @notifier_url = 'https://github.com/honeybadger/honeybadger'
138
+ @framework = 'Standalone'
139
+ @user_information = 'Honeybadger Error {{error_id}}'
140
+ @rescue_rake_exceptions = nil
141
+ end
142
+
143
+ # Public: Takes a block and adds it to the list of backtrace filters. When
144
+ # the filters run, the block will be handed each line of the backtrace and
145
+ # can modify it as necessary.
146
+ #
147
+ # &block - The new backtrace filter.
148
+ #
149
+ # Examples:
150
+ #
151
+ # config.filter_bracktrace do |line|
152
+ # line.gsub(/^#{Rails.root}/, "[Rails.root]")
153
+ # end
154
+ #
155
+ # Yields a line in the backtrace.
156
+ def filter_backtrace(&block)
157
+ self.backtrace_filters << block
158
+ end
159
+
160
+ # Public: Takes a block and adds it to the list of ignore filters. When
161
+ # the filters run, the block will be handed the exception.
162
+ #
163
+ # &block - The new ignore filter
164
+ # If the block returns true the exception will be ignored, otherwise it
165
+ # will be processed by honeybadger.
166
+ #
167
+ # Examples:
168
+ #
169
+ # config.ignore_by_filter do |exception_data|
170
+ # true if exception_data[:error_class] == "RuntimeError"
171
+ # end
172
+ #
173
+ # Yields the the exception data given to Honeybadger.notify
174
+ def ignore_by_filter(&block)
175
+ self.ignore_by_filters << block
176
+ end
177
+
178
+ # Public: Overrides the list of default ignored errors.
179
+ #
180
+ # names - A list of exceptions to ignore.
181
+ #
182
+ # Returns nothing
183
+ def ignore_only=(names)
184
+ @ignore = [names].flatten
185
+ end
186
+
187
+ # Public: Overrides the list of default ignored user agents
188
+ #
189
+ # names - A list of user agents to ignore
190
+ #
191
+ # Returns nothing
192
+ def ignore_user_agent_only=(names)
193
+ @ignore_user_agent = [names].flatten
194
+ end
195
+
196
+ # Public: Allows config options to be read like a hash
197
+ #
198
+ # option - Key for a given attribute
199
+ #
200
+ # Returns value of requested attribute
201
+ def [](option)
202
+ send(option)
203
+ end
204
+
205
+ # Public
206
+ # Returns a hash of all configurable options
207
+ def to_hash
208
+ OPTIONS.inject({}) do |hash, option|
209
+ hash[option.to_sym] = self.send(option)
210
+ hash
211
+ end
212
+ end
213
+
214
+ # Public
215
+ #
216
+ # hash - A set of configuration options that will take precedence over the defaults
217
+ #
218
+ # Returns a hash of all configurable options merged with +hash+
219
+ def merge(hash)
220
+ to_hash.merge(hash)
221
+ end
222
+
223
+ # Public: Determines if the notifier will send notices.
224
+ #
225
+ # Returns false if in a development environment, true otherwise.
226
+ def public?
227
+ !development_environments.include?(environment_name)
228
+ end
229
+
230
+ def port
231
+ @port || default_port
232
+ end
233
+
234
+ # Public: Determines whether protocol should be "http" or "https".
235
+ #
236
+ # Returns 'http' if you've set secure to false in
237
+ # configuration, and 'https' otherwise.
238
+ def protocol
239
+ if secure?
240
+ 'https'
241
+ else
242
+ 'http'
243
+ end
244
+ end
245
+
246
+ def ca_bundle_path
247
+ if use_system_ssl_cert_chain? && File.exist?(OpenSSL::X509::DEFAULT_CERT_FILE)
248
+ OpenSSL::X509::DEFAULT_CERT_FILE
249
+ else
250
+ local_cert_path # ca-bundle.crt built from source, see resources/README.md
251
+ end
252
+ end
253
+
254
+ def local_cert_path
255
+ File.expand_path(File.join("..", "..", "..", "resources", "ca-bundle.crt"), __FILE__)
256
+ end
257
+
258
+ private
259
+
260
+ # Private: Determines what port should we use for sending notices.
261
+ #
262
+ # Returns 443 if you've set secure to true in your
263
+ # configuration, and 80 otherwise.
264
+ def default_port
265
+ if secure?
266
+ 443
267
+ else
268
+ 80
269
+ end
270
+ end
271
+ end
272
+ end
273
+
@@ -0,0 +1,314 @@
1
+ require 'socket'
2
+
3
+ module Honeybadger
4
+ class Notice
5
+ # The exception that caused this notice, if any
6
+ attr_reader :exception
7
+
8
+ # The backtrace from the given exception or hash.
9
+ attr_reader :backtrace
10
+
11
+ # The name of the class of error (such as RuntimeError)
12
+ attr_reader :error_class
13
+
14
+ # The name of the server environment (such as "production")
15
+ attr_reader :environment_name
16
+
17
+ # CGI variables such as HTTP_METHOD
18
+ attr_reader :cgi_data
19
+
20
+ # The message from the exception, or a general description of the error
21
+ attr_reader :error_message
22
+
23
+ # See Configuration#backtrace_filters
24
+ attr_reader :backtrace_filters
25
+
26
+ # See Configuration#params_filters
27
+ attr_reader :params_filters
28
+
29
+ # A hash of parameters from the query string or post body.
30
+ attr_reader :parameters
31
+ alias_method :params, :parameters
32
+
33
+ # The component (if any) which was used in this request (usually the controller)
34
+ attr_reader :component
35
+ alias_method :controller, :component
36
+
37
+ # The action (if any) that was called in this request
38
+ attr_reader :action
39
+
40
+ # A hash of session data from the request
41
+ attr_reader :session_data
42
+
43
+ # The path to the project that caused the error (usually Rails.root)
44
+ attr_reader :project_root
45
+
46
+ # The URL at which the error occurred (if any)
47
+ attr_reader :url
48
+
49
+ # See Configuration#ignore
50
+ attr_reader :ignore
51
+
52
+ # See Configuration#ignore_by_filters
53
+ attr_reader :ignore_by_filters
54
+
55
+ # The name of the notifier library sending this notice, such as "Honeybadger Notifier"
56
+ attr_reader :notifier_name
57
+
58
+ # The version number of the notifier library sending this notice, such as "2.1.3"
59
+ attr_reader :notifier_version
60
+
61
+ # A URL for more information about the notifier library sending this notice
62
+ attr_reader :notifier_url
63
+
64
+ # The host name where this error occurred (if any)
65
+ attr_reader :hostname
66
+
67
+ def initialize(args)
68
+ self.args = args
69
+ self.exception = args[:exception]
70
+ self.project_root = args[:project_root]
71
+ self.url = args[:url] || rack_env(:url)
72
+
73
+ self.notifier_name = args[:notifier_name]
74
+ self.notifier_version = args[:notifier_version]
75
+ self.notifier_url = args[:notifier_url]
76
+
77
+ self.ignore = args[:ignore] || []
78
+ self.ignore_by_filters = args[:ignore_by_filters] || []
79
+ self.backtrace_filters = args[:backtrace_filters] || []
80
+ self.params_filters = args[:params_filters] || []
81
+ self.parameters = args[:parameters] ||
82
+ action_dispatch_params ||
83
+ rack_env(:params) ||
84
+ {}
85
+ self.component = args[:component] || args[:controller] || parameters['controller']
86
+ self.action = args[:action] || parameters['action']
87
+
88
+ self.environment_name = args[:environment_name]
89
+ self.cgi_data = args[:cgi_data] || args[:rack_env]
90
+ self.backtrace = Backtrace.parse(exception_attribute(:backtrace, caller), :filters => self.backtrace_filters)
91
+ self.error_class = exception_attribute(:error_class) {|exception| exception.class.name }
92
+ self.error_message = exception_attribute(:error_message, 'Notification') do |exception|
93
+ "#{exception.class.name}: #{exception.message}"
94
+ end
95
+
96
+ self.hostname = local_hostname
97
+
98
+ also_use_rack_params_filters
99
+ find_session_data
100
+ clean_params
101
+ clean_rack_request_data
102
+ end
103
+
104
+ # Public: Template used to create JSON payload
105
+ #
106
+ # Returns JSON representation of notice
107
+ def as_json(options = {})
108
+ {
109
+ :notifier => {
110
+ :name => notifier_name,
111
+ :url => notifier_url,
112
+ :version => notifier_version
113
+ },
114
+ :error => {
115
+ :class => error_class,
116
+ :message => error_message,
117
+ :backtrace => backtrace
118
+ },
119
+ :request => {
120
+ :url => url,
121
+ :component => component,
122
+ :action => action,
123
+ :params => parameters,
124
+ :session => session_data,
125
+ :cgi_data => cgi_data
126
+ },
127
+ :server => {
128
+ :project_root => project_root,
129
+ :environment_name => environment_name,
130
+ :hostname => hostname
131
+ }
132
+ }
133
+ end
134
+
135
+ # Public: Creates JSON
136
+ #
137
+ # Returns valid JSON representation of notice
138
+ def to_json(*a)
139
+ as_json.to_json(*a)
140
+ end
141
+
142
+ # Determines if this notice should be ignored
143
+ def ignore?
144
+ ignored_class_names.include?(error_class) ||
145
+ ignore_by_filters.any? {|filter| filter.call(self) }
146
+ end
147
+
148
+ # Public: Allows properties to be accessed using a hash-like syntax
149
+ #
150
+ # method - The given key for an attribute
151
+ #
152
+ # Examples:
153
+ #
154
+ # notice[:error_message]
155
+ #
156
+ # Returns the attribute value, or self if given +:request+
157
+ def [](method)
158
+ case method
159
+ when :request
160
+ self
161
+ else
162
+ send(method)
163
+ end
164
+ end
165
+
166
+ private
167
+
168
+ attr_writer :exception, :backtrace, :error_class, :error_message,
169
+ :backtrace_filters, :parameters, :params_filters, :environment_filters,
170
+ :session_data, :project_root, :url, :ignore, :ignore_by_filters,
171
+ :notifier_name, :notifier_url, :notifier_version, :component, :action,
172
+ :cgi_data, :environment_name, :hostname
173
+
174
+ # Private: Arguments given in the initializer
175
+ attr_accessor :args
176
+
177
+ # Private: Gets a property named +attribute+ of an exception, either from an actual
178
+ # exception or a hash.
179
+ #
180
+ # If an exception is available, #from_exception will be used. Otherwise,
181
+ # a key named +attribute+ will be used from the #args.
182
+ #
183
+ # If no exception or hash key is available, +default+ will be used.
184
+ def exception_attribute(attribute, default = nil, &block)
185
+ (exception && from_exception(attribute, &block)) || args[attribute] || default
186
+ end
187
+
188
+ # Private: Gets a property named +attribute+ from an exception.
189
+ #
190
+ # If a block is given, it will be used when getting the property from an
191
+ # exception. The block should accept and exception and return the value for
192
+ # the property.
193
+ #
194
+ # If no block is given, a method with the same name as +attribute+ will be
195
+ # invoked for the value.
196
+ def from_exception(attribute)
197
+ if block_given?
198
+ yield(exception)
199
+ else
200
+ exception.send(attribute)
201
+ end
202
+ end
203
+
204
+ # Private: Removes non-serializable data from the given attribute.
205
+ # See #clean_unserializable_data
206
+ def clean_unserializable_data_from(attribute)
207
+ self.send(:"#{attribute}=", clean_unserializable_data(send(attribute)))
208
+ end
209
+
210
+ # Private: Removes non-serializable data. Allowed data types are strings, arrays,
211
+ # and hashes. All other types are converted to strings.
212
+ # TODO: move this onto Hash
213
+ def clean_unserializable_data(data, stack = [])
214
+ return "[possible infinite recursion halted]" if stack.any?{|item| item == data.object_id }
215
+
216
+ if data.respond_to?(:to_hash)
217
+ data.to_hash.inject({}) do |result, (key, value)|
218
+ result.merge(key => clean_unserializable_data(value, stack + [data.object_id]))
219
+ end
220
+ elsif data.respond_to?(:to_ary)
221
+ data.to_ary.collect do |value|
222
+ clean_unserializable_data(value, stack + [data.object_id])
223
+ end
224
+ else
225
+ data.to_s
226
+ end
227
+ end
228
+
229
+ # Private: Replaces the contents of params that match params_filters.
230
+ # TODO: extract this to a different class
231
+ def clean_params
232
+ clean_unserializable_data_from(:parameters)
233
+ filter(parameters)
234
+ if cgi_data
235
+ clean_unserializable_data_from(:cgi_data)
236
+ filter(cgi_data)
237
+ end
238
+ if session_data
239
+ clean_unserializable_data_from(:session_data)
240
+ filter(session_data)
241
+ end
242
+ end
243
+
244
+ def clean_rack_request_data
245
+ if cgi_data
246
+ cgi_data.delete("rack.request.form_vars")
247
+ end
248
+ end
249
+
250
+ def filter(hash)
251
+ if params_filters
252
+ hash.each do |key, value|
253
+ if filter_key?(key)
254
+ hash[key] = "[FILTERED]"
255
+ elsif value.respond_to?(:to_hash)
256
+ filter(hash[key])
257
+ end
258
+ end
259
+ end
260
+ end
261
+
262
+ def filter_key?(key)
263
+ params_filters.any? do |filter|
264
+ key.to_s.eql?(filter.to_s)
265
+ end
266
+ end
267
+
268
+ def find_session_data
269
+ self.session_data = args[:session_data] || args[:session] || rack_session || {}
270
+ self.session_data = session_data[:data] if session_data[:data]
271
+ end
272
+
273
+ # Private: Converts the mixed class instances and class names into just names
274
+ # TODO: move this into Configuration or another class
275
+ def ignored_class_names
276
+ ignore.collect do |string_or_class|
277
+ if string_or_class.respond_to?(:name)
278
+ string_or_class.name
279
+ else
280
+ string_or_class
281
+ end
282
+ end
283
+ end
284
+
285
+ def rack_env(method)
286
+ rack_request.send(method) if rack_request
287
+ end
288
+
289
+ def rack_request
290
+ @rack_request ||= if args[:rack_env]
291
+ ::Rack::Request.new(args[:rack_env])
292
+ end
293
+ end
294
+
295
+ def action_dispatch_params
296
+ args[:rack_env]['action_dispatch.request.parameters'] if args[:rack_env]
297
+ end
298
+
299
+ def rack_session
300
+ args[:rack_env]['rack.session'] if args[:rack_env]
301
+ end
302
+
303
+ def also_use_rack_params_filters
304
+ if args[:rack_env]
305
+ @params_filters ||= []
306
+ @params_filters += rack_request.env["action_dispatch.parameter_filter"] || []
307
+ end
308
+ end
309
+
310
+ def local_hostname
311
+ Socket.gethostname
312
+ end
313
+ end
314
+ end