riscfuture-hoptoad_notifier 2.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. data/CHANGELOG +218 -0
  2. data/INSTALL +25 -0
  3. data/MIT-LICENSE +22 -0
  4. data/README.rdoc +394 -0
  5. data/Rakefile +217 -0
  6. data/SUPPORTED_RAILS_VERSIONS +10 -0
  7. data/TESTING.rdoc +8 -0
  8. data/generators/hoptoad/hoptoad_generator.rb +63 -0
  9. data/generators/hoptoad/lib/insert_commands.rb +34 -0
  10. data/generators/hoptoad/lib/rake_commands.rb +24 -0
  11. data/generators/hoptoad/templates/capistrano_hook.rb +6 -0
  12. data/generators/hoptoad/templates/hoptoad_notifier_tasks.rake +25 -0
  13. data/generators/hoptoad/templates/initializer.rb +6 -0
  14. data/lib/hoptoad_notifier.rb +148 -0
  15. data/lib/hoptoad_notifier/backtrace.rb +99 -0
  16. data/lib/hoptoad_notifier/capistrano.rb +20 -0
  17. data/lib/hoptoad_notifier/configuration.rb +236 -0
  18. data/lib/hoptoad_notifier/notice.rb +334 -0
  19. data/lib/hoptoad_notifier/rack.rb +40 -0
  20. data/lib/hoptoad_notifier/rails.rb +39 -0
  21. data/lib/hoptoad_notifier/rails/action_controller_catcher.rb +29 -0
  22. data/lib/hoptoad_notifier/rails/controller_methods.rb +60 -0
  23. data/lib/hoptoad_notifier/rails/error_lookup.rb +33 -0
  24. data/lib/hoptoad_notifier/rails/javascript_notifier.rb +43 -0
  25. data/lib/hoptoad_notifier/rails3_tasks.rb +91 -0
  26. data/lib/hoptoad_notifier/railtie.rb +29 -0
  27. data/lib/hoptoad_notifier/sender.rb +63 -0
  28. data/lib/hoptoad_notifier/tasks.rb +97 -0
  29. data/lib/hoptoad_notifier/version.rb +3 -0
  30. data/lib/hoptoad_tasks.rb +44 -0
  31. data/lib/rails/generators/hoptoad/hoptoad_generator.rb +69 -0
  32. data/lib/templates/javascript_notifier.erb +6 -0
  33. data/lib/templates/rescue.erb +91 -0
  34. data/rails/init.rb +1 -0
  35. data/script/integration_test.rb +38 -0
  36. data/test/backtrace_test.rb +118 -0
  37. data/test/catcher_test.rb +329 -0
  38. data/test/configuration_test.rb +209 -0
  39. data/test/helper.rb +239 -0
  40. data/test/hoptoad_tasks_test.rb +152 -0
  41. data/test/logger_test.rb +85 -0
  42. data/test/notice_test.rb +457 -0
  43. data/test/notifier_test.rb +222 -0
  44. data/test/rack_test.rb +58 -0
  45. data/test/rails_initializer_test.rb +36 -0
  46. data/test/sender_test.rb +123 -0
  47. metadata +197 -0
@@ -0,0 +1,99 @@
1
+ module HoptoadNotifier
2
+ # Front end to parsing the backtrace for each notice
3
+ class Backtrace
4
+
5
+ # Handles backtrace parsing line by line
6
+ class Line
7
+
8
+ INPUT_FORMAT = %r{^([^:]+):(\d+)(?::in `([^']+)')?$}.freeze
9
+
10
+ # The file portion of the line (such as app/models/user.rb)
11
+ attr_reader :file
12
+
13
+ # The line number portion of the line
14
+ attr_reader :number
15
+
16
+ # The method of the line (such as index)
17
+ attr_reader :method
18
+
19
+ # Parses a single line of a given backtrace
20
+ # @param [String] unparsed_line The raw line from +caller+ or some backtrace
21
+ # @return [Line] The parsed backtrace line
22
+ def self.parse(unparsed_line)
23
+ _, file, number, method = unparsed_line.match(INPUT_FORMAT).to_a
24
+ new(file, number, method)
25
+ end
26
+
27
+ def initialize(file, number, method)
28
+ self.file = file
29
+ self.number = number
30
+ self.method = method
31
+ end
32
+
33
+ # Reconstructs the line in a readable fashion
34
+ def to_s
35
+ "#{file}:#{number}:in `#{method}'"
36
+ end
37
+
38
+ def ==(other)
39
+ to_s == other.to_s
40
+ end
41
+
42
+ def inspect
43
+ "<Line:#{to_s}>"
44
+ end
45
+
46
+ private
47
+
48
+ attr_writer :file, :number, :method
49
+ end
50
+
51
+ # holder for an Array of Backtrace::Line instances
52
+ attr_reader :lines
53
+
54
+ def self.parse(ruby_backtrace, opts = {})
55
+ ruby_lines = split_multiline_backtrace(ruby_backtrace)
56
+
57
+ filters = opts[:filters] || []
58
+ filtered_lines = ruby_lines.to_a.map do |line|
59
+ filters.inject(line) do |line, proc|
60
+ proc.call(line)
61
+ end
62
+ end.compact
63
+
64
+ lines = filtered_lines.collect do |unparsed_line|
65
+ Line.parse(unparsed_line)
66
+ end
67
+
68
+ instance = new(lines)
69
+ end
70
+
71
+ def initialize(lines)
72
+ self.lines = lines
73
+ end
74
+
75
+ def inspect
76
+ "<Backtrace: " + lines.collect { |line| line.inspect }.join(", ") + ">"
77
+ end
78
+
79
+ def ==(other)
80
+ if other.respond_to?(:lines)
81
+ lines == other.lines
82
+ else
83
+ false
84
+ end
85
+ end
86
+
87
+ private
88
+
89
+ attr_writer :lines
90
+
91
+ def self.split_multiline_backtrace(backtrace)
92
+ if backtrace.to_a.size == 1
93
+ backtrace.to_a.first.split(/\n\s*/)
94
+ else
95
+ backtrace
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,20 @@
1
+ # Defines deploy:notify_hoptoad which will send information about the deploy to Hoptoad.
2
+
3
+ Capistrano::Configuration.instance(:must_exist).load do
4
+ after "deploy", "deploy:notify_hoptoad"
5
+ after "deploy:migrations", "deploy:notify_hoptoad"
6
+
7
+ namespace :deploy do
8
+ desc "Notify Hoptoad of the deployment"
9
+ task :notify_hoptoad, :except => { :no_release => true } do
10
+ rails_env = fetch(:hoptoad_env, fetch(:rails_env, "production"))
11
+ local_user = ENV['USER'] || ENV['USERNAME']
12
+ executable = RUBY_PLATFORM.downcase.include?('mswin') ? 'rake.bat' : 'rake'
13
+ notify_command = "#{executable} hoptoad:deploy TO=#{rails_env} REVISION=#{current_revision} REPO=#{repository} USER=#{local_user}"
14
+ notify_command << " API_KEY=#{ENV['API_KEY']}" if ENV['API_KEY']
15
+ puts "Notifying Hoptoad of Deploy (#{notify_command})"
16
+ `#{notify_command}`
17
+ puts "Hoptoad Notification Complete."
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,236 @@
1
+ module HoptoadNotifier
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, :js_notifier].freeze
11
+
12
+ # The API key for your project, found on the project edit form.
13
+ attr_accessor :api_key
14
+
15
+ # The host to connect to (defaults to hoptoadapp.com).
16
+ attr_accessor :host
17
+
18
+ # The port on which your Hoptoad server runs (defaults to 443 for secure
19
+ # connections, 80 for insecure connections).
20
+ attr_accessor :port
21
+
22
+ # +true+ for https connections, +false+ for http connections.
23
+ attr_accessor :secure
24
+
25
+ # The HTTP open timeout in seconds (defaults to 2).
26
+ attr_accessor :http_open_timeout
27
+
28
+ # The HTTP read timeout in seconds (defaults to 5).
29
+ attr_accessor :http_read_timeout
30
+
31
+ # The hostname of your proxy server (if using a proxy)
32
+ attr_accessor :proxy_host
33
+
34
+ # The port of your proxy server (if using a proxy)
35
+ attr_accessor :proxy_port
36
+
37
+ # The username to use when logging into your proxy server (if using a proxy)
38
+ attr_accessor :proxy_user
39
+
40
+ # The password to use when logging into your proxy server (if using a proxy)
41
+ attr_accessor :proxy_pass
42
+
43
+ # A list of parameters that should be filtered out of what is sent to Hoptoad.
44
+ # By default, all "password" attributes will have their contents replaced.
45
+ attr_reader :params_filters
46
+
47
+ # A list of filters for cleaning and pruning the backtrace. See #filter_backtrace.
48
+ attr_reader :backtrace_filters
49
+
50
+ # A list of filters for ignoring exceptions. See #ignore_by_filter.
51
+ attr_reader :ignore_by_filters
52
+
53
+ # A list of exception classes to ignore. The array can be appended to.
54
+ attr_reader :ignore
55
+
56
+ # A list of user agents that are being ignored. The array can be appended to.
57
+ attr_reader :ignore_user_agent
58
+
59
+ # A list of environments in which notifications should not be sent.
60
+ attr_accessor :development_environments
61
+
62
+ # +true+ if you want to check for production errors matching development errors, +false+ otherwise.
63
+ attr_accessor :development_lookup
64
+
65
+ # +true+ if you want to enable the JavaScript notifier in production environments
66
+ attr_accessor :js_notifier
67
+
68
+ # The name of the environment the application is running in
69
+ attr_accessor :environment_name
70
+
71
+ # The path to the project in which the error occurred, such as the RAILS_ROOT
72
+ attr_accessor :project_root
73
+
74
+ # The name of the notifier library being used to send notifications (such as "Hoptoad Notifier")
75
+ attr_accessor :notifier_name
76
+
77
+ # The version of the notifier library being used to send notifications (such as "1.0.2")
78
+ attr_accessor :notifier_version
79
+
80
+ # The url of the notifier library being used to send notifications
81
+ attr_accessor :notifier_url
82
+
83
+ # The logger used by HoptoadNotifier
84
+ attr_accessor :logger
85
+
86
+ # The framework HoptoadNotifier is configured to use
87
+ attr_accessor :framework
88
+
89
+ DEFAULT_PARAMS_FILTERS = %w(password password_confirmation).freeze
90
+
91
+ DEFAULT_BACKTRACE_FILTERS = [
92
+ lambda { |line|
93
+ if defined?(HoptoadNotifier.configuration.project_root) && HoptoadNotifier.configuration.project_root.to_s != ''
94
+ line.gsub(/#{HoptoadNotifier.configuration.project_root}/, "[PROJECT_ROOT]")
95
+ else
96
+ line
97
+ end
98
+ },
99
+ lambda { |line| line.gsub(/^\.\//, "") },
100
+ lambda { |line|
101
+ if defined?(Gem)
102
+ Gem.path.inject(line) do |line, path|
103
+ line.gsub(/#{path}/, "[GEM_ROOT]")
104
+ end
105
+ end
106
+ },
107
+ lambda { |line| line if line !~ %r{lib/hoptoad_notifier} }
108
+ ].freeze
109
+
110
+ IGNORE_DEFAULT = ['ActiveRecord::RecordNotFound',
111
+ 'ActionController::RoutingError',
112
+ 'ActionController::InvalidAuthenticityToken',
113
+ 'CGI::Session::CookieStore::TamperedWithCookie',
114
+ 'ActionController::UnknownAction']
115
+
116
+ alias_method :secure?, :secure
117
+
118
+ def initialize
119
+ @secure = false
120
+ @host = 'hoptoadapp.com'
121
+ @http_open_timeout = 2
122
+ @http_read_timeout = 5
123
+ @params_filters = DEFAULT_PARAMS_FILTERS.dup
124
+ @backtrace_filters = DEFAULT_BACKTRACE_FILTERS.dup
125
+ @ignore_by_filters = []
126
+ @ignore = IGNORE_DEFAULT.dup
127
+ @ignore_user_agent = []
128
+ @development_environments = %w(development test cucumber)
129
+ @development_lookup = true
130
+ @js_notifier = false
131
+ @notifier_name = 'Hoptoad Notifier'
132
+ @notifier_version = VERSION
133
+ @notifier_url = 'http://hoptoadapp.com'
134
+ @framework = 'Standalone'
135
+ end
136
+
137
+ # Takes a block and adds it to the list of backtrace filters. When the filters
138
+ # run, the block will be handed each line of the backtrace and can modify
139
+ # it as necessary.
140
+ #
141
+ # @example
142
+ # config.filter_bracktrace do |line|
143
+ # line.gsub(/^#{Rails.root}/, "[RAILS_ROOT]")
144
+ # end
145
+ #
146
+ # @param [Proc] block The new backtrace filter.
147
+ # @yieldparam [String] line A line in the backtrace.
148
+ def filter_backtrace(&block)
149
+ self.backtrace_filters << block
150
+ end
151
+
152
+ # Takes a block and adds it to the list of ignore filters.
153
+ # When the filters run, the block will be handed the exception.
154
+ # @example
155
+ # config.ignore_by_filter do |exception_data|
156
+ # true if exception_data[:error_class] == "RuntimeError"
157
+ # end
158
+ #
159
+ # @param [Proc] block The new ignore filter
160
+ # @yieldparam [Hash] data The exception data given to +HoptoadNotifier.notify+
161
+ # @yieldreturn [Boolean] If the block returns true the exception will be ignored, otherwise it will be processed by hoptoad.
162
+ def ignore_by_filter(&block)
163
+ self.ignore_by_filters << block
164
+ end
165
+
166
+ # Overrides the list of default ignored errors.
167
+ #
168
+ # @param [Array<Exception>] names A list of exceptions to ignore.
169
+ def ignore_only=(names)
170
+ @ignore = [names].flatten
171
+ end
172
+
173
+ # Overrides the list of default ignored user agents
174
+ #
175
+ # @param [Array<String>] A list of user agents to ignore
176
+ def ignore_user_agent_only=(names)
177
+ @ignore_user_agent = [names].flatten
178
+ end
179
+
180
+ # Allows config options to be read like a hash
181
+ #
182
+ # @param [Symbol] option Key for a given attribute
183
+ def [](option)
184
+ send(option)
185
+ end
186
+
187
+ # Returns a hash of all configurable options
188
+ def to_hash
189
+ OPTIONS.inject({}) do |hash, option|
190
+ hash.merge(option.to_sym => send(option))
191
+ end
192
+ end
193
+
194
+ # Returns a hash of all configurable options merged with +hash+
195
+ #
196
+ # @param [Hash] hash A set of configuration options that will take precedence over the defaults
197
+ def merge(hash)
198
+ to_hash.merge(hash)
199
+ end
200
+
201
+ # Determines if the notifier will send notices.
202
+ # @return [Boolean] Returns +false+ if in a development environment, +true+ otherwise.
203
+ def public?
204
+ !development_environments.include?(environment_name)
205
+ end
206
+
207
+ def port
208
+ @port || default_port
209
+ end
210
+
211
+ def protocol
212
+ if secure?
213
+ 'https'
214
+ else
215
+ 'http'
216
+ end
217
+ end
218
+
219
+ def environment_filters
220
+ warn 'config.environment_filters has been deprecated and has no effect.'
221
+ []
222
+ end
223
+
224
+ private
225
+
226
+ def default_port
227
+ if secure?
228
+ 443
229
+ else
230
+ 80
231
+ end
232
+ end
233
+
234
+ end
235
+
236
+ end
@@ -0,0 +1,334 @@
1
+ require 'builder'
2
+
3
+ module HoptoadNotifier
4
+ class Notice
5
+
6
+ # The exception that caused this notice, if any
7
+ attr_reader :exception
8
+
9
+ # The API key for the project to which this notice should be sent
10
+ attr_reader :api_key
11
+
12
+ # The backtrace from the given exception or hash.
13
+ attr_reader :backtrace
14
+
15
+ # The name of the class of error (such as RuntimeError)
16
+ attr_reader :error_class
17
+
18
+ # The name of the server environment (such as "production")
19
+ attr_reader :environment_name
20
+
21
+ # CGI variables such as HTTP_METHOD
22
+ attr_reader :cgi_data
23
+
24
+ # The message from the exception, or a general description of the error
25
+ attr_reader :error_message
26
+
27
+ # See Configuration#backtrace_filters
28
+ attr_reader :backtrace_filters
29
+
30
+ # See Configuration#params_filters
31
+ attr_reader :params_filters
32
+
33
+ # A hash of parameters from the query string or post body.
34
+ attr_reader :parameters
35
+ alias_method :params, :parameters
36
+
37
+ # The component (if any) which was used in this request (usually the controller)
38
+ attr_reader :component
39
+ alias_method :controller, :component
40
+
41
+ # The action (if any) that was called in this request
42
+ attr_reader :action
43
+
44
+ # A hash of session data from the request
45
+ attr_reader :session_data
46
+
47
+ # The path to the project that caused the error (usually RAILS_ROOT)
48
+ attr_reader :project_root
49
+
50
+ # The URL at which the error occurred (if any)
51
+ attr_reader :url
52
+
53
+ # See Configuration#ignore
54
+ attr_reader :ignore
55
+
56
+ # See Configuration#ignore_by_filters
57
+ attr_reader :ignore_by_filters
58
+
59
+ # The name of the notifier library sending this notice, such as "Hoptoad Notifier"
60
+ attr_reader :notifier_name
61
+
62
+ # The version number of the notifier library sending this notice, such as "2.1.3"
63
+ attr_reader :notifier_version
64
+
65
+ # A URL for more information about the notifier library sending this notice
66
+ attr_reader :notifier_url
67
+
68
+ def initialize(args)
69
+ self.args = args
70
+ self.exception = args[:exception]
71
+ self.api_key = args[:api_key]
72
+ self.project_root = args[:project_root]
73
+ self.url = args[:url] || rack_env(:url)
74
+
75
+ self.notifier_name = args[:notifier_name]
76
+ self.notifier_version = args[:notifier_version]
77
+ self.notifier_url = args[:notifier_url]
78
+
79
+ self.ignore = args[:ignore] || []
80
+ self.ignore_by_filters = args[:ignore_by_filters] || []
81
+ self.backtrace_filters = args[:backtrace_filters] || []
82
+ self.params_filters = args[:params_filters] || []
83
+ self.parameters = args[:parameters] ||
84
+ action_dispatch_params ||
85
+ rack_env(:params) ||
86
+ {}
87
+ self.component = args[:component] || args[:controller] || parameters['controller']
88
+ self.action = args[:action] || parameters['action']
89
+
90
+ self.environment_name = args[:environment_name]
91
+ self.cgi_data = args[:cgi_data] || args[:rack_env]
92
+ self.backtrace = Backtrace.parse(exception_attribute(:backtrace, caller), :filters => self.backtrace_filters)
93
+ self.error_class = exception_attribute(:error_class) {|exception| exception.class.name }
94
+ self.error_message = exception_attribute(:error_message, 'Notification') do |exception|
95
+ "#{exception.class.name}: #{exception.message}"
96
+ end
97
+
98
+ also_use_rack_params_filters
99
+ find_session_data
100
+ clean_params
101
+ clean_rack_request_data
102
+ end
103
+
104
+ # Converts the given notice to XML
105
+ def to_xml
106
+ builder = Builder::XmlMarkup.new
107
+ builder.instruct!
108
+ xml = builder.notice(:version => HoptoadNotifier::API_VERSION) do |notice|
109
+ notice.tag!("api-key", api_key)
110
+ notice.notifier do |notifier|
111
+ notifier.name(notifier_name)
112
+ notifier.version(notifier_version)
113
+ notifier.url(notifier_url)
114
+ end
115
+ notice.error do |error|
116
+ error.tag!('class', error_class)
117
+ error.message(error_message)
118
+ error.backtrace do |backtrace|
119
+ self.backtrace.lines.each do |line|
120
+ backtrace.line(:number => line.number,
121
+ :file => line.file,
122
+ :method => line.method)
123
+ end
124
+ end
125
+ end
126
+ if url ||
127
+ controller ||
128
+ action ||
129
+ !parameters.blank? ||
130
+ !cgi_data.blank? ||
131
+ !session_data.blank?
132
+ notice.request do |request|
133
+ request.url(url)
134
+ request.component(controller)
135
+ request.action(action)
136
+ unless parameters.nil? || parameters.empty?
137
+ request.params do |params|
138
+ xml_vars_for(params, parameters)
139
+ end
140
+ end
141
+ unless session_data.nil? || session_data.empty?
142
+ request.session do |session|
143
+ xml_vars_for(session, session_data)
144
+ end
145
+ end
146
+ unless cgi_data.nil? || cgi_data.empty?
147
+ request.tag!("cgi-data") do |cgi_datum|
148
+ xml_vars_for(cgi_datum, cgi_data)
149
+ end
150
+ end
151
+ end
152
+ end
153
+ notice.tag!("server-environment") do |env|
154
+ env.tag!("project-root", project_root)
155
+ env.tag!("environment-name", environment_name)
156
+ end
157
+ end
158
+ xml.to_s
159
+ end
160
+
161
+ # Determines if this notice should be ignored
162
+ def ignore?
163
+ ignored_class_names.include?(error_class) ||
164
+ ignore_by_filters.any? {|filter| filter.call(self) }
165
+ end
166
+
167
+ # Allows properties to be accessed using a hash-like syntax
168
+ #
169
+ # @example
170
+ # notice[:error_message]
171
+ # @param [String] method The given key for an attribute
172
+ # @return The attribute value, or self if given +:request+
173
+ def [](method)
174
+ case method
175
+ when :request
176
+ self
177
+ else
178
+ send(method)
179
+ end
180
+ end
181
+
182
+ private
183
+
184
+ attr_writer :exception, :api_key, :backtrace, :error_class, :error_message,
185
+ :backtrace_filters, :parameters, :params_filters,
186
+ :environment_filters, :session_data, :project_root, :url, :ignore,
187
+ :ignore_by_filters, :notifier_name, :notifier_url, :notifier_version,
188
+ :component, :action, :cgi_data, :environment_name
189
+
190
+ # Arguments given in the initializer
191
+ attr_accessor :args
192
+
193
+ # Gets a property named +attribute+ of an exception, either from an actual
194
+ # exception or a hash.
195
+ #
196
+ # If an exception is available, #from_exception will be used. Otherwise,
197
+ # a key named +attribute+ will be used from the #args.
198
+ #
199
+ # If no exception or hash key is available, +default+ will be used.
200
+ def exception_attribute(attribute, default = nil, &block)
201
+ (exception && from_exception(attribute, &block)) || args[attribute] || default
202
+ end
203
+
204
+ # Gets a property named +attribute+ from an exception.
205
+ #
206
+ # If a block is given, it will be used when getting the property from an
207
+ # exception. The block should accept and exception and return the value for
208
+ # the property.
209
+ #
210
+ # If no block is given, a method with the same name as +attribute+ will be
211
+ # invoked for the value.
212
+ def from_exception(attribute)
213
+ if block_given?
214
+ yield(exception)
215
+ else
216
+ exception.send(attribute)
217
+ end
218
+ end
219
+
220
+ # Removes non-serializable data from the given attribute.
221
+ # See #clean_unserializable_data
222
+ def clean_unserializable_data_from(attribute)
223
+ self.send(:"#{attribute}=", clean_unserializable_data(send(attribute)))
224
+ end
225
+
226
+ # Removes non-serializable data. Allowed data types are strings, arrays,
227
+ # and hashes. All other types are converted to strings.
228
+ # TODO: move this onto Hash
229
+ def clean_unserializable_data(data)
230
+ if data.respond_to?(:to_hash)
231
+ data.to_hash.inject({}) do |result, (key, value)|
232
+ result.merge(key => clean_unserializable_data(value))
233
+ end
234
+ elsif data.respond_to?(:to_ary)
235
+ data.collect do |value|
236
+ clean_unserializable_data(value)
237
+ end
238
+ else
239
+ data.to_s
240
+ end
241
+ end
242
+
243
+ # Replaces the contents of params that match params_filters.
244
+ # TODO: extract this to a different class
245
+ def clean_params
246
+ clean_unserializable_data_from(:parameters)
247
+ filter(parameters)
248
+ if cgi_data
249
+ clean_unserializable_data_from(:cgi_data)
250
+ filter(cgi_data)
251
+ end
252
+ if session_data
253
+ clean_unserializable_data_from(:session_data)
254
+ filter(session_data)
255
+ end
256
+ end
257
+
258
+ def clean_rack_request_data
259
+ if cgi_data
260
+ cgi_data.delete("rack.request.form_vars")
261
+ end
262
+ end
263
+
264
+ def filter(hash)
265
+ if params_filters
266
+ hash.each do |key, value|
267
+ if filter_key?(key)
268
+ hash[key] = "[FILTERED]"
269
+ elsif value.respond_to?(:to_hash)
270
+ filter(hash[key])
271
+ end
272
+ end
273
+ end
274
+ end
275
+
276
+ def filter_key?(key)
277
+ params_filters.any? do |filter|
278
+ key.to_s.include?(filter.to_s)
279
+ end
280
+ end
281
+
282
+ def find_session_data
283
+ self.session_data = args[:session_data] || args[:session] || rack_session || {}
284
+ self.session_data = session_data[:data] if session_data[:data]
285
+ end
286
+
287
+ # Converts the mixed class instances and class names into just names
288
+ # TODO: move this into Configuration or another class
289
+ def ignored_class_names
290
+ ignore.collect do |string_or_class|
291
+ if string_or_class.respond_to?(:name)
292
+ string_or_class.name
293
+ else
294
+ string_or_class
295
+ end
296
+ end
297
+ end
298
+
299
+ def xml_vars_for(builder, hash)
300
+ hash.each do |key, value|
301
+ if value.respond_to?(:to_hash)
302
+ builder.var(:key => key){|b| xml_vars_for(b, value.to_hash) }
303
+ else
304
+ builder.var(value.to_s, :key => key)
305
+ end
306
+ end
307
+ end
308
+
309
+ def rack_env(method)
310
+ rack_request.send(method) if rack_request
311
+ end
312
+
313
+ def rack_request
314
+ @rack_request ||= if args[:rack_env]
315
+ ::Rack::Request.new(args[:rack_env])
316
+ end
317
+ end
318
+
319
+ def action_dispatch_params
320
+ args[:rack_env]['action_dispatch.request.parameters'] if args[:rack_env]
321
+ end
322
+
323
+ def rack_session
324
+ args[:rack_env]['rack.session'] if args[:rack_env]
325
+ end
326
+
327
+ def also_use_rack_params_filters
328
+ if args[:rack_env]
329
+ @params_filters += rack_request.env["action_dispatch.parameter_filter"] || []
330
+ end
331
+ end
332
+
333
+ end
334
+ end