airbrake 3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/.gitignore +18 -0
  2. data/.yardopts +3 -0
  3. data/CHANGELOG +441 -0
  4. data/Gemfile +3 -0
  5. data/INSTALL +25 -0
  6. data/MIT-LICENSE +22 -0
  7. data/README.md +431 -0
  8. data/README_FOR_HEROKU_ADDON.md +93 -0
  9. data/Rakefile +188 -0
  10. data/SUPPORTED_RAILS_VERSIONS +14 -0
  11. data/TESTING.md +26 -0
  12. data/airbrake.gemspec +33 -0
  13. data/features/metal.feature +23 -0
  14. data/features/rack.feature +27 -0
  15. data/features/rails.feature +254 -0
  16. data/features/rails_with_js_notifier.feature +78 -0
  17. data/features/rake.feature +23 -0
  18. data/features/sinatra.feature +33 -0
  19. data/features/step_definitions/airbrake_shim.rb.template +15 -0
  20. data/features/step_definitions/file_steps.rb +10 -0
  21. data/features/step_definitions/metal_steps.rb +23 -0
  22. data/features/step_definitions/rack_steps.rb +20 -0
  23. data/features/step_definitions/rails_application_steps.rb +401 -0
  24. data/features/step_definitions/rake_steps.rb +17 -0
  25. data/features/support/airbrake_shim.rb.template +15 -0
  26. data/features/support/env.rb +18 -0
  27. data/features/support/matchers.rb +35 -0
  28. data/features/support/rails.rb +181 -0
  29. data/features/support/rake/Rakefile +57 -0
  30. data/features/support/terminal.rb +103 -0
  31. data/features/user_informer.feature +63 -0
  32. data/generators/airbrake/airbrake_generator.rb +90 -0
  33. data/generators/airbrake/lib/insert_commands.rb +34 -0
  34. data/generators/airbrake/lib/rake_commands.rb +24 -0
  35. data/generators/airbrake/templates/airbrake_tasks.rake +25 -0
  36. data/generators/airbrake/templates/capistrano_hook.rb +6 -0
  37. data/generators/airbrake/templates/initializer.rb +6 -0
  38. data/install.rb +1 -0
  39. data/lib/airbrake.rb +150 -0
  40. data/lib/airbrake/backtrace.rb +100 -0
  41. data/lib/airbrake/capistrano.rb +21 -0
  42. data/lib/airbrake/configuration.rb +247 -0
  43. data/lib/airbrake/notice.rb +348 -0
  44. data/lib/airbrake/rack.rb +42 -0
  45. data/lib/airbrake/rails.rb +41 -0
  46. data/lib/airbrake/rails/action_controller_catcher.rb +30 -0
  47. data/lib/airbrake/rails/controller_methods.rb +68 -0
  48. data/lib/airbrake/rails/error_lookup.rb +33 -0
  49. data/lib/airbrake/rails/javascript_notifier.rb +42 -0
  50. data/lib/airbrake/rails3_tasks.rb +82 -0
  51. data/lib/airbrake/railtie.rb +33 -0
  52. data/lib/airbrake/rake_handler.rb +65 -0
  53. data/lib/airbrake/sender.rb +83 -0
  54. data/lib/airbrake/shared_tasks.rb +30 -0
  55. data/lib/airbrake/tasks.rb +83 -0
  56. data/lib/airbrake/user_informer.rb +25 -0
  57. data/lib/airbrake/version.rb +3 -0
  58. data/lib/airbrake_tasks.rb +50 -0
  59. data/lib/rails/generators/airbrake/airbrake_generator.rb +96 -0
  60. data/lib/templates/javascript_notifier.erb +13 -0
  61. data/lib/templates/rescue.erb +91 -0
  62. data/rails/init.rb +1 -0
  63. data/script/integration_test.rb +38 -0
  64. data/test/airbrake_2_2.xsd +78 -0
  65. data/test/airbrake_tasks_test.rb +163 -0
  66. data/test/backtrace_test.rb +163 -0
  67. data/test/catcher_test.rb +333 -0
  68. data/test/configuration_test.rb +216 -0
  69. data/test/helper.rb +251 -0
  70. data/test/javascript_notifier_test.rb +52 -0
  71. data/test/logger_test.rb +85 -0
  72. data/test/notice_test.rb +459 -0
  73. data/test/notifier_test.rb +235 -0
  74. data/test/rack_test.rb +58 -0
  75. data/test/rails_initializer_test.rb +36 -0
  76. data/test/recursion_test.rb +10 -0
  77. data/test/sender_test.rb +193 -0
  78. data/test/user_informer_test.rb +29 -0
  79. metadata +365 -0
@@ -0,0 +1,21 @@
1
+ # Defines deploy:notify_airbrake which will send information about the deploy to Airbrake.
2
+
3
+ Capistrano::Configuration.instance(:must_exist).load do
4
+ after "deploy", "deploy:notify_airbrake"
5
+ after "deploy:migrations", "deploy:notify_airbrake"
6
+
7
+ namespace :deploy do
8
+ desc "Notify Airbrake of the deployment"
9
+ task :notify_airbrake, :except => { :no_release => true } do
10
+ rails_env = fetch(:airbrake_env, fetch(:rails_env, "production"))
11
+ local_user = ENV['USER'] || ENV['USERNAME']
12
+ executable = RUBY_PLATFORM.downcase.include?('mswin') ? fetch(:rake, 'rake.bat') : fetch(:rake, 'rake')
13
+ notify_command = "#{executable} airbrake:deploy TO=#{rails_env} REVISION=#{current_revision} REPO=#{repository} USER=#{local_user}"
14
+ notify_command << " DRY_RUN=true" if dry_run
15
+ notify_command << " API_KEY=#{ENV['API_KEY']}" if ENV['API_KEY']
16
+ puts "Notifying Airbrake of Deploy (#{notify_command})"
17
+ `#{notify_command}`
18
+ puts "Airbrake Notification Complete."
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,247 @@
1
+ module Airbrake
2
+ # Used to set up and modify settings for the notifier.
3
+ class Configuration
4
+
5
+ OPTIONS = [:api_key, :backtrace_filters, :development_environments,
6
+ :development_lookup, :environment_name, :host,
7
+ :http_open_timeout, :http_read_timeout, :ignore, :ignore_by_filters,
8
+ :ignore_user_agent, :notifier_name, :notifier_url, :notifier_version,
9
+ :params_filters, :project_root, :port, :protocol, :proxy_host,
10
+ :proxy_pass, :proxy_port, :proxy_user, :secure, :framework,
11
+ :user_information, :rescue_rake_exceptions].freeze
12
+
13
+ # The API key for your project, found on the project edit form.
14
+ attr_accessor :api_key
15
+
16
+ # The host to connect to (defaults to airbrakeapp.com).
17
+ attr_accessor :host
18
+
19
+ # The port on which your Airbrake server runs (defaults to 443 for secure
20
+ # connections, 80 for insecure connections).
21
+ attr_accessor :port
22
+
23
+ # +true+ for https connections, +false+ for http connections.
24
+ attr_accessor :secure
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 Airbrake.
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
+ # +true+ if you want to check for production errors matching development errors, +false+ otherwise.
64
+ attr_accessor :development_lookup
65
+
66
+ # The name of the environment the application is running in
67
+ attr_accessor :environment_name
68
+
69
+ # The path to the project in which the error occurred, such as the RAILS_ROOT
70
+ attr_accessor :project_root
71
+
72
+ # The name of the notifier library being used to send notifications (such as "Airbrake Notifier")
73
+ attr_accessor :notifier_name
74
+
75
+ # The version of the notifier library being used to send notifications (such as "1.0.2")
76
+ attr_accessor :notifier_version
77
+
78
+ # The url of the notifier library being used to send notifications
79
+ attr_accessor :notifier_url
80
+
81
+ # The logger used by Airbrake
82
+ attr_accessor :logger
83
+
84
+ # The text that the placeholder is replaced with. {{error_id}} is the actual error number.
85
+ attr_accessor :user_information
86
+
87
+ # The framework Airbrake is configured to use
88
+ attr_accessor :framework
89
+
90
+ # Should Airbrake catch exceptions from Rake tasks?
91
+ # (boolean or nil; set to nil to catch exceptions when rake isn't running from a terminal; default is nil)
92
+ attr_accessor :rescue_rake_exceptions
93
+
94
+ DEFAULT_PARAMS_FILTERS = %w(password password_confirmation).freeze
95
+
96
+ DEFAULT_BACKTRACE_FILTERS = [
97
+ lambda { |line|
98
+ if defined?(Airbrake.configuration.project_root) && Airbrake.configuration.project_root.to_s != ''
99
+ line.sub(/#{Airbrake.configuration.project_root}/, "[PROJECT_ROOT]")
100
+ else
101
+ line
102
+ end
103
+ },
104
+ lambda { |line| line.gsub(/^\.\//, "") },
105
+ lambda { |line|
106
+ if defined?(Gem)
107
+ Gem.path.inject(line) do |line, path|
108
+ line.gsub(/#{path}/, "[GEM_ROOT]")
109
+ end
110
+ end
111
+ },
112
+ lambda { |line| line if line !~ %r{lib/airbrake} }
113
+ ].freeze
114
+
115
+ IGNORE_DEFAULT = ['ActiveRecord::RecordNotFound',
116
+ 'ActionController::RoutingError',
117
+ 'ActionController::InvalidAuthenticityToken',
118
+ 'CGI::Session::CookieStore::TamperedWithCookie',
119
+ 'ActionController::UnknownAction',
120
+ 'AbstractController::ActionNotFound']
121
+
122
+ alias_method :secure?, :secure
123
+
124
+ def initialize
125
+ @secure = false
126
+ @host = 'airbrakeapp.com'
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
+ @development_lookup = true
136
+ @notifier_name = 'Airbrake Notifier'
137
+ @notifier_version = VERSION
138
+ @notifier_url = 'http://airbrakeapp.com'
139
+ @framework = 'Standalone'
140
+ @user_information = 'Airbrake Error {{error_id}}'
141
+ @rescue_rake_exceptions = nil
142
+ end
143
+
144
+ # Takes a block and adds it to the list of backtrace filters. When the filters
145
+ # run, the block will be handed each line of the backtrace and can modify
146
+ # it as necessary.
147
+ #
148
+ # @example
149
+ # config.filter_bracktrace do |line|
150
+ # line.gsub(/^#{Rails.root}/, "[RAILS_ROOT]")
151
+ # end
152
+ #
153
+ # @param [Proc] block The new backtrace filter.
154
+ # @yieldparam [String] line A line in the backtrace.
155
+ def filter_backtrace(&block)
156
+ self.backtrace_filters << block
157
+ end
158
+
159
+ # Takes a block and adds it to the list of ignore filters.
160
+ # When the filters run, the block will be handed the exception.
161
+ # @example
162
+ # config.ignore_by_filter do |exception_data|
163
+ # true if exception_data[:error_class] == "RuntimeError"
164
+ # end
165
+ #
166
+ # @param [Proc] block The new ignore filter
167
+ # @yieldparam [Hash] data The exception data given to +Airbrake.notify+
168
+ # @yieldreturn [Boolean] If the block returns true the exception will be ignored, otherwise it will be processed by airbrake.
169
+ def ignore_by_filter(&block)
170
+ self.ignore_by_filters << block
171
+ end
172
+
173
+ # Overrides the list of default ignored errors.
174
+ #
175
+ # @param [Array<Exception>] names A list of exceptions to ignore.
176
+ def ignore_only=(names)
177
+ @ignore = [names].flatten
178
+ end
179
+
180
+ # Overrides the list of default ignored user agents
181
+ #
182
+ # @param [Array<String>] A list of user agents to ignore
183
+ def ignore_user_agent_only=(names)
184
+ @ignore_user_agent = [names].flatten
185
+ end
186
+
187
+ # Allows config options to be read like a hash
188
+ #
189
+ # @param [Symbol] option Key for a given attribute
190
+ def [](option)
191
+ send(option)
192
+ end
193
+
194
+ # Returns a hash of all configurable options
195
+ def to_hash
196
+ OPTIONS.inject({}) do |hash, option|
197
+ hash.merge(option.to_sym => send(option))
198
+ end
199
+ end
200
+
201
+ # Returns a hash of all configurable options merged with +hash+
202
+ #
203
+ # @param [Hash] hash A set of configuration options that will take precedence over the defaults
204
+ def merge(hash)
205
+ to_hash.merge(hash)
206
+ end
207
+
208
+ # Determines if the notifier will send notices.
209
+ # @return [Boolean] Returns +false+ if in a development environment, +true+ otherwise.
210
+ def public?
211
+ !development_environments.include?(environment_name)
212
+ end
213
+
214
+ def port
215
+ @port || default_port
216
+ end
217
+
218
+ def protocol
219
+ if secure?
220
+ 'https'
221
+ else
222
+ 'http'
223
+ end
224
+ end
225
+
226
+ def js_notifier=(*args)
227
+ warn '[AIRBRAKE] config.js_notifier has been deprecated and has no effect. You should use <%= airbrake_javascript_notifier %> directly at the top of your layouts. Be sure to place it before all other javascript.'
228
+ end
229
+
230
+ def environment_filters
231
+ warn 'config.environment_filters has been deprecated and has no effect.'
232
+ []
233
+ end
234
+
235
+ private
236
+
237
+ def default_port
238
+ if secure?
239
+ 443
240
+ else
241
+ 80
242
+ end
243
+ end
244
+
245
+ end
246
+
247
+ end
@@ -0,0 +1,348 @@
1
+ require 'builder'
2
+ require 'socket'
3
+
4
+ module Airbrake
5
+ class Notice
6
+
7
+ # The exception that caused this notice, if any
8
+ attr_reader :exception
9
+
10
+ # The API key for the project to which this notice should be sent
11
+ attr_reader :api_key
12
+
13
+ # The backtrace from the given exception or hash.
14
+ attr_reader :backtrace
15
+
16
+ # The name of the class of error (such as RuntimeError)
17
+ attr_reader :error_class
18
+
19
+ # The name of the server environment (such as "production")
20
+ attr_reader :environment_name
21
+
22
+ # CGI variables such as HTTP_METHOD
23
+ attr_reader :cgi_data
24
+
25
+ # The message from the exception, or a general description of the error
26
+ attr_reader :error_message
27
+
28
+ # See Configuration#backtrace_filters
29
+ attr_reader :backtrace_filters
30
+
31
+ # See Configuration#params_filters
32
+ attr_reader :params_filters
33
+
34
+ # A hash of parameters from the query string or post body.
35
+ attr_reader :parameters
36
+ alias_method :params, :parameters
37
+
38
+ # The component (if any) which was used in this request (usually the controller)
39
+ attr_reader :component
40
+ alias_method :controller, :component
41
+
42
+ # The action (if any) that was called in this request
43
+ attr_reader :action
44
+
45
+ # A hash of session data from the request
46
+ attr_reader :session_data
47
+
48
+ # The path to the project that caused the error (usually RAILS_ROOT)
49
+ attr_reader :project_root
50
+
51
+ # The URL at which the error occurred (if any)
52
+ attr_reader :url
53
+
54
+ # See Configuration#ignore
55
+ attr_reader :ignore
56
+
57
+ # See Configuration#ignore_by_filters
58
+ attr_reader :ignore_by_filters
59
+
60
+ # The name of the notifier library sending this notice, such as "Airbrake Notifier"
61
+ attr_reader :notifier_name
62
+
63
+ # The version number of the notifier library sending this notice, such as "2.1.3"
64
+ attr_reader :notifier_version
65
+
66
+ # A URL for more information about the notifier library sending this notice
67
+ attr_reader :notifier_url
68
+
69
+ # The host name where this error occurred (if any)
70
+ attr_reader :hostname
71
+
72
+ def initialize(args)
73
+ self.args = args
74
+ self.exception = args[:exception]
75
+ self.api_key = args[:api_key]
76
+ self.project_root = args[:project_root]
77
+ self.url = args[:url] || rack_env(:url)
78
+
79
+ self.notifier_name = args[:notifier_name]
80
+ self.notifier_version = args[:notifier_version]
81
+ self.notifier_url = args[:notifier_url]
82
+
83
+ self.ignore = args[:ignore] || []
84
+ self.ignore_by_filters = args[:ignore_by_filters] || []
85
+ self.backtrace_filters = args[:backtrace_filters] || []
86
+ self.params_filters = args[:params_filters] || []
87
+ self.parameters = args[:parameters] ||
88
+ action_dispatch_params ||
89
+ rack_env(:params) ||
90
+ {}
91
+ self.component = args[:component] || args[:controller] || parameters['controller']
92
+ self.action = args[:action] || parameters['action']
93
+
94
+ self.environment_name = args[:environment_name]
95
+ self.cgi_data = args[:cgi_data] || args[:rack_env]
96
+ self.backtrace = Backtrace.parse(exception_attribute(:backtrace, caller), :filters => self.backtrace_filters)
97
+ self.error_class = exception_attribute(:error_class) {|exception| exception.class.name }
98
+ self.error_message = exception_attribute(:error_message, 'Notification') do |exception|
99
+ "#{exception.class.name}: #{exception.message}"
100
+ end
101
+
102
+ self.hostname = local_hostname
103
+
104
+ also_use_rack_params_filters
105
+ find_session_data
106
+ clean_params
107
+ clean_rack_request_data
108
+ end
109
+
110
+ # Converts the given notice to XML
111
+ def to_xml
112
+ builder = Builder::XmlMarkup.new
113
+ builder.instruct!
114
+ xml = builder.notice(:version => Airbrake::API_VERSION) do |notice|
115
+ notice.tag!("api-key", api_key)
116
+ notice.notifier do |notifier|
117
+ notifier.name(notifier_name)
118
+ notifier.version(notifier_version)
119
+ notifier.url(notifier_url)
120
+ end
121
+ notice.error do |error|
122
+ error.tag!('class', error_class)
123
+ error.message(error_message)
124
+ error.backtrace do |backtrace|
125
+ self.backtrace.lines.each do |line|
126
+ backtrace.line(:number => line.number,
127
+ :file => line.file,
128
+ :method => line.method)
129
+ end
130
+ end
131
+ end
132
+ if url ||
133
+ controller ||
134
+ action ||
135
+ !parameters.blank? ||
136
+ !cgi_data.blank? ||
137
+ !session_data.blank?
138
+ notice.request do |request|
139
+ request.url(url)
140
+ request.component(controller)
141
+ request.action(action)
142
+ unless parameters.nil? || parameters.empty?
143
+ request.params do |params|
144
+ xml_vars_for(params, parameters)
145
+ end
146
+ end
147
+ unless session_data.nil? || session_data.empty?
148
+ request.session do |session|
149
+ xml_vars_for(session, session_data)
150
+ end
151
+ end
152
+ unless cgi_data.nil? || cgi_data.empty?
153
+ request.tag!("cgi-data") do |cgi_datum|
154
+ xml_vars_for(cgi_datum, cgi_data)
155
+ end
156
+ end
157
+ end
158
+ end
159
+ notice.tag!("server-environment") do |env|
160
+ env.tag!("project-root", project_root)
161
+ env.tag!("environment-name", environment_name)
162
+ env.tag!("hostname", hostname)
163
+ end
164
+ end
165
+ xml.to_s
166
+ end
167
+
168
+ # Determines if this notice should be ignored
169
+ def ignore?
170
+ ignored_class_names.include?(error_class) ||
171
+ ignore_by_filters.any? {|filter| filter.call(self) }
172
+ end
173
+
174
+ # Allows properties to be accessed using a hash-like syntax
175
+ #
176
+ # @example
177
+ # notice[:error_message]
178
+ # @param [String] method The given key for an attribute
179
+ # @return The attribute value, or self if given +:request+
180
+ def [](method)
181
+ case method
182
+ when :request
183
+ self
184
+ else
185
+ send(method)
186
+ end
187
+ end
188
+
189
+ private
190
+
191
+ attr_writer :exception, :api_key, :backtrace, :error_class, :error_message,
192
+ :backtrace_filters, :parameters, :params_filters,
193
+ :environment_filters, :session_data, :project_root, :url, :ignore,
194
+ :ignore_by_filters, :notifier_name, :notifier_url, :notifier_version,
195
+ :component, :action, :cgi_data, :environment_name, :hostname
196
+
197
+ # Arguments given in the initializer
198
+ attr_accessor :args
199
+
200
+ # Gets a property named +attribute+ of an exception, either from an actual
201
+ # exception or a hash.
202
+ #
203
+ # If an exception is available, #from_exception will be used. Otherwise,
204
+ # a key named +attribute+ will be used from the #args.
205
+ #
206
+ # If no exception or hash key is available, +default+ will be used.
207
+ def exception_attribute(attribute, default = nil, &block)
208
+ (exception && from_exception(attribute, &block)) || args[attribute] || default
209
+ end
210
+
211
+ # Gets a property named +attribute+ from an exception.
212
+ #
213
+ # If a block is given, it will be used when getting the property from an
214
+ # exception. The block should accept and exception and return the value for
215
+ # the property.
216
+ #
217
+ # If no block is given, a method with the same name as +attribute+ will be
218
+ # invoked for the value.
219
+ def from_exception(attribute)
220
+ if block_given?
221
+ yield(exception)
222
+ else
223
+ exception.send(attribute)
224
+ end
225
+ end
226
+
227
+ # Removes non-serializable data from the given attribute.
228
+ # See #clean_unserializable_data
229
+ def clean_unserializable_data_from(attribute)
230
+ self.send(:"#{attribute}=", clean_unserializable_data(send(attribute)))
231
+ end
232
+
233
+ # Removes non-serializable data. Allowed data types are strings, arrays,
234
+ # and hashes. All other types are converted to strings.
235
+ # TODO: move this onto Hash
236
+ def clean_unserializable_data(data, stack = [])
237
+ return "[possible infinite recursion halted]" if stack.any?{|item| item == data.object_id }
238
+
239
+ if data.respond_to?(:to_hash)
240
+ data.to_hash.inject({}) do |result, (key, value)|
241
+ result.merge(key => clean_unserializable_data(value, stack + [data.object_id]))
242
+ end
243
+ elsif data.respond_to?(:to_ary)
244
+ data.collect do |value|
245
+ clean_unserializable_data(value, stack + [data.object_id])
246
+ end
247
+ else
248
+ data.to_s
249
+ end
250
+ end
251
+
252
+ # Replaces the contents of params that match params_filters.
253
+ # TODO: extract this to a different class
254
+ def clean_params
255
+ clean_unserializable_data_from(:parameters)
256
+ filter(parameters)
257
+ if cgi_data
258
+ clean_unserializable_data_from(:cgi_data)
259
+ filter(cgi_data)
260
+ end
261
+ if session_data
262
+ clean_unserializable_data_from(:session_data)
263
+ filter(session_data)
264
+ end
265
+ end
266
+
267
+ def clean_rack_request_data
268
+ if cgi_data
269
+ cgi_data.delete("rack.request.form_vars")
270
+ end
271
+ end
272
+
273
+ def filter(hash)
274
+ if params_filters
275
+ hash.each do |key, value|
276
+ if filter_key?(key)
277
+ hash[key] = "[FILTERED]"
278
+ elsif value.respond_to?(:to_hash)
279
+ filter(hash[key])
280
+ end
281
+ end
282
+ end
283
+ end
284
+
285
+ def filter_key?(key)
286
+ params_filters.any? do |filter|
287
+ key.to_s.include?(filter.to_s)
288
+ end
289
+ end
290
+
291
+ def find_session_data
292
+ self.session_data = args[:session_data] || args[:session] || rack_session || {}
293
+ self.session_data = session_data[:data] if session_data[:data]
294
+ end
295
+
296
+ # Converts the mixed class instances and class names into just names
297
+ # TODO: move this into Configuration or another class
298
+ def ignored_class_names
299
+ ignore.collect do |string_or_class|
300
+ if string_or_class.respond_to?(:name)
301
+ string_or_class.name
302
+ else
303
+ string_or_class
304
+ end
305
+ end
306
+ end
307
+
308
+ def xml_vars_for(builder, hash)
309
+ hash.each do |key, value|
310
+ if value.respond_to?(:to_hash)
311
+ builder.var(:key => key){|b| xml_vars_for(b, value.to_hash) }
312
+ else
313
+ builder.var(value.to_s, :key => key)
314
+ end
315
+ end
316
+ end
317
+
318
+ def rack_env(method)
319
+ rack_request.send(method) if rack_request
320
+ end
321
+
322
+ def rack_request
323
+ @rack_request ||= if args[:rack_env]
324
+ ::Rack::Request.new(args[:rack_env])
325
+ end
326
+ end
327
+
328
+ def action_dispatch_params
329
+ args[:rack_env]['action_dispatch.request.parameters'] if args[:rack_env]
330
+ end
331
+
332
+ def rack_session
333
+ args[:rack_env]['rack.session'] if args[:rack_env]
334
+ end
335
+
336
+ def also_use_rack_params_filters
337
+ if args[:rack_env]
338
+ @params_filters ||= []
339
+ @params_filters += rack_request.env["action_dispatch.parameter_filter"] || []
340
+ end
341
+ end
342
+
343
+ def local_hostname
344
+ Socket.gethostname
345
+ end
346
+
347
+ end
348
+ end