diff --git a/CHANGELOG.md b/CHANGELOG.md
index bcc8b1ac..81b68a88 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,7 @@
## Next Release
+* Added an option to stop adding HTTP headers to API requests
+
## 6.1.3 (01/21/2021)
* Consider ThroughAssociation at SingularAssociation like CollectionAssociation
diff --git a/README.md b/README.md
index bd7d356d..5eb728eb 100644
--- a/README.md
+++ b/README.md
@@ -94,6 +94,7 @@ The code above will enable all of the Bullet notification systems:
* `Bullet.sentry`: add notifications to sentry
* `Bullet.add_footer`: adds the details in the bottom left corner of the page. Double click the footer or use close button to hide footer.
* `Bullet.skip_html_injection`: prevents Bullet from injecting code into the returned HTML. This must be false for receiving alerts, showing the footer or console logging.
+* `Bullet.skip_http_headers`: don't add headers to API requests, and remove the javascript that relies on them. Note that this prevents bullet from logging warnings to the browser console or updating the footer.
* `Bullet.stacktrace_includes`: include paths with any of these substrings in the stack trace, even if they are not in your main app
* `Bullet.stacktrace_excludes`: ignore paths with any of these substrings in the stack trace, even if they are not in your main app.
Each item can be a string (match substring), a regex, or an array where the first item is a path to match, and the second
diff --git a/lib/bullet.rb b/lib/bullet.rb
index 00eff27f..15c6f63a 100644
--- a/lib/bullet.rb
+++ b/lib/bullet.rb
@@ -39,7 +39,7 @@ class << self
:stacktrace_excludes,
:skip_html_injection
attr_reader :whitelist
- attr_accessor :add_footer, :orm_patches_applied
+ attr_accessor :add_footer, :orm_patches_applied, :skip_http_headers
available_notifiers = UniformNotifier::AVAILABLE_NOTIFIERS.select { |notifier| notifier != :raise }.map { |notifier| "#{notifier}=" }
available_notifiers_options = { to: UniformNotifier }
diff --git a/lib/bullet/rack.rb b/lib/bullet/rack.rb
index 1139bf35..83f31cc3 100644
--- a/lib/bullet/rack.rb
+++ b/lib/bullet/rack.rb
@@ -22,9 +22,9 @@ def call(env)
response_body = response_body(response)
response_body = append_to_html_body(response_body, footer_note) if Bullet.add_footer
response_body = append_to_html_body(response_body, Bullet.gather_inline_notifications)
- response_body = append_to_html_body(response_body, xhr_script) if Bullet.add_footer
+ response_body = append_to_html_body(response_body, xhr_script) if Bullet.add_footer && !Bullet.skip_http_headers
headers['Content-Length'] = response_body.bytesize.to_s
- else
+ elsif !Bullet.skip_http_headers
set_header(headers, 'X-bullet-footer-text', Bullet.footer_info.uniq) if Bullet.add_footer
set_header(headers, 'X-bullet-console-text', Bullet.text_notifications) if Bullet.console_enabled?
end
diff --git a/spec/bullet/rack_spec.rb b/spec/bullet/rack_spec.rb
index f12af10e..f04d0f37 100644
--- a/spec/bullet/rack_spec.rb
+++ b/spec/bullet/rack_spec.rb
@@ -90,7 +90,7 @@ module Bullet
before do
expect(Bullet).to receive(:notification?).and_return(true)
allow(Bullet).to receive(:gather_inline_notifications).and_return('')
- allow(middleware).to receive(:xhr_script).and_return('')
+ allow(middleware).to receive(:xhr_script).and_return('')
allow(middleware).to receive(:footer_note).and_return('footer')
expect(Bullet).to receive(:perform_out_of_channel_notifications)
end
@@ -99,9 +99,8 @@ module Bullet
expect(Bullet).to receive(:add_footer).exactly(3).times.and_return(true)
_, headers, response = middleware.call('Content-Type' => 'text/html')
- expect(headers['Content-Length']).to eq((56 + middleware.send(:footer_note).length).to_s)
- expect(response.first).to start_with('
')
- expect(response.first).to include('<')
+ expect(headers['Content-Length']).to eq((73 + middleware.send(:footer_note).length).to_s)
+ expect(response).to eq(%w[footer])
end
it 'should change response body for html safe string if add_footer is true' do
@@ -111,9 +110,16 @@ module Bullet
end
_, headers, response = middleware.call('Content-Type' => 'text/html')
- expect(headers['Content-Length']).to eq((56 + middleware.send(:footer_note).length).to_s)
- expect(response.first).to start_with('')
- expect(response.first).to include('<')
+ expect(headers['Content-Length']).to eq((73 + middleware.send(:footer_note).length).to_s)
+ expect(response).to eq(%w[footer])
+ end
+
+ it 'should add the footer-text header for non-html requests when add_footer is true' do
+ allow(Bullet).to receive(:add_footer).at_least(:once).and_return(true)
+ allow(Bullet).to receive(:footer_info).and_return(['footer text'])
+ app.headers = {'Content-Type' => 'application/json'}
+ _, headers, _response = middleware.call({})
+ expect(headers).to include('X-bullet-footer-text' => '["footer text"]')
end
it 'should change response body if console_enabled is true' do
@@ -133,12 +139,62 @@ module Bullet
expect(response).to eq(%w[])
end
+ it 'should add headers for non-html requests when console_enabled is true' do
+ allow(Bullet).to receive(:console_enabled?).at_least(:once).and_return(true)
+ allow(Bullet).to receive(:text_notifications).and_return(['text notifications'])
+ app.headers = {'Content-Type' => 'application/json'}
+ _, headers, _response = middleware.call({})
+ expect(headers).to include('X-bullet-console-text' => '["text notifications"]')
+ end
+
it "shouldn't change response body unnecessarily" do
expected_response = Support::ResponseDouble.new 'Actual body'
app.response = expected_response
_, _, response = middleware.call({})
expect(response).to eq(expected_response)
end
+
+ it "shouldn't add headers unnecessarily" do
+ app.headers = {'Content-Type' => 'application/json'}
+ _, headers, _response = middleware.call({})
+ expect(headers).not_to include('X-bullet-footer-text')
+ expect(headers).not_to include('X-bullet-console-text')
+ end
+
+ context "when skip_http_headers is enabled" do
+ before do
+ allow(Bullet).to receive(:skip_http_headers).and_return(true)
+ end
+
+ it 'should include the footer but not the xhr script tag if add_footer is true' do
+ expect(Bullet).to receive(:add_footer).at_least(:once).and_return(true)
+ _, headers, response = middleware.call({})
+
+ expect(headers['Content-Length']).to eq((56 + middleware.send(:footer_note).length).to_s)
+ expect(response).to eq(%w[footer])
+ end
+
+ it 'should not include the xhr script tag if console_enabled is true' do
+ expect(Bullet).to receive(:console_enabled?).and_return(true)
+ _, headers, response = middleware.call({})
+ expect(headers['Content-Length']).to eq('56')
+ expect(response).to eq(%w[])
+ end
+
+ it 'should not add the footer-text header for non-html requests when add_footer is true' do
+ allow(Bullet).to receive(:add_footer).at_least(:once).and_return(true)
+ app.headers = {'Content-Type' => 'application/json'}
+ _, headers, _response = middleware.call({})
+ expect(headers).not_to include('X-bullet-footer-text')
+ end
+
+ it 'should not add headers for non-html requests when console_enabled is true' do
+ allow(Bullet).to receive(:console_enabled?).at_least(:once).and_return(true)
+ app.headers = {'Content-Type' => 'application/json'}
+ _, headers, _response = middleware.call({})
+ expect(headers).not_to include('X-bullet-console-text')
+ end
+ end
end
context 'when skip_html_injection is enabled' do