rollbar 2.16.2 → 2.22.1
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.
- checksums.yaml +5 -5
- data/.rubocop.yml +47 -0
- data/.travis.yml +182 -94
- data/Appraisals +10 -10
- data/Gemfile +45 -13
- data/README.md +20 -3
- data/Rakefile +0 -0
- data/data/rollbar.snippet.js +1 -1
- data/docs/configuration.md +15 -0
- data/gemfiles/rails30.gemfile +21 -14
- data/gemfiles/rails31.gemfile +21 -12
- data/gemfiles/rails32.gemfile +18 -8
- data/gemfiles/rails40.gemfile +18 -6
- data/gemfiles/rails41.gemfile +17 -6
- data/gemfiles/rails42.gemfile +24 -14
- data/gemfiles/rails50.gemfile +20 -11
- data/gemfiles/rails51.gemfile +20 -10
- data/gemfiles/rails52.gemfile +65 -0
- data/gemfiles/rails60.gemfile +67 -0
- data/lib/generators/rollbar/rollbar_generator.rb +1 -1
- data/lib/rails/rollbar_runner.rb +17 -2
- data/lib/rollbar.rb +2 -3
- data/lib/rollbar/capistrano.rb +71 -39
- data/lib/rollbar/capistrano3.rb +56 -1
- data/lib/rollbar/capistrano_tasks.rb +130 -0
- data/lib/rollbar/configuration.rb +95 -7
- data/lib/rollbar/delay/active_job.rb +17 -0
- data/lib/rollbar/delay/girl_friday.rb +2 -2
- data/lib/rollbar/delay/resque.rb +4 -6
- data/lib/rollbar/delay/shoryuken.rb +15 -9
- data/lib/rollbar/delay/sidekiq.rb +6 -8
- data/lib/rollbar/delay/sucker_punch.rb +17 -19
- data/lib/rollbar/delay/thread.rb +3 -3
- data/lib/rollbar/deploy.rb +90 -0
- data/lib/rollbar/encoding/encoder.rb +9 -9
- data/lib/rollbar/exception_reporter.rb +19 -5
- data/lib/rollbar/item.rb +62 -20
- data/lib/rollbar/item/backtrace.rb +4 -4
- data/lib/rollbar/item/frame.rb +7 -1
- data/lib/rollbar/item/locals.rb +56 -0
- data/lib/rollbar/json.rb +5 -51
- data/lib/rollbar/language_support.rb +4 -20
- data/lib/rollbar/lazy_store.rb +5 -5
- data/lib/rollbar/logger.rb +1 -0
- data/lib/rollbar/logger_proxy.rb +15 -2
- data/lib/rollbar/middleware/js.rb +110 -10
- data/lib/rollbar/middleware/js/json_value.rb +26 -0
- data/lib/rollbar/middleware/rack.rb +4 -1
- data/lib/rollbar/middleware/rails/rollbar.rb +10 -1
- data/lib/rollbar/notifier.rb +118 -49
- data/lib/rollbar/notifier/trace_with_bindings.rb +65 -0
- data/lib/rollbar/plugin.rb +54 -6
- data/lib/rollbar/plugins.rb +7 -1
- data/lib/rollbar/plugins/active_job.rb +5 -1
- data/lib/rollbar/plugins/basic_socket.rb +21 -6
- data/lib/rollbar/plugins/delayed_job/job_data.rb +3 -3
- data/lib/rollbar/plugins/delayed_job/plugin.rb +3 -3
- data/lib/rollbar/plugins/goalie.rb +11 -3
- data/lib/rollbar/plugins/rails/controller_methods.rb +17 -4
- data/lib/rollbar/plugins/rails/railtie_mixin.rb +7 -3
- data/lib/rollbar/plugins/rake.rb +2 -2
- data/lib/rollbar/plugins/sidekiq/plugin.rb +10 -6
- data/lib/rollbar/rake_tasks.rb +3 -86
- data/lib/rollbar/request_data_extractor.rb +35 -21
- data/lib/rollbar/rollbar_test.rb +147 -0
- data/lib/rollbar/scrubbers.rb +7 -3
- data/lib/rollbar/scrubbers/params.rb +38 -20
- data/lib/rollbar/scrubbers/url.rb +27 -13
- data/lib/rollbar/truncation.rb +9 -2
- data/lib/rollbar/truncation/min_body_strategy.rb +2 -3
- data/lib/rollbar/truncation/remove_any_key_strategy.rb +123 -0
- data/lib/rollbar/truncation/remove_extra_strategy.rb +35 -0
- data/lib/rollbar/truncation/remove_request_strategy.rb +21 -0
- data/lib/rollbar/truncation/strings_strategy.rb +3 -4
- data/lib/rollbar/util.rb +75 -45
- data/lib/rollbar/util/hash.rb +30 -6
- data/lib/rollbar/util/ip_anonymizer.rb +8 -7
- data/lib/rollbar/util/ip_obfuscator.rb +1 -1
- data/lib/rollbar/version.rb +1 -1
- data/lib/tasks/benchmark.rake +103 -0
- data/rollbar.gemspec +14 -8
- metadata +25 -277
- data/gemfiles/ruby_1_8_and_1_9_2.gemfile +0 -49
- data/lib/rollbar/json/default.rb +0 -11
- data/lib/rollbar/json/oj.rb +0 -16
- data/lib/rollbar/tasks/rollbar.cap +0 -47
- data/spec/cacert.pem +0 -3988
- data/spec/controllers/home_controller_spec.rb +0 -480
- data/spec/delay/sidekiq_spec.rb +0 -61
- data/spec/delay/sucker_punch_spec.rb +0 -25
- data/spec/delayed/backend/test.rb +0 -140
- data/spec/delayed/serialization/test.rb +0 -0
- data/spec/dummyapp/.gitignore +0 -73
- data/spec/dummyapp/Rakefile +0 -7
- data/spec/dummyapp/app/assets/javascripts/application.js +0 -3
- data/spec/dummyapp/app/assets/stylesheets/application.css.scss +0 -37
- data/spec/dummyapp/app/controllers/application_controller.rb +0 -3
- data/spec/dummyapp/app/controllers/home_controller.rb +0 -60
- data/spec/dummyapp/app/controllers/users_controller.rb +0 -17
- data/spec/dummyapp/app/helpers/.gitkeep +0 -0
- data/spec/dummyapp/app/mailers/.gitkeep +0 -0
- data/spec/dummyapp/app/models/.gitkeep +0 -0
- data/spec/dummyapp/app/models/book.rb +0 -5
- data/spec/dummyapp/app/models/post.rb +0 -9
- data/spec/dummyapp/app/models/user.rb +0 -9
- data/spec/dummyapp/app/views/devise/registrations/edit.html.erb +0 -27
- data/spec/dummyapp/app/views/devise/registrations/new.html.erb +0 -20
- data/spec/dummyapp/app/views/devise/shared/_links.html.erb +0 -25
- data/spec/dummyapp/app/views/home/cause_exception.html.erb +0 -1
- data/spec/dummyapp/app/views/home/index.html.erb +0 -4
- data/spec/dummyapp/app/views/home/report_exception.html.erb +0 -1
- data/spec/dummyapp/app/views/js/test.html.erb +0 -1
- data/spec/dummyapp/app/views/layouts/_messages.html.erb +0 -5
- data/spec/dummyapp/app/views/layouts/_navigation.html.erb +0 -21
- data/spec/dummyapp/app/views/layouts/application.html.erb +0 -25
- data/spec/dummyapp/app/views/layouts/simple.html.erb +0 -18
- data/spec/dummyapp/app/views/users/index.html.erb +0 -8
- data/spec/dummyapp/app/views/users/show.html.erb +0 -3
- data/spec/dummyapp/config.ru +0 -4
- data/spec/dummyapp/config/application.rb +0 -59
- data/spec/dummyapp/config/boot.rb +0 -10
- data/spec/dummyapp/config/database.yml +0 -25
- data/spec/dummyapp/config/environment.rb +0 -5
- data/spec/dummyapp/config/environments/development.rb +0 -37
- data/spec/dummyapp/config/environments/production.rb +0 -67
- data/spec/dummyapp/config/environments/test.rb +0 -37
- data/spec/dummyapp/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/dummyapp/config/initializers/inflections.rb +0 -15
- data/spec/dummyapp/config/initializers/mime_types.rb +0 -5
- data/spec/dummyapp/config/initializers/rollbar.rb +0 -26
- data/spec/dummyapp/config/initializers/secret_token.rb +0 -7
- data/spec/dummyapp/config/initializers/session_store.rb +0 -8
- data/spec/dummyapp/config/initializers/wrap_parameters.rb +0 -16
- data/spec/dummyapp/config/locales/devise.en.yml +0 -58
- data/spec/dummyapp/config/locales/en.yml +0 -5
- data/spec/dummyapp/config/routes.rb +0 -17
- data/spec/dummyapp/config/secrets.yml +0 -2
- data/spec/dummyapp/db/migrate/20121121184652_devise_create_users.rb +0 -46
- data/spec/dummyapp/db/migrate/20121121184654_add_name_to_users.rb +0 -5
- data/spec/dummyapp/db/migrate/20161219184410_create_books.rb +0 -10
- data/spec/dummyapp/db/migrate/20161219185529_add_username_to_users.rb +0 -5
- data/spec/dummyapp/db/schema.rb +0 -41
- data/spec/dummyapp/db/seeds.rb +0 -12
- data/spec/dummyapp/lib/assets/.gitkeep +0 -0
- data/spec/dummyapp/public/404.html +0 -26
- data/spec/dummyapp/public/422.html +0 -26
- data/spec/dummyapp/public/500.html +0 -25
- data/spec/dummyapp/public/favicon.ico +0 -0
- data/spec/dummyapp/script/rails +0 -6
- data/spec/fixtures/file1 +0 -1
- data/spec/fixtures/file2 +0 -1
- data/spec/fixtures/payloads/message.json +0 -25
- data/spec/fixtures/payloads/sample.trace.json +0 -275
- data/spec/fixtures/payloads/sample.trace_chain.json +0 -530
- data/spec/fixtures/plugins/dummy1.rb +0 -5
- data/spec/fixtures/plugins/dummy2.rb +0 -5
- data/spec/generators/rollbar/rollbar_generator_rails30_spec.rb +0 -31
- data/spec/generators/rollbar/rollbar_generator_spec.rb +0 -51
- data/spec/requests/home_spec.rb +0 -49
- data/spec/rollbar/configuration_spec.rb +0 -46
- data/spec/rollbar/delay/delayed_job_spec.rb +0 -22
- data/spec/rollbar/delay/girl_friday_spec.rb +0 -41
- data/spec/rollbar/delay/resque_spec.rb +0 -37
- data/spec/rollbar/delay/thread_spec.rb +0 -27
- data/spec/rollbar/encoding/encoder_spec.rb +0 -63
- data/spec/rollbar/item/backtrace_spec.rb +0 -26
- data/spec/rollbar/item/frame_spec.rb +0 -267
- data/spec/rollbar/item_spec.rb +0 -736
- data/spec/rollbar/json/oj_spec.rb +0 -18
- data/spec/rollbar/json_spec.rb +0 -110
- data/spec/rollbar/lazy_store_spec.rb +0 -99
- data/spec/rollbar/logger_proxy_spec.rb +0 -50
- data/spec/rollbar/logger_spec.rb +0 -124
- data/spec/rollbar/middleware/js_spec.rb +0 -421
- data/spec/rollbar/middleware/sinatra_spec.rb +0 -197
- data/spec/rollbar/notifier_spec.rb +0 -56
- data/spec/rollbar/plugin_spec.rb +0 -209
- data/spec/rollbar/plugins/active_job_spec.rb +0 -38
- data/spec/rollbar/plugins/delayed_job/job_data_spec.rb +0 -48
- data/spec/rollbar/plugins/delayed_job_spec.rb +0 -129
- data/spec/rollbar/plugins/rack_spec.rb +0 -152
- data/spec/rollbar/plugins/rails_js_spec.rb +0 -19
- data/spec/rollbar/plugins/rake_spec.rb +0 -34
- data/spec/rollbar/plugins/resque/failure_spec.rb +0 -36
- data/spec/rollbar/plugins/sidekiq_spec.rb +0 -171
- data/spec/rollbar/plugins/validations_spec.rb +0 -56
- data/spec/rollbar/plugins_spec.rb +0 -68
- data/spec/rollbar/request_data_extractor_spec.rb +0 -270
- data/spec/rollbar/scrubbers/params_spec.rb +0 -314
- data/spec/rollbar/scrubbers/url_spec.rb +0 -136
- data/spec/rollbar/scrubbers_spec.rb +0 -31
- data/spec/rollbar/sidekig/clear_scope_spec.rb +0 -19
- data/spec/rollbar/truncation/frames_strategy_spec.rb +0 -70
- data/spec/rollbar/truncation/min_body_strategy_spec.rb +0 -57
- data/spec/rollbar/truncation/strings_strategy_spec.rb +0 -89
- data/spec/rollbar/truncation_spec.rb +0 -27
- data/spec/rollbar/util/hash_spec.rb +0 -22
- data/spec/rollbar/util/ip_anonymizer_spec.rb +0 -30
- data/spec/rollbar/util_spec.rb +0 -80
- data/spec/rollbar_bc_spec.rb +0 -380
- data/spec/rollbar_spec.rb +0 -1667
- data/spec/spec_helper.rb +0 -84
- data/spec/support/cause_exception.rb +0 -1
- data/spec/support/encoding_helpers.rb +0 -8
- data/spec/support/encodings/iso_8859_9 +0 -1
- data/spec/support/fixture_helpers.rb +0 -10
- data/spec/support/get_ip_raising.rb +0 -7
- data/spec/support/helpers.rb +0 -5
- data/spec/support/matchers.rb +0 -23
- data/spec/support/notifier_helpers.rb +0 -57
- data/spec/support/rollbar_api.rb +0 -57
- data/spec/support/shared_contexts.rb +0 -12
data/lib/rollbar/item/frame.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# We want to use Gem.path
|
|
2
2
|
require 'rubygems'
|
|
3
|
+
require 'rollbar/item/locals'
|
|
3
4
|
|
|
4
5
|
module Rollbar
|
|
5
6
|
class Item
|
|
@@ -47,7 +48,8 @@ module Rollbar
|
|
|
47
48
|
|
|
48
49
|
{
|
|
49
50
|
:code => code_data(file_lines, lineno),
|
|
50
|
-
:context => context_data(file_lines, lineno)
|
|
51
|
+
:context => context_data(file_lines, lineno),
|
|
52
|
+
:locals => locals_data(filename, lineno)
|
|
51
53
|
}
|
|
52
54
|
end
|
|
53
55
|
|
|
@@ -94,6 +96,10 @@ module Rollbar
|
|
|
94
96
|
}
|
|
95
97
|
end
|
|
96
98
|
|
|
99
|
+
def locals_data(filename, lineno)
|
|
100
|
+
::Rollbar::Item::Locals.locals_for_location(filename, lineno)
|
|
101
|
+
end
|
|
102
|
+
|
|
97
103
|
def post_data(file_lines, lineno)
|
|
98
104
|
from_line = lineno
|
|
99
105
|
number_of_lines = [from_line + MAX_CONTEXT_LENGTH, file_lines.size].min - from_line
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'rollbar/notifier'
|
|
2
|
+
require 'rollbar/scrubbers/params'
|
|
3
|
+
|
|
4
|
+
module Rollbar
|
|
5
|
+
class Item
|
|
6
|
+
class Locals # :nodoc:
|
|
7
|
+
class << self
|
|
8
|
+
def exception_frames
|
|
9
|
+
Rollbar.notifier.exception_bindings
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def locals_for_location(filename, lineno)
|
|
13
|
+
if (frame = frame_for_location(filename, lineno))
|
|
14
|
+
scrub(locals_for(frame[:binding]))
|
|
15
|
+
else
|
|
16
|
+
{}
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def frame_for_location(filename, lineno)
|
|
21
|
+
while (frame = exception_frames.pop)
|
|
22
|
+
return nil unless frame
|
|
23
|
+
return frame if matching_frame?(frame, filename, lineno)
|
|
24
|
+
end
|
|
25
|
+
nil
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def matching_frame?(frame, filename, lineno)
|
|
31
|
+
frame[:path] == filename && frame[:lineno].to_i <= lineno.to_i
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def locals_for(frame)
|
|
35
|
+
{}.tap do |hash|
|
|
36
|
+
frame.local_variables.map do |var|
|
|
37
|
+
hash[var] = prepare_value(frame.local_variable_get(var))
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def prepare_value(value)
|
|
43
|
+
value.to_s
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def scrub(hash)
|
|
47
|
+
Rollbar::Scrubbers::Params.call(
|
|
48
|
+
:params => hash,
|
|
49
|
+
:config => Rollbar.configuration.scrub_fields,
|
|
50
|
+
:whitelist => Rollbar.configuration.scrub_whitelist
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
data/lib/rollbar/json.rb
CHANGED
|
@@ -1,65 +1,19 @@
|
|
|
1
|
-
require 'multi_json'
|
|
2
|
-
require 'rollbar/json/oj'
|
|
3
|
-
require 'rollbar/json/default'
|
|
4
1
|
require 'rollbar/language_support'
|
|
5
2
|
|
|
6
|
-
begin
|
|
7
|
-
require 'oj'
|
|
8
|
-
rescue LoadError
|
|
9
|
-
end
|
|
10
|
-
|
|
11
3
|
module Rollbar
|
|
12
|
-
module JSON
|
|
4
|
+
module JSON # :nodoc:
|
|
13
5
|
extend self
|
|
14
6
|
|
|
15
7
|
attr_writer :options_module
|
|
16
8
|
|
|
17
9
|
def dump(object)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def load(string)
|
|
22
|
-
with_adapter { MultiJson.load(string, adapter_options) }
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def with_adapter(&block)
|
|
26
|
-
MultiJson.with_adapter(detect_multi_json_adapter, &block)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def detect_multi_json_adapter
|
|
30
|
-
options = {}
|
|
31
|
-
options[:adapter] = :oj if defined?(::Oj)
|
|
32
|
-
|
|
33
|
-
MultiJson.current_adapter(options)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def adapter_options
|
|
37
|
-
options_module.options
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def options_module
|
|
41
|
-
@options_module ||= find_options_module
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def find_options_module
|
|
45
|
-
module_name = multi_json_adapter_module_name
|
|
46
|
-
|
|
47
|
-
if LanguageSupport.const_defined?(Rollbar::JSON, module_name, false)
|
|
48
|
-
LanguageSupport.const_get(Rollbar::JSON, module_name, false)
|
|
49
|
-
else
|
|
50
|
-
Default
|
|
10
|
+
Rollbar.plugins.get('basic_socket').load_scoped!(true) do
|
|
11
|
+
::JSON.generate(object)
|
|
51
12
|
end
|
|
52
13
|
end
|
|
53
14
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
#
|
|
57
|
-
# Ex: MultiJson::Adapters::Oj
|
|
58
|
-
# Ex: MultiJson::Adapters::JsonGem
|
|
59
|
-
#
|
|
60
|
-
# In this method we just get the last module name.
|
|
61
|
-
def multi_json_adapter_module_name
|
|
62
|
-
detect_multi_json_adapter.name[/^MultiJson::Adapters::(.*)$/, 1]
|
|
15
|
+
def load(string)
|
|
16
|
+
::JSON.parse(string)
|
|
63
17
|
end
|
|
64
18
|
end
|
|
65
19
|
end
|
|
@@ -1,29 +1,13 @@
|
|
|
1
1
|
module Rollbar
|
|
2
2
|
module LanguageSupport
|
|
3
|
-
|
|
3
|
+
module_function
|
|
4
4
|
|
|
5
5
|
def const_defined?(mod, target, inherit = true)
|
|
6
|
-
|
|
7
|
-
mod.const_defined?(target)
|
|
8
|
-
else
|
|
9
|
-
mod.const_defined?(target, inherit)
|
|
10
|
-
end
|
|
6
|
+
mod.const_defined?(target, inherit)
|
|
11
7
|
end
|
|
12
8
|
|
|
13
9
|
def const_get(mod, target, inherit = true)
|
|
14
|
-
|
|
15
|
-
mod.const_get(target)
|
|
16
|
-
else
|
|
17
|
-
mod.const_get(target, inherit)
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def can_scrub_url?
|
|
22
|
-
!version?('1.8')
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def ruby_18?
|
|
26
|
-
version?('1.8')
|
|
10
|
+
mod.const_get(target, inherit)
|
|
27
11
|
end
|
|
28
12
|
|
|
29
13
|
def ruby_19?
|
|
@@ -37,7 +21,7 @@ module Rollbar
|
|
|
37
21
|
end
|
|
38
22
|
|
|
39
23
|
def timeout_exceptions
|
|
40
|
-
return [] if
|
|
24
|
+
return [] if ruby_19?
|
|
41
25
|
|
|
42
26
|
[Net::ReadTimeout, Net::OpenTimeout]
|
|
43
27
|
end
|
data/lib/rollbar/lazy_store.rb
CHANGED
|
@@ -21,11 +21,11 @@ module Rollbar
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def ==(other)
|
|
24
|
-
if other.is_a?(self.class)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
raw == if other.is_a?(self.class)
|
|
25
|
+
other.raw
|
|
26
|
+
else
|
|
27
|
+
other
|
|
28
|
+
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# With this version of clone we ensure that the loaded_data is empty
|
data/lib/rollbar/logger.rb
CHANGED
data/lib/rollbar/logger_proxy.rb
CHANGED
|
@@ -23,12 +23,25 @@ module Rollbar
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def log(level, message)
|
|
26
|
-
return unless Rollbar.configuration.enabled
|
|
26
|
+
return unless Rollbar.configuration.enabled && acceptable_levels.include?(level.to_sym)
|
|
27
27
|
|
|
28
28
|
@object.send(level, message)
|
|
29
|
-
rescue
|
|
29
|
+
rescue StandardError
|
|
30
30
|
puts "[Rollbar] Error logging #{level}:"
|
|
31
31
|
puts "[Rollbar] #{message}"
|
|
32
32
|
end
|
|
33
|
+
|
|
34
|
+
protected
|
|
35
|
+
|
|
36
|
+
def acceptable_levels
|
|
37
|
+
@acceptable_levels ||= begin
|
|
38
|
+
levels = [:debug, :info, :warn, :error]
|
|
39
|
+
if Rollbar.configuration.logger_level
|
|
40
|
+
levels[levels.find_index(Rollbar.configuration.logger_level)..-1]
|
|
41
|
+
else
|
|
42
|
+
[]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
33
46
|
end
|
|
34
47
|
end
|
|
@@ -13,7 +13,7 @@ module Rollbar
|
|
|
13
13
|
attr_reader :app
|
|
14
14
|
attr_reader :config
|
|
15
15
|
|
|
16
|
-
JS_IS_INJECTED_KEY = 'rollbar.js_is_injected'
|
|
16
|
+
JS_IS_INJECTED_KEY = 'rollbar.js_is_injected'.freeze
|
|
17
17
|
SNIPPET = File.read(File.expand_path('../../../../data/rollbar.snippet.js', __FILE__))
|
|
18
18
|
|
|
19
19
|
def initialize(app, config)
|
|
@@ -29,13 +29,15 @@ module Rollbar
|
|
|
29
29
|
|
|
30
30
|
response_string = add_js(env, app_result[2])
|
|
31
31
|
build_response(env, app_result, response_string)
|
|
32
|
-
rescue => e
|
|
32
|
+
rescue StandardError => e
|
|
33
33
|
Rollbar.log_error("[Rollbar] Rollbar.js could not be added because #{e} exception")
|
|
34
34
|
|
|
35
35
|
app_result
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
+
private
|
|
40
|
+
|
|
39
41
|
def enabled?
|
|
40
42
|
!!config[:enabled]
|
|
41
43
|
end
|
|
@@ -69,7 +71,7 @@ module Rollbar
|
|
|
69
71
|
return nil unless insert_after_idx
|
|
70
72
|
|
|
71
73
|
build_body_with_js(env, body, insert_after_idx)
|
|
72
|
-
rescue => e
|
|
74
|
+
rescue StandardError => e
|
|
73
75
|
Rollbar.log_error("[Rollbar] Rollbar.js could not be added because #{e} exception")
|
|
74
76
|
nil
|
|
75
77
|
end
|
|
@@ -118,7 +120,11 @@ module Rollbar
|
|
|
118
120
|
|
|
119
121
|
add_person_data(js_config, env)
|
|
120
122
|
|
|
121
|
-
|
|
123
|
+
# MUST use the Ruby JSON encoder (JSON#generate).
|
|
124
|
+
# See lib/rollbar/middleware/js/json_value
|
|
125
|
+
json = ::JSON.generate(js_config)
|
|
126
|
+
|
|
127
|
+
script_tag("var _rollbarConfig = #{json};", env)
|
|
122
128
|
end
|
|
123
129
|
|
|
124
130
|
def add_person_data(js_config, env)
|
|
@@ -139,7 +145,9 @@ module Rollbar
|
|
|
139
145
|
end
|
|
140
146
|
|
|
141
147
|
def script_tag(content, env)
|
|
142
|
-
if
|
|
148
|
+
if (nonce = rails5_nonce(env))
|
|
149
|
+
script_tag_content = "\n<script type=\"text/javascript\" nonce=\"#{nonce}\">#{content}</script>"
|
|
150
|
+
elsif secure_headers_nonce?
|
|
143
151
|
nonce = ::SecureHeaders.content_security_policy_script_nonce(::Rack::Request.new(env))
|
|
144
152
|
script_tag_content = "\n<script type=\"text/javascript\" nonce=\"#{nonce}\">#{content}</script>"
|
|
145
153
|
else
|
|
@@ -154,11 +162,103 @@ module Rollbar
|
|
|
154
162
|
string
|
|
155
163
|
end
|
|
156
164
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
165
|
+
# Rails 5.2 Secure Content Policy
|
|
166
|
+
def rails5_nonce(env)
|
|
167
|
+
# The nonce is the preferred method, however 'unsafe-inline' is also possible.
|
|
168
|
+
# The app gets to decide, so we handle both. If the script_src key is missing,
|
|
169
|
+
# Rails will not add the nonce to the headers, so we should not add it either.
|
|
170
|
+
# If the 'unsafe-inline' value is present, the app should not add a nonce and
|
|
171
|
+
# we should ignore it if they do.
|
|
172
|
+
req = ::ActionDispatch::Request.new env
|
|
173
|
+
req.respond_to?(:content_security_policy) &&
|
|
174
|
+
req.content_security_policy &&
|
|
175
|
+
req.content_security_policy.directives['script-src'] &&
|
|
176
|
+
!req.content_security_policy.directives['script-src'].include?("'unsafe-inline'") &&
|
|
177
|
+
req.content_security_policy_nonce
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Secure Headers gem
|
|
181
|
+
def secure_headers_nonce?
|
|
182
|
+
secure_headers.append_nonce?
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def secure_headers
|
|
186
|
+
return SecureHeadersFalse.new unless defined?(::SecureHeaders::Configuration)
|
|
187
|
+
|
|
188
|
+
config = ::SecureHeaders::Configuration
|
|
189
|
+
|
|
190
|
+
secure_headers_cls = nil
|
|
191
|
+
|
|
192
|
+
secure_headers_cls = if !::SecureHeaders.respond_to?(:content_security_policy_script_nonce)
|
|
193
|
+
SecureHeadersFalse
|
|
194
|
+
elsif config.respond_to?(:get)
|
|
195
|
+
SecureHeaders3To5
|
|
196
|
+
elsif config.dup.respond_to?(:csp)
|
|
197
|
+
SecureHeaders6
|
|
198
|
+
else
|
|
199
|
+
SecureHeadersFalse
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
secure_headers_cls.new
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
class SecureHeadersResolver
|
|
206
|
+
def append_nonce?
|
|
207
|
+
csp_needs_nonce?(find_csp)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
private
|
|
211
|
+
|
|
212
|
+
def find_csp
|
|
213
|
+
raise NotImplementedError
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def csp_needs_nonce?(csp)
|
|
217
|
+
!opt_out?(csp) && !unsafe_inline?(csp)
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def opt_out?(_csp)
|
|
221
|
+
raise NotImplementedError
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def unsafe_inline?(csp)
|
|
225
|
+
csp[:script_src].to_a.include?("'unsafe-inline'")
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
class SecureHeadersFalse < SecureHeadersResolver
|
|
230
|
+
def append_nonce?
|
|
231
|
+
false
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
class SecureHeaders3To5 < SecureHeadersResolver
|
|
236
|
+
private
|
|
237
|
+
|
|
238
|
+
def find_csp
|
|
239
|
+
::SecureHeaders::Configuration.get.csp
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def opt_out?(csp)
|
|
243
|
+
if csp.respond_to?(:opt_out?) && csp.opt_out?
|
|
244
|
+
csp.opt_out?
|
|
245
|
+
# secure_headers csp 3.0.x-3.4.x doesn't respond to 'opt_out?'
|
|
246
|
+
elsif defined?(::SecureHeaders::OPT_OUT) && ::SecureHeaders::OPT_OUT.is_a?(Symbol)
|
|
247
|
+
csp == ::SecureHeaders::OPT_OUT
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
class SecureHeaders6 < SecureHeadersResolver
|
|
253
|
+
private
|
|
254
|
+
|
|
255
|
+
def find_csp
|
|
256
|
+
::SecureHeaders::Configuration.dup.csp
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def opt_out?(csp)
|
|
260
|
+
csp.opt_out?
|
|
261
|
+
end
|
|
162
262
|
end
|
|
163
263
|
end
|
|
164
264
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Allows a Ruby String to be used to create native Javascript objects
|
|
2
|
+
# when calling JSON#generate.
|
|
3
|
+
#
|
|
4
|
+
# Example:
|
|
5
|
+
# JSON.generate({ foo: Rollbar::JSON::Value.new('function(){ alert("bar") }') })
|
|
6
|
+
# => '{"foo":function(){ alert(\"bar\") }}'
|
|
7
|
+
#
|
|
8
|
+
# MUST use the Ruby JSON encoder, as in the example. The ActiveSupport encoder,
|
|
9
|
+
# which is installed with Rails, is invoked when calling Hash#to_json and #as_json,
|
|
10
|
+
# and will not work.
|
|
11
|
+
#
|
|
12
|
+
module Rollbar
|
|
13
|
+
module JSON
|
|
14
|
+
class Value # :nodoc:
|
|
15
|
+
attr_accessor :value
|
|
16
|
+
|
|
17
|
+
def initialize(value)
|
|
18
|
+
@value = value
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def to_json(*_args)
|
|
22
|
+
value
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|