bugsnag 6.7.2 → 6.7.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4a0ddb8da5fb920f1f434e58e955d26b979debe8
4
- data.tar.gz: 65de67a4ae0dbb7356bd893100e7889d608cb8bb
3
+ metadata.gz: d0486c226a185af8162d31b64d545d235624e887
4
+ data.tar.gz: 1d29c838c3d026601bdc9f4c4b574338b3fe4635
5
5
  SHA512:
6
- metadata.gz: 83327beda70eccb521332bdac2fd0c6b96eff182c508bdfacf67ba5465ceac51bb5c3f5df26ab5294c8c6051efc721eda05d9862d561de0a5b1bfe0184b746ad
7
- data.tar.gz: cb10e69935a1682cba5aedcceee811097626a95a96a394bcbab0f22aaa77d427fd8ec00d1788a210b0c3354d4b1a8ea567066758fc3df01c1b909496a42a5fb1
6
+ metadata.gz: c7f23e849d19e4a8a92b8bc86900ea15d1f1c3651641398d961b765fb402ceaa466d3c097179df092c1628746ce6e723ba409dc2a6481ecba3acf4915610b5a3
7
+ data.tar.gz: f88ac4656275a100c8de76758c836fb75c336f5ba882d1ece6cbf81fc4cb4bdc4bcee9065df7781519122530581ba2310c503c041dc5bbb64ffa16ec960895ab
@@ -0,0 +1,84 @@
1
+ ## Goal
2
+
3
+ <!-- What is the intent of this change?
4
+ e.g. "When initializing the Bugsnag client, it is currently difficult to (...)
5
+ this change simplifies the process by (...)"
6
+
7
+ "Improves the performance of data filtering"
8
+
9
+ "Adds additional test coverage to multi-threaded use of Configuration
10
+ objects"
11
+ -->
12
+
13
+ <!-- For new features, include design documentation:
14
+
15
+ ## Design
16
+
17
+ Why was this approach to the goal used?
18
+
19
+ -->
20
+
21
+ ## Changeset
22
+
23
+ <!-- What structures or properties or functions were:
24
+
25
+ ### Added
26
+
27
+ ### Removed
28
+
29
+ ### Changed
30
+
31
+ -->
32
+
33
+ ## Tests
34
+
35
+ <!-- How was this change tested? What manual and automated tests were
36
+ run/added? -->
37
+
38
+ ## Discussion
39
+
40
+ ### Alternative Approaches
41
+
42
+ <!-- What other approaches were considered or discussed? -->
43
+
44
+ ### Outstanding Questions
45
+
46
+ <!-- Are there any parts of the design or the implementation which seem
47
+ less than ideal and that could require additional discussion?
48
+ List here: -->
49
+
50
+ ### Linked issues
51
+
52
+ <!--
53
+
54
+ Fixes #
55
+ Related to #
56
+
57
+ -->
58
+
59
+ ## Review
60
+
61
+ <!-- When submitting for review, consider the points for self-review and the
62
+ criteria which will be used for secondary review -->
63
+
64
+ For the submitter, initial self-review:
65
+
66
+ - [ ] Commented on code changes inline explain the reasoning behind the approach
67
+ - [ ] Reviewed the test cases added for completeness and possible points for discussion
68
+ - [ ] A changelog entry was added for the goal of this pull request
69
+ - [ ] Check the scope of the changeset - is everything in the diff required for the pull request?
70
+ - This pull request is ready for:
71
+ - [ ] Initial review of the intended approach, not yet feature complete
72
+ - [ ] Structural review of the classes, functions, and properties modified
73
+ - [ ] Final review
74
+
75
+ For the pull request reviewer(s), this changeset has been reviewed for:
76
+
77
+ - [ ] Consistency across platforms for structures or concepts added or modified
78
+ - [ ] Consistency between the changeset and the goal stated above
79
+ - [ ] Internal consistency with the rest of the library - is there any overlap between existing interfaces and any which have been added?
80
+ - [ ] Usage friction - is the proposed change in usage cumbersome or complicated?
81
+ - [ ] Performance and complexity - are there any cases of unexpected O(n^3) when iterating, recursing, flat mapping, etc?
82
+ - [ ] Concurrency concerns - if components are accessed asynchronously, what issues will arise
83
+ - [ ] Thoroughness of added tests and any missing edge cases
84
+ - [ ] Idiomatic use of the language
@@ -1,6 +1,14 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ ## 6.7.3 (18 May 2018)
5
+
6
+ ### Fixes
7
+
8
+ * Apply metadata filters to HTTP referer fields
9
+ | [#460](https://github.com/bugsnag/bugsnag-ruby/pull/460)
10
+ | [Renee Balmert](https://github.com/tremlab)
11
+
4
12
  ## 6.7.2 (24 Apr 2018)
5
13
 
6
14
  ### Fixes
data/Gemfile CHANGED
@@ -1,7 +1,7 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  group :test, optional: true do
4
- gem 'rake', '~> 10.1.1'
4
+ gem 'rake', RUBY_VERSION <= '1.9.3' ? '~> 11.3.0' : '~> 12.3.0'
5
5
  gem 'rspec'
6
6
  gem 'rspec-mocks'
7
7
  gem 'rdoc', '~> 5.1.0'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 6.7.2
1
+ 6.7.3
@@ -30,7 +30,8 @@ unless defined? Delayed::Plugins::Bugsnag
30
30
  overrides[:job][:queue] = queue
31
31
  end
32
32
  if job.respond_to?(:attempts)
33
- overrides[:job][:attempts] = "#{job.attempts + 1} / #{Delayed::Worker.max_attempts}"
33
+ max_attempts = job.respond_to?(:max_attempts) ? job.max_attempts : Delayed::Worker.max_attempts
34
+ overrides[:job][:attempts] = "#{job.attempts + 1} / #{max_attempts}"
34
35
  # +1 as "attempts" is really previous attempts AFAICT, certainly it starts at 0.
35
36
  end
36
37
  if payload = job.payload_object
@@ -28,13 +28,22 @@ module Bugsnag::Middleware
28
28
  url = "#{request.scheme}://#{request.host}"
29
29
  url << ":#{request.port}" unless [80, 443].include?(request.port)
30
30
 
31
+ cleaner = Bugsnag::Cleaner.new(report.configuration.meta_data_filters)
32
+
31
33
  # If app is passed a bad URL, this code will crash attempting to clean it
32
34
  begin
33
- url << Bugsnag::Cleaner.new(report.configuration.meta_data_filters).clean_url(request.fullpath)
35
+ url << cleaner.clean_url(request.fullpath)
34
36
  rescue StandardError => stde
35
37
  Bugsnag.configuration.warn "RackRequest - Rescued error while cleaning request.fullpath: #{stde}"
36
38
  end
37
39
 
40
+ referer = nil
41
+ begin
42
+ referer = cleaner.clean_url(request.referer) if request.referer
43
+ rescue StandardError => stde
44
+ Bugsnag.configuration.warn "RackRequest - Rescued error while cleaning request.referer: #{stde}"
45
+ end
46
+
38
47
  headers = {}
39
48
 
40
49
  env.each_pair do |key, value|
@@ -49,12 +58,14 @@ module Bugsnag::Middleware
49
58
  headers[header_key.split("_").map {|s| s.capitalize}.join("-")] = value
50
59
  end
51
60
 
61
+ headers["Referer"] = referer if headers["Referer"]
62
+
52
63
  # Add a request tab
53
64
  report.add_tab(:request, {
54
65
  :url => url,
55
66
  :httpMethod => request.request_method,
56
67
  :params => params.to_hash,
57
- :referer => request.referer,
68
+ :referer => referer,
58
69
  :clientIp => client_ip,
59
70
  :headers => headers
60
71
  })
@@ -33,7 +33,6 @@ describe Bugsnag do
33
33
  end
34
34
 
35
35
  it 'attempts to load integrations' do
36
- Kernel::REQUIRED = []
37
36
  ENV["BUGSNAG_DISABLE_AUTOCONFIGURE"] = nil
38
37
  load "./lib/bugsnag.rb"
39
38
  Bugsnag::INTEGRATIONS.each do |integration|
@@ -42,36 +41,31 @@ describe Bugsnag do
42
41
  end
43
42
 
44
43
  it 'does not load integrations when BUGSNAG_DISABLE_AUTOCONFIGURE is true' do
45
- Kernel::REQUIRED = []
46
44
  ENV["BUGSNAG_DISABLE_AUTOCONFIGURE"] = 'true'
47
45
  load "./lib/bugsnag.rb"
48
46
  expect(Kernel::REQUIRED).to eq(["bugsnag/integrations/rack"])
49
47
  end
50
48
 
51
49
  it 'loads all integrations if requested' do
52
- Kernel::REQUIRED = []
53
- expect(Kernel::REQUIRED).to eq([])
54
50
  Bugsnag.load_integrations
55
51
  Bugsnag::INTEGRATIONS.each do |integration|
56
52
  expect(Kernel::REQUIRED).to include("bugsnag/integrations/#{integration}")
57
53
  end
58
54
  end
59
55
 
60
- it 'loads singular integrations' do
61
- Kernel::REQUIRED = []
62
- expect(Kernel::REQUIRED).to eq([])
63
- Bugsnag::INTEGRATIONS.each do |integration|
64
- Kernel::REQUIRED = []
56
+ Bugsnag::INTEGRATIONS.each do |integration|
57
+ it "loads #{integration}" do
65
58
  Bugsnag.load_integration(integration)
66
59
  expect(Kernel::REQUIRED).to include("bugsnag/integrations/#{integration}")
67
60
  end
68
61
  end
69
62
 
70
- it 'loads railtie for :rails or :railtie' do
71
- Kernel::REQUIRED = []
63
+ it 'loads railtie for rails' do
72
64
  Bugsnag.load_integration(:rails)
73
65
  expect(Kernel::REQUIRED).to include("bugsnag/integrations/railtie")
74
- Kernel::REQUIRED = []
66
+ end
67
+
68
+ it 'loads railtie for railtie' do
75
69
  Bugsnag.load_integration(:railtie)
76
70
  expect(Kernel::REQUIRED).to include("bugsnag/integrations/railtie")
77
71
  end
@@ -57,10 +57,10 @@ describe 'Bugsnag' do
57
57
 
58
58
  Bugsnag.notify 'yo'
59
59
 
60
- Process.fork do
60
+ pid = Process.fork do
61
61
  Bugsnag.notify 'yo too'
62
62
  end
63
- Process.wait
63
+ Process.wait(pid)
64
64
 
65
65
  expect(queue.length).to eq(2)
66
66
  end
@@ -4,12 +4,115 @@ require 'spec_helper'
4
4
 
5
5
  RSpec.describe ::Delayed::Plugins::Bugsnag do
6
6
  describe '#error' do
7
- it 'should not raise exception' do
7
+ it 'should set metadata correctly with max_attempts' do
8
8
  payload = Object.new
9
9
  payload.extend(described_class::Notify)
10
+ job = double
11
+ allow(job).to receive_messages(
12
+ :id => "TEST",
13
+ :queue => "TEST_QUEUE",
14
+ :attempts => 0,
15
+ :max_attempts => 3,
16
+ :payload_object => {
17
+ :id => "PAYLOAD_ID",
18
+ :display_name => "PAYLOAD_DISPLAY_NAME",
19
+ :method_name => "PAYLOAD_METHOD_NAME",
20
+ :args => [
21
+ "SOME",
22
+ "TEST",
23
+ "ARGS"
24
+ ]
25
+ }
26
+ )
27
+
28
+ expect do
29
+ payload.error(job, '')
30
+ end.not_to raise_error
31
+
32
+ expect(Bugsnag).to have_sent_notification{ |payload, headers|
33
+ event = get_event_from_payload(payload)
34
+ expect(event["severity"]).to eq("error")
35
+ expect(event["severityReason"]).to eq({
36
+ "type" => "unhandledExceptionMiddleware",
37
+ "attributes" => {
38
+ "framework" => "DelayedJob"
39
+ }
40
+ })
41
+ expect(event["metaData"]["job"]).to eq({
42
+ "class" => job.class.name,
43
+ "id" => "TEST",
44
+ "queue" => "TEST_QUEUE",
45
+ "attempts" => "1 / 3",
46
+ "payload" => {
47
+ "class" => {}.class.name,
48
+ "args" => {
49
+ "id" => "PAYLOAD_ID",
50
+ "display_name" => "PAYLOAD_DISPLAY_NAME",
51
+ "method_name" => "PAYLOAD_METHOD_NAME",
52
+ "args" => [
53
+ "SOME",
54
+ "TEST",
55
+ "ARGS"
56
+ ]
57
+ }
58
+ }
59
+ })
60
+ }
61
+ end
62
+
63
+ it 'should set metadata correctly without max_attempts' do
64
+ payload = Object.new
65
+ payload.extend(described_class::Notify)
66
+ job = double
67
+ allow(job).to receive_messages(
68
+ :id => "TEST",
69
+ :queue => "TEST_QUEUE",
70
+ :attempts => 0,
71
+ :payload_object => {
72
+ :id => "PAYLOAD_ID",
73
+ :display_name => "PAYLOAD_DISPLAY_NAME",
74
+ :method_name => "PAYLOAD_METHOD_NAME",
75
+ :args => [
76
+ "SOME",
77
+ "TEST",
78
+ "ARGS"
79
+ ]
80
+ }
81
+ )
82
+
10
83
  expect do
11
- payload.error(double('job', id: 1, payload_object: nil), '')
84
+ payload.error(job, '')
12
85
  end.not_to raise_error
86
+
87
+ expect(Bugsnag).to have_sent_notification{ |payload, headers|
88
+ event = get_event_from_payload(payload)
89
+ expect(event["severity"]).to eq("error")
90
+ expect(event["severityReason"]).to eq({
91
+ "type" => "unhandledExceptionMiddleware",
92
+ "attributes" => {
93
+ "framework" => "DelayedJob"
94
+ }
95
+ })
96
+ expect(event["metaData"]["job"]).to eq({
97
+ "class" => job.class.name,
98
+ "id" => "TEST",
99
+ "queue" => "TEST_QUEUE",
100
+ "attempts" => "1 / #{Delayed::Worker.max_attempts}",
101
+ "payload" => {
102
+ "class" => {}.class.name,
103
+ "args" => {
104
+ "id" => "PAYLOAD_ID",
105
+ "display_name" => "PAYLOAD_DISPLAY_NAME",
106
+ "method_name" => "PAYLOAD_METHOD_NAME",
107
+ "args" => [
108
+ "SOME",
109
+ "TEST",
110
+ "ARGS"
111
+ ]
112
+ }
113
+ }
114
+ })
115
+ }
13
116
  end
14
117
  end
15
118
  end
@@ -62,13 +62,74 @@ describe Bugsnag::Rack do
62
62
  before do
63
63
  unless defined?(::Rack)
64
64
  @mocked_rack = true
65
- class ::Rack
66
- class ::Request
65
+ class Rack
66
+ class Request
67
67
  end
68
68
  end
69
69
  end
70
70
  end
71
71
 
72
+ it "correctly redacts from url and referer any value indicated by meta_data_filters" do
73
+ callback = double
74
+ rack_env = {
75
+ :env => true,
76
+ :HTTP_REFERER => "https://bugsnag.com/about?email=hello@world.com&another_param=thing",
77
+ "rack.session" => {
78
+ :session => true
79
+ }
80
+ }
81
+
82
+ rack_request = double
83
+ rack_params = {
84
+ :param => 'test'
85
+ }
86
+ allow(rack_request).to receive_messages(
87
+ :params => rack_params,
88
+ :ip => "rack_ip",
89
+ :request_method => "TEST",
90
+ :path => "/TEST_PATH",
91
+ :scheme => "http",
92
+ :host => "test_host",
93
+ :port => 80,
94
+ :referer => "https://bugsnag.com/about?email=hello@world.com&another_param=thing",
95
+ :fullpath => "/TEST_PATH?email=hello@world.com&another_param=thing"
96
+ )
97
+ expect(::Rack::Request).to receive(:new).with(rack_env).and_return(rack_request)
98
+
99
+ # modify rack_env to include redacted referer
100
+ report = double("Bugsnag::Report")
101
+ allow(report).to receive(:request_data).and_return({
102
+ :rack_env => rack_env
103
+ })
104
+ expect(report).to receive(:context=).with("TEST /TEST_PATH")
105
+ expect(report).to receive(:user).and_return({})
106
+
107
+ config = double
108
+ allow(config).to receive(:send_environment).and_return(true)
109
+ allow(config).to receive(:meta_data_filters).and_return(['email'])
110
+ allow(report).to receive(:configuration).and_return(config)
111
+ expect(report).to receive(:add_tab).once.with(:request, {
112
+ :url => "http://test_host/TEST_PATH?email=[FILTERED]&another_param=thing",
113
+ :httpMethod => "TEST",
114
+ :params => rack_params,
115
+ :referer => "https://bugsnag.com/about?email=[FILTERED]&another_param=thing",
116
+ :clientIp => "rack_ip",
117
+ :headers => {
118
+ "Referer" => "https://bugsnag.com/about?email=[FILTERED]&another_param=thing"
119
+ }
120
+ })
121
+ # rack_env["HTTP_REFERER"] = "https://bugsnag.com/about?email=[FILTERED]&another_param=thing"
122
+ expect(report).to receive(:add_tab).once.with(:environment, rack_env)
123
+ expect(report).to receive(:add_tab).once.with(:session, {
124
+ :session => true
125
+ })
126
+
127
+ expect(callback).to receive(:call).with(report)
128
+
129
+ middleware = Bugsnag::Middleware::RackRequest.new(callback)
130
+ middleware.call(report)
131
+ end
132
+
72
133
  it "correctly extracts data from rack middleware" do
73
134
  callback = double
74
135
  rack_env = {
@@ -78,7 +139,7 @@ describe Bugsnag::Rack do
78
139
  :session => true
79
140
  }
80
141
  }
81
-
142
+
82
143
  rack_request = double
83
144
  rack_params = {
84
145
  :param => 'test'
@@ -94,7 +155,7 @@ describe Bugsnag::Rack do
94
155
  :referer => "referer",
95
156
  :fullpath => "/TEST_PATH"
96
157
  )
97
- expect(::Rack::Request).to receive(:new).with(rack_env).and_return(rack_request)
158
+ expect(Rack::Request).to receive(:new).with(rack_env).and_return(rack_request)
98
159
 
99
160
  report = double("Bugsnag::Report")
100
161
  allow(report).to receive(:request_data).and_return({
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: 6.7.2
4
+ version: 6.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-24 00:00:00.000000000 Z
11
+ date: 2018-05-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -33,6 +33,7 @@ extra_rdoc_files:
33
33
  - README.md
34
34
  - CHANGELOG.md
35
35
  files:
36
+ - ".github/PULL_REQUEST_TEMPLATE.md"
36
37
  - ".gitignore"
37
38
  - ".rdoc_options"
38
39
  - ".rspec"
@@ -151,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
151
152
  version: '0'
152
153
  requirements: []
153
154
  rubyforge_project:
154
- rubygems_version: 2.6.11
155
+ rubygems_version: 2.4.5
155
156
  signing_key:
156
157
  specification_version: 4
157
158
  summary: Ruby notifier for bugsnag.com