bugsnag-maglev- 2.8.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.gitignore +52 -0
  4. data/.rspec +3 -0
  5. data/.travis.yml +15 -0
  6. data/CHANGELOG.md +425 -0
  7. data/CONTRIBUTING.md +43 -0
  8. data/Gemfile +2 -0
  9. data/LICENSE.txt +20 -0
  10. data/README.md +804 -0
  11. data/Rakefile +29 -0
  12. data/VERSION +1 -0
  13. data/bugsnag.gemspec +32 -0
  14. data/lib/bugsnag.rb +129 -0
  15. data/lib/bugsnag/capistrano.rb +7 -0
  16. data/lib/bugsnag/capistrano2.rb +32 -0
  17. data/lib/bugsnag/configuration.rb +129 -0
  18. data/lib/bugsnag/delay/resque.rb +21 -0
  19. data/lib/bugsnag/delayed_job.rb +57 -0
  20. data/lib/bugsnag/delivery.rb +18 -0
  21. data/lib/bugsnag/delivery/synchronous.rb +51 -0
  22. data/lib/bugsnag/delivery/thread_queue.rb +53 -0
  23. data/lib/bugsnag/deploy.rb +35 -0
  24. data/lib/bugsnag/helpers.rb +127 -0
  25. data/lib/bugsnag/mailman.rb +28 -0
  26. data/lib/bugsnag/meta_data.rb +7 -0
  27. data/lib/bugsnag/middleware/callbacks.rb +19 -0
  28. data/lib/bugsnag/middleware/mailman.rb +13 -0
  29. data/lib/bugsnag/middleware/rack_request.rb +72 -0
  30. data/lib/bugsnag/middleware/rails2_request.rb +52 -0
  31. data/lib/bugsnag/middleware/rails3_request.rb +42 -0
  32. data/lib/bugsnag/middleware/rake.rb +23 -0
  33. data/lib/bugsnag/middleware/sidekiq.rb +13 -0
  34. data/lib/bugsnag/middleware/warden_user.rb +39 -0
  35. data/lib/bugsnag/middleware_stack.rb +98 -0
  36. data/lib/bugsnag/notification.rb +452 -0
  37. data/lib/bugsnag/rack.rb +53 -0
  38. data/lib/bugsnag/rails.rb +66 -0
  39. data/lib/bugsnag/rails/action_controller_rescue.rb +62 -0
  40. data/lib/bugsnag/rails/active_record_rescue.rb +20 -0
  41. data/lib/bugsnag/rails/controller_methods.rb +44 -0
  42. data/lib/bugsnag/railtie.rb +78 -0
  43. data/lib/bugsnag/rake.rb +25 -0
  44. data/lib/bugsnag/resque.rb +40 -0
  45. data/lib/bugsnag/sidekiq.rb +38 -0
  46. data/lib/bugsnag/tasks.rb +3 -0
  47. data/lib/bugsnag/tasks/bugsnag.cap +48 -0
  48. data/lib/bugsnag/tasks/bugsnag.rake +89 -0
  49. data/lib/bugsnag/version.rb +3 -0
  50. data/lib/generators/bugsnag/bugsnag_generator.rb +24 -0
  51. data/rails/init.rb +3 -0
  52. data/spec/code_spec.rb +86 -0
  53. data/spec/fixtures/crashes/end_of_file.rb +9 -0
  54. data/spec/fixtures/crashes/short_file.rb +1 -0
  55. data/spec/fixtures/crashes/start_of_file.rb +9 -0
  56. data/spec/fixtures/middleware/internal_info_setter.rb +11 -0
  57. data/spec/fixtures/middleware/public_info_setter.rb +11 -0
  58. data/spec/fixtures/tasks/Rakefile +15 -0
  59. data/spec/helper_spec.rb +144 -0
  60. data/spec/integration_spec.rb +110 -0
  61. data/spec/middleware_spec.rb +181 -0
  62. data/spec/notification_spec.rb +822 -0
  63. data/spec/rack_spec.rb +56 -0
  64. data/spec/spec_helper.rb +53 -0
  65. metadata +198 -0
@@ -0,0 +1,89 @@
1
+ require "bugsnag"
2
+
3
+ namespace :bugsnag do
4
+ desc "Notify Bugsnag of a new deploy."
5
+ task :deploy do
6
+ api_key = ENV["BUGSNAG_API_KEY"]
7
+ release_stage = ENV["BUGSNAG_RELEASE_STAGE"]
8
+ app_version = ENV["BUGSNAG_APP_VERSION"]
9
+ revision = ENV["BUGSNAG_REVISION"]
10
+ repository = ENV["BUGSNAG_REPOSITORY"]
11
+ branch = ENV["BUGSNAG_BRANCH"]
12
+
13
+ Rake::Task["load"].invoke unless api_key
14
+
15
+ Bugsnag::Deploy.notify({
16
+ :api_key => api_key,
17
+ :release_stage => release_stage,
18
+ :app_version => app_version,
19
+ :revision => revision,
20
+ :repository => repository,
21
+ :branch => branch
22
+ })
23
+ end
24
+
25
+ desc "Send a test exception to Bugsnag."
26
+ task :test_exception => :load do
27
+ begin
28
+ raise RuntimeError.new("Bugsnag test exception")
29
+ rescue => e
30
+ Bugsnag.notify(e, {:context => "rake#test_exception"})
31
+ end
32
+ end
33
+
34
+ desc "Show the bugsnag middleware stack"
35
+ task :middleware => :load do
36
+ Bugsnag.configuration.middleware.each {|m| puts m.to_s}
37
+ end
38
+
39
+ namespace :heroku do
40
+ desc "Add a heroku deploy hook to notify Bugsnag of deploys"
41
+ task :add_deploy_hook => :load do
42
+ # Wrapper to run command safely even in bundler
43
+ run_command = lambda { |command|
44
+ defined?(Bundler.with_clean_env) ? Bundler.with_clean_env { `#{command}` } : `#{command}`
45
+ }
46
+
47
+ # Fetch heroku config settings
48
+ config_command = "heroku config --shell"
49
+ config_command += " --app #{ENV["HEROKU_APP"]}" if ENV["HEROKU_APP"]
50
+ heroku_env = run_command.call(config_command).split(/[\n\r]/).each_with_object({}) do |c, obj|
51
+ k,v = c.split("=")
52
+ obj[k] = v.strip.empty? ? nil : v
53
+ end
54
+
55
+ # Check for Bugsnag API key (required)
56
+ api_key = heroku_env["BUGSNAG_API_KEY"] || Bugsnag.configuration.api_key || ENV["BUGSNAG_API_KEY"]
57
+ unless api_key
58
+ puts "Error: No API key found, have you run 'heroku config:set BUGSNAG_API_KEY=your-api-key'?"
59
+ next
60
+ end
61
+
62
+ # Build the request, making use of deploy hook variables
63
+ # (https://devcenter.heroku.com/articles/deploy-hooks#customizing-messages)
64
+ params = {
65
+ :apiKey => api_key,
66
+ :branch => "master",
67
+ :revision => "{{head_long}}",
68
+ :releaseStage => heroku_env["RAILS_ENV"] || ENV["RAILS_ENV"] || "production"
69
+ }
70
+ repo = `git config --get remote.origin.url`.strip
71
+ params[:repository] = repo unless repo.empty?
72
+
73
+ # Add the hook
74
+ url = "https://notify.bugsnag.com/deploy?" + params.map {|k,v| "#{k}=#{v}"}.join("&")
75
+ command = "heroku addons:add deployhooks:http --url=\"#{url}\""
76
+ command += " --app #{ENV["HEROKU_APP"]}" if ENV["HEROKU_APP"]
77
+
78
+ puts "$ #{command}"
79
+ run_command.call(command)
80
+ end
81
+ end
82
+ end
83
+
84
+ task :load do
85
+ begin
86
+ Rake::Task["environment"].invoke
87
+ rescue
88
+ end
89
+ end
@@ -0,0 +1,3 @@
1
+ module Bugsnag
2
+ VERSION = File.read(File.join(File.dirname(__FILE__), "../../VERSION")).strip
3
+ end
@@ -0,0 +1,24 @@
1
+ require 'rails/generators'
2
+ class BugsnagGenerator < Rails::Generators::Base
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ argument :api_key, required: true, :desc => "required"
6
+
7
+ gem "bugsnag"
8
+
9
+ desc "Configures the bugsnag notifier with your API key"
10
+
11
+ def create_initializer_file
12
+ unless /^[a-f0-9]{32}$/ =~ api_key
13
+ raise Thor::Error, "Invalid bugsnag notifier api key #{api_key.inspect}\nYou can find the api key on the Settings tab of https://bugsnag.com/"
14
+ end
15
+
16
+ initializer "bugsnag.rb" do
17
+ <<-EOF
18
+ Bugsnag.configure do |config|
19
+ config.api_key = #{api_key.inspect}
20
+ end
21
+ EOF
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ # On Rails 2.x GEM_ROOT/rails/init.rb is auto loaded for all gems
2
+ # so this is the place to initialize Rails 2.x plugin support
3
+ require "bugsnag/rails"
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe Bugsnag::Notification do
4
+ it "includes code in the stack trace" do
5
+ _a = 1
6
+ _b = 2
7
+ _c = 3
8
+ notify_test_exception
9
+ _d = 4
10
+ _e = 5
11
+ _f = 6
12
+
13
+ expect(Bugsnag).to have_sent_notification{ |payload|
14
+ exception = get_exception_from_payload(payload)
15
+ starting_line = __LINE__ - 10
16
+ expect(exception["stacktrace"][1]["code"]).to eq({
17
+ (starting_line + 0).to_s => " _a = 1",
18
+ (starting_line + 1).to_s => " _b = 2",
19
+ (starting_line + 2).to_s => " _c = 3",
20
+ (starting_line + 3).to_s => " notify_test_exception",
21
+ (starting_line + 4).to_s => " _d = 4",
22
+ (starting_line + 5).to_s => " _e = 5",
23
+ (starting_line + 6).to_s => " _f = 6"
24
+ })
25
+ }
26
+ end
27
+
28
+ it "allows you to disable sending code" do
29
+ Bugsnag.configuration.send_code = false
30
+
31
+ notify_test_exception
32
+
33
+ expect(Bugsnag).to have_sent_notification{ |payload|
34
+ exception = get_exception_from_payload(payload)
35
+ expect(exception["stacktrace"][1]["code"]).to eq(nil)
36
+ }
37
+ end
38
+
39
+ it 'should send the first 7 lines of the file for exceptions near the top' do
40
+ load 'spec/fixtures/crashes/start_of_file.rb' rescue Bugsnag.notify $!
41
+
42
+ expect(Bugsnag).to have_sent_notification{ |payload|
43
+ exception = get_exception_from_payload(payload)
44
+
45
+ expect(exception["stacktrace"][0]["code"]).to eq({
46
+ "1" => "#",
47
+ "2" => "raise 'hell'",
48
+ "3" => "#",
49
+ "4" => "#",
50
+ "5" => "#",
51
+ "6" => "#",
52
+ "7" => "#"
53
+ })
54
+ }
55
+ end
56
+
57
+ it 'should send the last 7 lines of the file for exceptions near the bottom' do
58
+ load 'spec/fixtures/crashes/end_of_file.rb' rescue Bugsnag.notify $!
59
+
60
+ expect(Bugsnag).to have_sent_notification{ |payload|
61
+ exception = get_exception_from_payload(payload)
62
+
63
+ expect(exception["stacktrace"][0]["code"]).to eq({
64
+ "3" => "#",
65
+ "4" => "#",
66
+ "5" => "#",
67
+ "6" => "#",
68
+ "7" => "#",
69
+ "8" => "raise 'hell'",
70
+ "9" => "#"
71
+ })
72
+ }
73
+ end
74
+
75
+ it 'should send the last 7 lines of the file for exceptions near the bottom' do
76
+ load 'spec/fixtures/crashes/short_file.rb' rescue Bugsnag.notify $!
77
+
78
+ expect(Bugsnag).to have_sent_notification{ |payload|
79
+ exception = get_exception_from_payload(payload)
80
+
81
+ expect(exception["stacktrace"][0]["code"]).to eq({
82
+ "1" => "raise 'hell'"
83
+ })
84
+ }
85
+ end
86
+ end
@@ -0,0 +1,9 @@
1
+ #
2
+ #
3
+ #
4
+ #
5
+ #
6
+ #
7
+ #
8
+ raise 'hell'
9
+ #
@@ -0,0 +1 @@
1
+ raise 'hell'
@@ -0,0 +1,9 @@
1
+ #
2
+ raise 'hell'
3
+ #
4
+ #
5
+ #
6
+ #
7
+ #
8
+ #
9
+ #
@@ -0,0 +1,11 @@
1
+ class InternalInfoSetter
2
+ MESSAGE = "set by internal_middleware"
3
+ def initialize(bugsnag)
4
+ @bugsnag = bugsnag
5
+ end
6
+
7
+ def call(notification)
8
+ notification.meta_data[:custom][:info] = MESSAGE
9
+ @bugsnag.call(notification)
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class PublicInfoSetter
2
+ MESSAGE = "set by middleware"
3
+ def initialize(bugsnag)
4
+ @bugsnag = bugsnag
5
+ end
6
+
7
+ def call(notification)
8
+ notification.meta_data[:custom][:info] = MESSAGE
9
+ @bugsnag.call(notification)
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ require "bugsnag/rake"
2
+
3
+ namespace :test do
4
+ desc "used by integration_spec to test that Bugsnag::Middleware::Rake runs properly"
5
+ task :crash do
6
+ port = ENV['BUGSNAG_TEST_SERVER_PORT']
7
+ Bugsnag.configure do |config|
8
+ config.endpoint = "localhost:#{port}"
9
+ config.api_key = "0" * 32
10
+ config.use_ssl = false
11
+ end
12
+
13
+ raise
14
+ end
15
+ end
@@ -0,0 +1,144 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
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
+ it "reduces hash size correctly" do
69
+ meta_data = {
70
+ :key_one => "this should not be truncated",
71
+ :key_two => ""
72
+ }
73
+
74
+ 1000.times {|i| meta_data[:key_two] += "this should be truncated " }
75
+
76
+ expect(meta_data[:key_two].length).to be > 4096
77
+
78
+ meta_data_return = Bugsnag::Helpers.reduce_hash_size meta_data
79
+
80
+ expect(meta_data_return[:key_one].length).to eq(28)
81
+ expect(meta_data_return[:key_one]).to eq("this should not be truncated")
82
+
83
+ expect(meta_data_return[:key_two].length).to eq(4107)
84
+ expect(meta_data_return[:key_two].match(/\[TRUNCATED\]$/).nil?).to eq(false)
85
+
86
+ expect(meta_data[:key_two].length).to be > 4096
87
+ expect(meta_data[:key_two].match(/\[TRUNCATED\]$/).nil?).to eq(true)
88
+
89
+ expect(meta_data[:key_one].length).to eq(28)
90
+ expect(meta_data[:key_one]).to eq("this should not be truncated")
91
+ 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
+ end
@@ -0,0 +1,110 @@
1
+ require 'webrick'
2
+ require 'spec_helper'
3
+ require 'json'
4
+
5
+ describe 'Bugsnag' do
6
+ server = nil
7
+ queue = Queue.new
8
+
9
+ before do
10
+ server = WEBrick::HTTPServer.new :Port => 0, :Logger => WEBrick::Log.new("/dev/null"), :AccessLog => []
11
+ server.mount_proc '/' do |req, res|
12
+ queue.push req.body
13
+ res.status = 200
14
+ res.body = "OK\n"
15
+ end
16
+ Thread.new{ server.start }
17
+ end
18
+ after do
19
+ server.stop
20
+ end
21
+
22
+ let(:request) { JSON.parse(queue.pop) }
23
+
24
+ it 'should run the rake middleware when rake tasks crash' do
25
+ ENV['BUGSNAG_TEST_SERVER_PORT'] = server.config[:Port].to_s
26
+ task_fixtures_path = File.join(File.dirname(__FILE__), 'fixtures', 'tasks')
27
+ Dir.chdir(task_fixtures_path) do
28
+ system("bundle exec rake test:crash > /dev/null 2>&1")
29
+ end
30
+ expect(request["events"][0]["metaData"]["rake_task"]).not_to be_nil
31
+ expect(request["events"][0]["metaData"]["rake_task"]["name"]).to eq("test:crash")
32
+ end
33
+
34
+ it 'should send notifications over the wire' do
35
+ Bugsnag.configure do |config|
36
+ config.endpoint = "localhost:#{server.config[:Port]}"
37
+ config.use_ssl = false
38
+ end
39
+ WebMock.allow_net_connect!
40
+
41
+ Bugsnag.notify 'yo'
42
+
43
+ expect(request['events'][0]['exceptions'][0]['message']).to eq('yo')
44
+ end
45
+
46
+ it 'should send deploys over the wire' do
47
+ Bugsnag.configure do |config|
48
+ config.endpoint = "localhost:#{server.config[:Port]}"
49
+ config.use_ssl = false
50
+ end
51
+ WebMock.allow_net_connect!
52
+
53
+ Bugsnag::Deploy.notify :app_version => '1.1.1'
54
+
55
+ expect(request['appVersion']).to eq('1.1.1')
56
+ end
57
+
58
+ it 'should work with threadpool delivery' do
59
+ Bugsnag.configure do |config|
60
+ config.endpoint = "localhost:#{server.config[:Port]}"
61
+ config.use_ssl = false
62
+ config.delivery_method = :thread_queue
63
+ end
64
+ WebMock.allow_net_connect!
65
+
66
+ Bugsnag.notify 'yo'
67
+
68
+ expect(request['events'][0]['exceptions'][0]['message']).to eq('yo')
69
+ end
70
+
71
+ describe 'with a proxy' do
72
+ proxy = nil
73
+ pqueue = Queue.new
74
+
75
+ before do
76
+ proxy = WEBrick::HTTPServer.new :Port => 0, :Logger => WEBrick::Log.new("/dev/null"), :AccessLog => []
77
+ proxy.mount_proc '/' do |req, res|
78
+ pqueue.push req
79
+ res.status = 200
80
+ res.body = "OK\n"
81
+ end
82
+ Thread.new{ proxy.start }
83
+ end
84
+ after do
85
+ proxy.stop
86
+ end
87
+
88
+ let(:proxied_request) { pqueue.pop }
89
+
90
+ it 'should use a proxy when configured' do
91
+ Bugsnag.configure do |config|
92
+
93
+ config.endpoint = "localhost:#{server.config[:Port]}"
94
+ config.use_ssl = false
95
+
96
+ config.proxy_host = 'localhost'
97
+ config.proxy_port = proxy.config[:Port]
98
+ config.proxy_user = 'conrad'
99
+ config.proxy_password = '$ecret'
100
+ end
101
+
102
+ Bugsnag.notify 'oy'
103
+
104
+ r = proxied_request
105
+
106
+ expect(r.header['proxy-authorization'].first).to eq("Basic Y29ucmFkOiRlY3JldA==")
107
+ expect(r.request_line).to eq("POST http://localhost:#{server.config[:Port]}/ HTTP/1.1\r\n")
108
+ end
109
+ end
110
+ end