bugsnag 2.8.13 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7d6aa2d47b176056a2296c83ed021e60535d8500
4
- data.tar.gz: 993b3197a9a58242cc35f27ee6e89144c0a5bc56
3
+ metadata.gz: c47737bc08fe70bfdc4b9391ab04d5b6aa6900aa
4
+ data.tar.gz: abe70b3cc901bf48a06fab50bd410e1927ca7a6d
5
5
  SHA512:
6
- metadata.gz: 42e61fc1a225f0428fe20357d0af38f022e9fecd835b0c414651f2873e26f00165beee2059920002185db91e082896fa225b68024bad6b74d5d6c20452c2eb46
7
- data.tar.gz: 4d55d3468985cc4a7b6b7b2275b26af66ae0b39d200b2063a9db687990e67f927d2fd663034484dfe4db6fb898f3ec66009c2eba1624846d68b590c6ae86fecf
6
+ metadata.gz: eedb7804e481f0ecfd3436b758e7880f7ebfe232cc7fc93ee5a670738e61df4751a7ff11523cd523c9ec873259f21880df84d214f2a63333c3f6bda704c34184
7
+ data.tar.gz: afc1a1885938f4926dea26e9eb4f22080ea506f15997afe4acd4302085a445e5ff7a0e7191c2d55f50f2919a8a56c664ea7e64b261d6c4c76d360ed823d5da23
@@ -1,3 +1,4 @@
1
+ sudo: false
1
2
  language: ruby
2
3
  rvm:
3
4
  - 2.1.0
@@ -9,7 +10,3 @@ rvm:
9
10
  before_install:
10
11
  - gem update --system 2.1.11
11
12
  - gem --version
12
- notifications:
13
- hipchat:
14
- rooms:
15
- secure: cv5V8ivZExOywKL9n0CODnxy9m5u4rQ5ZMYK8XHPIoqQKkvH9DQOeb2ItW2aM2kxeupJEcQEy1Eu4sYMGhyzKUNdqbFtQBhDYxRwSAgTRIkGlHQCnznyExHWZbGfDB8y/m11HiZ1wuPuqs8ZZ+VccNb4bwJKbhPTbf1RZ+GPeU8=
@@ -1,6 +1,23 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ 3.0.0 (23 Dec 2015)
5
+ -----
6
+
7
+ ### Enhancements
8
+
9
+ * Fix warning from usage of `before_filter` in Rails 5
10
+ | [Scott Ringwelski](https://github.com/sgringwe)
11
+ | [#267](https://github.com/bugsnag/bugsnag-ruby/pull/267)
12
+
13
+ * Use Rails 5-style deep parameter filtering
14
+ | [fimmtiu](https://github.com/fimmtiu)
15
+ | [#256](https://github.com/bugsnag/bugsnag-ruby/pull/256)
16
+
17
+ Note: This is a backwards incompatible change, as filters containing `.` are
18
+ now parsed as nested instead of as a single key.
19
+
20
+
4
21
  2.8.13
5
22
  ------
6
23
 
data/README.md CHANGED
@@ -24,16 +24,13 @@ Contents
24
24
  - [Sending Non-fatal Exceptions](#sending-non-fatal-exceptions)
25
25
  - [Deploy Tracking](#deploy-tracking)
26
26
  - [Callbacks](#callbacks)
27
+ - [Configuration](https://github.com/bugsnag/bugsnag-ruby/tree/master/docs/Configuration.md)
28
+ - [Notification Options](https://github.com/bugsnag/bugsnag-ruby/tree/master/docs/Notification Options.md)
27
29
  - [Demo Applications](#demo-applications)
28
30
  - [Support](#support)
29
31
  - [Contributing](#contributing)
30
32
  - [License](#license)
31
33
 
32
- - [Additional Documentation](https://github.com/bugsnag/bugsnag-ruby/tree/master/docs)
33
- - [Configuration](docs/Configuration.md)
34
- - [Notification Options](docs/Notification Options.md)
35
-
36
-
37
34
 
38
35
  Getting Started
39
36
  ---------------
@@ -69,17 +66,19 @@ Getting Started
69
66
  end
70
67
  ```
71
68
 
72
- The Bugsnag module will read the `BUGSNAG_API_KEY` environment variable if you
73
- do not configure one automatically.
69
+ The Bugsnag module will read the `BUGSNAG_API_KEY` environment variable if
70
+ you do not configure one automatically.
74
71
 
75
72
  ### Rake Integration
76
73
 
77
- Rake integration is automatically enabled in Rails 3/4 apps, so providing you load the environment
78
- in your Rake tasks you dont need to do anything to get Rake support. If you choose not to load
79
- your environment, you can manually configure Bugsnag with a `bugsnag.configure` block in the Rakefile.
74
+ Rake integration is automatically enabled in Rails 3/4/5 apps, so providing you
75
+ load the environment in your Rake tasks you dont need to do anything to get Rake
76
+ support. If you choose not to load your environment, you can manually configure
77
+ Bugsnag with a `bugsnag.configure` block in the Rakefile.
80
78
 
81
- Bugsnag can automatically notify of all exceptions that happen in your rake tasks. In order
82
- to enable this, you need to `require "bugsnag/rake"` in your Rakefile, like so:
79
+ Bugsnag can automatically notify of all exceptions that happen in your rake
80
+ tasks. In order to enable this, you need to `require "bugsnag/rake"` in your
81
+ Rakefile, like so:
83
82
 
84
83
  ```ruby
85
84
  require File.expand_path('../config/application', __FILE__)
@@ -93,27 +92,29 @@ end
93
92
  YourApp::Application.load_tasks
94
93
  ```
95
94
 
96
- > Note: We also configure Bugsnag in the Rakefile, so the tasks that do not load the full
97
- environment can still notify Bugsnag.
95
+ > Note: We also configure Bugsnag in the Rakefile, so the tasks that do not load
96
+ > the full environment can still notify Bugsnag.
98
97
 
99
98
  ### Sending a Test Notification
100
99
 
101
- To test that bugsnag is properly configured, you can use the `test_exception` rake task:
100
+ To test that bugsnag is properly configured, you can use the `test_exception`
101
+ rake task:
102
102
 
103
103
  ```bash
104
104
  rake bugsnag:test_exception
105
105
  ```
106
106
 
107
- A test exception will be sent to your bugsnag dashboard if everything is configured correctly.
107
+ A test exception will be sent to your bugsnag dashboard if everything is
108
+ configured correctly.
108
109
 
109
110
  Usage
110
111
  -----
111
112
 
112
113
  ### Catching and Reporting Exceptions
113
114
 
114
- Bugsnag Ruby works out of the box with Rails, Sidekiq, Resque, DelayedJob (3+), Mailman, Rake and Rack. It
115
- should be easy to add support for other frameworks, either by sending a pull request here or adding a hook
116
- to those projects.
115
+ Bugsnag Ruby works out of the box with Rails, Sidekiq, Resque, DelayedJob (3+),
116
+ Mailman, Rake and Rack. It should be easy to add support for other frameworks,
117
+ either by sending a pull request here or adding a hook to those projects.
117
118
 
118
119
  #### Rack/Sinatra Apps
119
120
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.8.13
1
+ 3.0.0
@@ -28,5 +28,6 @@ Gem::Specification.new do |s|
28
28
  s.add_development_dependency 'rspec'
29
29
  s.add_development_dependency 'rdoc'
30
30
  s.add_development_dependency 'pry'
31
+ s.add_development_dependency 'addressable', '~> 2.3.8'
31
32
  s.add_development_dependency 'webmock'
32
33
  end
@@ -5,6 +5,7 @@ require "bugsnag/version"
5
5
  require "bugsnag/configuration"
6
6
  require "bugsnag/meta_data"
7
7
  require "bugsnag/notification"
8
+ require "bugsnag/cleaner"
8
9
  require "bugsnag/helpers"
9
10
  require "bugsnag/deploy"
10
11
 
@@ -0,0 +1,122 @@
1
+ require 'uri'
2
+
3
+ module Bugsnag
4
+ class Cleaner
5
+ ENCODING_OPTIONS = {:invalid => :replace, :undef => :replace}.freeze
6
+ FILTERED = '[FILTERED]'.freeze
7
+ RECURSION = '[RECURSION]'.freeze
8
+ OBJECT = '[OBJECT]'.freeze
9
+
10
+ def initialize(filters)
11
+ @filters = Array(filters)
12
+ @deep_filters = @filters.any? {|f| f.kind_of?(Regexp) && f.to_s.include?("\\.".freeze) }
13
+ end
14
+
15
+ def clean_object(obj)
16
+ traverse_object(obj, {}, nil)
17
+ end
18
+
19
+ def traverse_object(obj, seen, scope)
20
+ return nil unless obj
21
+
22
+ # Protect against recursion of recursable items
23
+ protection = if obj.is_a?(Hash) || obj.is_a?(Array) || obj.is_a?(Set)
24
+ return seen[obj] if seen[obj]
25
+ seen[obj] = RECURSION
26
+ end
27
+
28
+ value = case obj
29
+ when Hash
30
+ clean_hash = {}
31
+ obj.each do |k,v|
32
+ if filters_match_deeply?(k, scope)
33
+ clean_hash[k] = FILTERED
34
+ else
35
+ clean_hash[k] = traverse_object(v, seen, [scope, k].compact.join('.'))
36
+ end
37
+ end
38
+ clean_hash
39
+ when Array, Set
40
+ obj.map { |el| traverse_object(el, seen, scope) }.compact
41
+ when Numeric, TrueClass, FalseClass
42
+ obj
43
+ when String
44
+ clean_string(obj)
45
+ else
46
+ str = obj.to_s
47
+ # avoid leaking potentially sensitive data from objects' #inspect output
48
+ if str =~ /#<.*>/
49
+ OBJECT
50
+ else
51
+ clean_string(str)
52
+ end
53
+ end
54
+
55
+ seen[obj] = value if protection
56
+ value
57
+ end
58
+
59
+ def clean_string(str)
60
+ if defined?(str.encoding) && defined?(Encoding::UTF_8)
61
+ if str.encoding == Encoding::UTF_8
62
+ str.valid_encoding? ? str : str.encode('utf-16', ENCODING_OPTIONS).encode('utf-8')
63
+ else
64
+ str.encode('utf-8', ENCODING_OPTIONS)
65
+ end
66
+ elsif defined?(Iconv)
67
+ Iconv.conv('UTF-8//IGNORE', 'UTF-8', str) || str
68
+ else
69
+ str
70
+ end
71
+ end
72
+
73
+ def self.clean_object_encoding(obj)
74
+ new(nil).clean_object(obj)
75
+ end
76
+
77
+ def clean_url(url)
78
+ return url if @filters.empty?
79
+
80
+ uri = URI(url)
81
+ return url unless uri.query
82
+
83
+ query_params = uri.query.split('&').map { |pair| pair.split('=') }
84
+ query_params.map! do |key, val|
85
+ if filters_match?(key)
86
+ "#{key}=#{FILTERED}"
87
+ else
88
+ "#{key}=#{val}"
89
+ end
90
+ end
91
+
92
+ uri.query = query_params.join('&')
93
+ uri.to_s
94
+ end
95
+
96
+ private
97
+
98
+ def filters_match?(key)
99
+ str = key.to_s
100
+
101
+ @filters.any? do |f|
102
+ case f
103
+ when Regexp
104
+ str.match(f)
105
+ else
106
+ str.include?(f.to_s)
107
+ end
108
+ end
109
+ end
110
+
111
+ # If someone has a Rails filter like /^stuff\.secret/, it won't match "request.params.stuff.secret",
112
+ # so we try it both with and without the "request.params." bit.
113
+ def filters_match_deeply?(key, scope)
114
+ return true if filters_match?(key)
115
+ return false unless @deep_filters
116
+
117
+ long = [scope, key].compact.join('.')
118
+ short = long.sub(/^request\.params\./, '')
119
+ filters_match?(long) || filters_match?(short)
120
+ end
121
+ end
122
+ end
@@ -24,8 +24,8 @@ module Bugsnag
24
24
 
25
25
  def start_once!
26
26
  MUTEX.synchronize do
27
- return if @started
28
- @started = true
27
+ return if @started == Process.pid
28
+ @started = Process.pid
29
29
 
30
30
  @queue = Queue.new
31
31
 
@@ -3,98 +3,6 @@ require 'uri'
3
3
  module Bugsnag
4
4
  module Helpers
5
5
  MAX_STRING_LENGTH = 4096
6
- ENCODING_OPTIONS = {:invalid => :replace, :undef => :replace}.freeze
7
-
8
- def self.cleanup_obj(obj, filters = nil, seen = {})
9
- return nil unless obj
10
-
11
- # Protect against recursion of recursable items
12
- protection = if obj.is_a?(Hash) || obj.is_a?(Array) || obj.is_a?(Set)
13
- return seen[obj] if seen[obj]
14
- seen[obj] = '[RECURSION]'.freeze
15
- end
16
-
17
- value = case obj
18
- when Hash
19
- clean_hash = {}
20
- obj.each do |k,v|
21
- if filters_match?(k, filters)
22
- clean_hash[k] = '[FILTERED]'.freeze
23
- else
24
- clean_obj = cleanup_obj(v, filters, seen)
25
- clean_hash[k] = clean_obj
26
- end
27
- end
28
- clean_hash
29
- when Array, Set
30
- obj.map { |el| cleanup_obj(el, filters, seen) }.compact
31
- when Numeric, TrueClass, FalseClass
32
- obj
33
- when String
34
- cleanup_string(obj)
35
- else
36
- str = obj.to_s
37
- # avoid leaking potentially sensitive data from objects' #inspect output
38
- if str =~ /#<.*>/
39
- '[OBJECT]'.freeze
40
- else
41
- cleanup_string(str)
42
- end
43
- end
44
-
45
- seen[obj] = value if protection
46
- value
47
- end
48
-
49
- def self.cleanup_string(str)
50
- if defined?(str.encoding) && defined?(Encoding::UTF_8)
51
- if str.encoding == Encoding::UTF_8
52
- str.valid_encoding? ? str : str.encode('utf-16', ENCODING_OPTIONS).encode('utf-8')
53
- else
54
- str.encode('utf-8', ENCODING_OPTIONS)
55
- end
56
- elsif defined?(Iconv)
57
- Iconv.conv('UTF-8//IGNORE', 'UTF-8', str) || str
58
- else
59
- str
60
- end
61
- end
62
-
63
- def self.cleanup_obj_encoding(obj)
64
- cleanup_obj(obj, nil)
65
- end
66
-
67
- def self.filters_match?(object, filters)
68
- str = object.to_s
69
-
70
- Array(filters).any? do |f|
71
- case f
72
- when Regexp
73
- str.match(f)
74
- else
75
- str.include?(f.to_s)
76
- end
77
- end
78
- end
79
-
80
- def self.cleanup_url(url, filters = [])
81
- return url if filters.empty?
82
-
83
- uri = URI(url)
84
- return url unless uri.query
85
-
86
- query_params = uri.query.split('&').map { |pair| pair.split('=') }
87
- query_params.map! do |key, val|
88
- if filters_match?(key, filters)
89
- "#{key}=[FILTERED]"
90
- else
91
- "#{key}=#{val}"
92
- end
93
- end
94
-
95
- uri.query = query_params.join('&')
96
- uri.to_s
97
- end
98
6
 
99
7
  def self.reduce_hash_size(hash)
100
8
  return {} unless hash.is_a?(Hash)
@@ -23,7 +23,7 @@ module Bugsnag::Middleware
23
23
  # Build the clean url (hide the port if it is obvious)
24
24
  url = "#{request.scheme}://#{request.host}"
25
25
  url << ":#{request.port}" unless [80, 443].include?(request.port)
26
- url << Bugsnag::Helpers.cleanup_url(request.fullpath, notification.configuration.params_filters)
26
+ url << Bugsnag::Cleaner.new(notification.configuration.params_filters).clean_url(request.fullpath)
27
27
 
28
28
  headers = {}
29
29
 
@@ -19,7 +19,7 @@ module Bugsnag::Middleware
19
19
  # Build the clean url
20
20
  url = "#{request.protocol}#{request.host}"
21
21
  url << ":#{request.port}" unless [80, 443].include?(request.port)
22
- url << Bugsnag::Helpers.cleanup_url(request.fullpath, notification.configuration.params_filters)
22
+ url << Bugsnag::Cleaner.new(notification.configuration.params_filters).clean_url(request.fullpath)
23
23
 
24
24
  # Add a request tab
25
25
  notification.add_tab(:request, {
@@ -250,10 +250,10 @@ module Bugsnag
250
250
  payload_event[:device] = {:hostname => @configuration.hostname} if @configuration.hostname
251
251
 
252
252
  # cleanup character encodings
253
- payload_event = Bugsnag::Helpers.cleanup_obj_encoding(payload_event)
253
+ payload_event = Bugsnag::Cleaner.clean_object_encoding(payload_event)
254
254
 
255
255
  # filter out sensitive values in (and cleanup encodings) metaData
256
- payload_event[:metaData] = Bugsnag::Helpers.cleanup_obj(@meta_data, @configuration.params_filters)
256
+ payload_event[:metaData] = Bugsnag::Cleaner.new(@configuration.params_filters).clean_object(@meta_data)
257
257
  payload_event.reject! {|k,v| v.nil? }
258
258
 
259
259
  # return the payload hash
@@ -17,7 +17,7 @@ module Bugsnag::Rails
17
17
  def _add_bugsnag_notify_callback(callback_key, *methods, &block)
18
18
  options = methods.last.is_a?(Hash) ? methods.pop : {}
19
19
 
20
- before_filter(options) do |controller|
20
+ action = lambda do |controller|
21
21
  request_data = Bugsnag.configuration.request_data
22
22
  request_data[callback_key] ||= []
23
23
 
@@ -33,6 +33,11 @@ module Bugsnag::Rails
33
33
  controller.instance_exec(notification, &block)
34
34
  } if block_given?
35
35
  end
36
+ if respond_to?(:before_action)
37
+ before_action(options, &action)
38
+ else
39
+ before_filter(options, &action)
40
+ end
36
41
  end
37
42
  end
38
43
 
@@ -0,0 +1,138 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Bugsnag::Cleaner do
6
+ subject { described_class.new(nil) }
7
+
8
+ describe "#clean_object" do
9
+ it "cleans up recursive hashes" do
10
+ a = {:a => {}}
11
+ a[:a][:b] = a
12
+ expect(subject.clean_object(a)).to eq({:a => {:b => "[RECURSION]"}})
13
+ end
14
+
15
+ it "cleans up recursive arrays" do
16
+ a = []
17
+ a << a
18
+ a << "hello"
19
+ expect(subject.clean_object(a)).to eq(["[RECURSION]", "hello"])
20
+ end
21
+
22
+ it "allows multiple copies of the same string" do
23
+ a = {:name => "bugsnag"}
24
+ a[:second] = a[:name]
25
+ expect(subject.clean_object(a)).to eq({:name => "bugsnag", :second => "bugsnag"})
26
+ end
27
+
28
+ it "allows multiple copies of the same object" do
29
+ a = []
30
+ b = ["hello"]
31
+ a << b; a << b
32
+ expect(subject.clean_object(a)).to eq([["hello"], ["hello"]])
33
+ end
34
+
35
+ it "cleans up UTF8 strings properly" do
36
+ obj = "André"
37
+ expect(subject.clean_object(obj)).to eq("André")
38
+ end
39
+
40
+ it "cleans up binary strings properly" do
41
+ if RUBY_VERSION > "1.9"
42
+ obj = "Andr\xc7\xff"
43
+ if obj.respond_to? :force_encoding
44
+ obj = obj.force_encoding('BINARY')
45
+ end
46
+ expect(subject.clean_object(obj)).to eq("Andr��")
47
+ end
48
+ end
49
+
50
+ it "cleans up strings returned from #to_s properly" do
51
+ if RUBY_VERSION > "1.9"
52
+ str = "Andr\xc7\xff"
53
+ if str.respond_to? :force_encoding
54
+ str = str.force_encoding('BINARY')
55
+ end
56
+ obj = RuntimeError.new(str)
57
+ expect(subject.clean_object(obj)).to eq("Andr��")
58
+ end
59
+ end
60
+
61
+ it "filters by string inclusion" do
62
+ expect(described_class.new(['f']).clean_object({ :foo => 'bar' })).to eq({ :foo => '[FILTERED]' })
63
+ expect(described_class.new(['b']).clean_object({ :foo => 'bar' })).to eq({ :foo => 'bar' })
64
+ end
65
+
66
+ it "filters by regular expression" do
67
+ expect(described_class.new([/fb?/]).clean_object({ :foo => 'bar' })).to eq({ :foo => '[FILTERED]' })
68
+ expect(described_class.new([/fb+/]).clean_object({ :foo => 'bar' })).to eq({ :foo => 'bar' })
69
+ end
70
+
71
+ it "filters deeply nested keys" do
72
+ params = {:foo => {:bar => "baz"}}
73
+ expect(described_class.new([/^foo\.bar/]).clean_object(params)).to eq({:foo => {:bar => '[FILTERED]'}})
74
+ end
75
+
76
+ it "filters deeply nested request parameters" do
77
+ params = {:request => {:params => {:foo => {:bar => "baz"}}}}
78
+ expect(described_class.new([/^foo\.bar/]).clean_object(params)).to eq({:request => {:params => {:foo => {:bar => '[FILTERED]'}}}})
79
+ end
80
+ end
81
+
82
+ describe "#clean_url" do
83
+ let(:filters) { [] }
84
+ subject { described_class.new(filters).clean_url(url) }
85
+
86
+ context "with no filters configured" do
87
+ let(:url) { "/dir/page?param1=value1&param2=value2" }
88
+ it { should eq "/dir/page?param1=value1&param2=value2" }
89
+ end
90
+
91
+ context "with no get params" do
92
+ let(:url) { "/dir/page" }
93
+ it { should eq "/dir/page" }
94
+ end
95
+
96
+ context "with no matching parameters" do
97
+ let(:filters) { ["param3"] }
98
+ let(:url) { "/dir/page?param1=value1&param2=value2" }
99
+ it { should eq "/dir/page?param1=value1&param2=value2" }
100
+ end
101
+
102
+ context "with a single matching parameter" do
103
+ let(:filters) { ["param1"] }
104
+ let(:url) { "/dir/page?param1=value1&param2=value2" }
105
+ it { should eq "/dir/page?param1=[FILTERED]&param2=value2" }
106
+ end
107
+
108
+ context "with partially matching parameters" do
109
+ let(:filters) { ["param"] }
110
+ let(:url) { "/dir/page?param1=value1&param2=value2&bla=yes" }
111
+ it { should eq "/dir/page?param1=[FILTERED]&param2=[FILTERED]&bla=yes" }
112
+ end
113
+
114
+ context "with multiple matching filters" do
115
+ let(:filters) { ["param1", "param2"] }
116
+ let(:url) { "/dir/page?param1=value1&param2=value2&param3=value3" }
117
+ it { should eq "/dir/page?param1=[FILTERED]&param2=[FILTERED]&param3=value3" }
118
+ end
119
+
120
+ context "with both string and regexp filters" do
121
+ let(:filters) { ["param1", /param2/] }
122
+ let(:url) { "/dir/page?param1=value1&param2=value2&param3=value3" }
123
+ it { should eq "/dir/page?param1=[FILTERED]&param2=[FILTERED]&param3=value3" }
124
+ end
125
+
126
+ context "with matching regexp filters" do
127
+ let(:filters) { [/\Aaccess_token\z/] }
128
+ let(:url) { "https://host.example/sessions?access_token=abc123" }
129
+ it { should eq "https://host.example/sessions?access_token=[FILTERED]" }
130
+ end
131
+
132
+ context "with partially-matching regexp filters" do
133
+ let(:filters) { [/token/] }
134
+ let(:url) { "https://host.example/sessions?access_token=abc123" }
135
+ it { should eq "https://host.example/sessions?access_token=[FILTERED]" }
136
+ end
137
+ end
138
+ end
@@ -3,68 +3,6 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Bugsnag::Helpers do
6
- it "cleans up recursive hashes" do
7
- a = {:a => {}}
8
- a[:a][:b] = a
9
- expect(Bugsnag::Helpers.cleanup_obj(a)).to eq({:a => {:b => "[RECURSION]"}})
10
- end
11
-
12
- it "cleans up recursive arrays" do
13
- a = []
14
- a << a
15
- a << "hello"
16
- expect(Bugsnag::Helpers.cleanup_obj(a)).to eq(["[RECURSION]", "hello"])
17
- end
18
-
19
- it "allows multiple copies of the same string" do
20
- a = {:name => "bugsnag"}
21
- a[:second] = a[:name]
22
- expect(Bugsnag::Helpers.cleanup_obj(a)).to eq({:name => "bugsnag", :second => "bugsnag"})
23
- end
24
-
25
- it "allows multiple copies of the same object" do
26
- a = []
27
- b = ["hello"]
28
- a << b; a << b
29
- expect(Bugsnag::Helpers.cleanup_obj(a)).to eq([["hello"], ["hello"]])
30
- end
31
-
32
- it "cleans up UTF8 strings properly" do
33
- obj = "André"
34
- expect(Bugsnag::Helpers.cleanup_obj(obj)).to eq("André")
35
- end
36
-
37
- it "cleans up binary strings properly" do
38
- if RUBY_VERSION > "1.9"
39
- obj = "Andr\xc7\xff"
40
- if obj.respond_to? :force_encoding
41
- obj = obj.force_encoding('BINARY')
42
- end
43
- expect(Bugsnag::Helpers.cleanup_obj(obj)).to eq("Andr��")
44
- end
45
- end
46
-
47
- it "cleans up strings returned from #to_s properly" do
48
- if RUBY_VERSION > "1.9"
49
- str = "Andr\xc7\xff"
50
- if str.respond_to? :force_encoding
51
- str = str.force_encoding('BINARY')
52
- end
53
- obj = RuntimeError.new(str)
54
- expect(Bugsnag::Helpers.cleanup_obj(obj)).to eq("Andr��")
55
- end
56
- end
57
-
58
- it "filters by string inclusion" do
59
- expect(Bugsnag::Helpers.cleanup_obj({ :foo => 'bar' }, ['f'])).to eq({ :foo => '[FILTERED]' })
60
- expect(Bugsnag::Helpers.cleanup_obj({ :foo => 'bar' }, ['b'])).to eq({ :foo => 'bar' })
61
- end
62
-
63
- it "filters by regular expression" do
64
- expect(Bugsnag::Helpers.cleanup_obj({ :foo => 'bar' }, [/fb?/])).to eq({ :foo => '[FILTERED]' })
65
- expect(Bugsnag::Helpers.cleanup_obj({ :foo => 'bar' }, [/fb+/])).to eq({ :foo => 'bar' })
66
- end
67
-
68
6
  it "reduces hash size correctly" do
69
7
  meta_data = {
70
8
  :key_one => "this should not be truncated",
@@ -89,56 +27,4 @@ describe Bugsnag::Helpers do
89
27
  expect(meta_data[:key_one].length).to eq(28)
90
28
  expect(meta_data[:key_one]).to eq("this should not be truncated")
91
29
  end
92
-
93
- it "works with no filters configured" do
94
- url = Bugsnag::Helpers.cleanup_url "/dir/page?param1=value1&param2=value2"
95
-
96
- expect(url).to eq("/dir/page?param1=value1&param2=value2")
97
- end
98
-
99
- it "does not filter with no get params" do
100
- url = Bugsnag::Helpers.cleanup_url "/dir/page"
101
-
102
- expect(url).to eq("/dir/page")
103
- end
104
-
105
- it "leaves a url alone if no filters match" do
106
- url = Bugsnag::Helpers.cleanup_url "/dir/page?param1=value1&param2=value2", ["param3"]
107
-
108
- expect(url).to eq("/dir/page?param1=value1&param2=value2")
109
- end
110
-
111
- it "filters a single get param" do
112
- url = Bugsnag::Helpers.cleanup_url "/dir/page?param1=value1&param2=value2", ["param1"]
113
-
114
- expect(url).to eq("/dir/page?param1=[FILTERED]&param2=value2")
115
- end
116
-
117
- it "filters a get param that contains a filtered term" do
118
- url = Bugsnag::Helpers.cleanup_url '/dir/page?param1=value1&param2=value2&bla=yes', ["param"]
119
-
120
- expect(url).to eq("/dir/page?param1=[FILTERED]&param2=[FILTERED]&bla=yes")
121
- end
122
-
123
- it "filters multiple matches" do
124
- url = Bugsnag::Helpers.cleanup_url "/dir/page?param1=value1&param2=value2&param3=value3", ["param1", "param2"]
125
-
126
- expect(url).to eq("/dir/page?param1=[FILTERED]&param2=[FILTERED]&param3=value3")
127
- end
128
-
129
- it "filters using a combination of string and regex filters" do
130
- url = Bugsnag::Helpers.cleanup_url "/dir/page?param1=value1&param2=value2&param3=value3", ["param1", /param2/]
131
-
132
- expect(url).to eq("/dir/page?param1=[FILTERED]&param2=[FILTERED]&param3=value3")
133
- end
134
-
135
- it "filters regex matches" do
136
- url = Bugsnag::Helpers.cleanup_url "https://host.example/sessions?access_token=abc123", [/\Aaccess_token\z/]
137
- expect(url).to eq("https://host.example/sessions?access_token=[FILTERED]")
138
- end
139
-
140
- it "filters partial regex matches" do
141
- url = Bugsnag::Helpers.cleanup_url "https://host.example/sessions?access_token=abc123", [/token/]
142
- expect(url).to eq("https://host.example/sessions?access_token=[FILTERED]")
143
- end
144
30
  end
@@ -17,6 +17,7 @@ describe 'Bugsnag' do
17
17
  end
18
18
  after do
19
19
  server.stop
20
+ queue.clear
20
21
  end
21
22
 
22
23
  let(:request) { JSON.parse(queue.pop) }
@@ -68,6 +69,27 @@ describe 'Bugsnag' do
68
69
  expect(request['events'][0]['exceptions'][0]['message']).to eq('yo')
69
70
  end
70
71
 
72
+ it 'should work with threadpool delivery after fork' do
73
+ is_jruby = defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
74
+ unless is_jruby #jruby doesn't support fork, so this test doesn't apply
75
+ Bugsnag.configure do |config|
76
+ config.endpoint = "localhost:#{server.config[:Port]}"
77
+ config.use_ssl = false
78
+ config.delivery_method = :thread_queue
79
+ end
80
+ WebMock.allow_net_connect!
81
+
82
+ Bugsnag.notify 'yo'
83
+
84
+ Process.fork do
85
+ Bugsnag.notify 'yo too'
86
+ end
87
+ Process.wait
88
+
89
+ expect(queue.length).to eq(2)
90
+ end
91
+ end
92
+
71
93
  describe 'with a proxy' do
72
94
  proxy = nil
73
95
  pqueue = Queue.new
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bugsnag
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.13
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-04 00:00:00.000000000 Z
11
+ date: 2015-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -86,6 +86,20 @@ dependencies:
86
86
  - - '>='
87
87
  - !ruby/object:Gem::Version
88
88
  version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: addressable
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ~>
94
+ - !ruby/object:Gem::Version
95
+ version: 2.3.8
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ~>
101
+ - !ruby/object:Gem::Version
102
+ version: 2.3.8
89
103
  - !ruby/object:Gem::Dependency
90
104
  name: webmock
91
105
  requirement: !ruby/object:Gem::Requirement
@@ -126,6 +140,7 @@ files:
126
140
  - lib/bugsnag.rb
127
141
  - lib/bugsnag/capistrano.rb
128
142
  - lib/bugsnag/capistrano2.rb
143
+ - lib/bugsnag/cleaner.rb
129
144
  - lib/bugsnag/configuration.rb
130
145
  - lib/bugsnag/delay/resque.rb
131
146
  - lib/bugsnag/delayed_job.rb
@@ -161,6 +176,7 @@ files:
161
176
  - lib/bugsnag/version.rb
162
177
  - lib/generators/bugsnag/bugsnag_generator.rb
163
178
  - rails/init.rb
179
+ - spec/cleaner_spec.rb
164
180
  - spec/code_spec.rb
165
181
  - spec/fixtures/crashes/end_of_file.rb
166
182
  - spec/fixtures/crashes/short_file.rb