riscfuture-hoptoad_notifier 2.3.6

Sign up to get free protection for your applications and to get access to all the features.
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