require "net/https" module Bugsnag module Delivery class Synchronous class << self ## # Attempts to deliver a payload to the given endpoint synchronously. def deliver(url, body, configuration, options={}) begin response = request(url, body, configuration, options) configuration.debug("Request to #{url} completed, status: #{response.code}") if response.code[0] != "2" configuration.warn("Notifications to #{url} was reported unsuccessful with code #{response.code}") end rescue StandardError => e # KLUDGE: Since we don't re-raise http exceptions, this breaks rspec raise if e.class.to_s == "RSpec::Expectations::ExpectationNotMetError" configuration.error("Unable to send information to Bugsnag (#{url}), #{e.inspect}") configuration.error(e.backtrace) end end private def request(url, body, configuration, options) uri = URI.parse(url) if configuration.proxy_host http = Net::HTTP.new(uri.host, uri.port, configuration.proxy_host, configuration.proxy_port, configuration.proxy_user, configuration.proxy_password) else http = Net::HTTP.new(uri.host, uri.port) end http.read_timeout = configuration.timeout http.open_timeout = configuration.timeout if uri.scheme == "https" http.use_ssl = true http.ca_file = configuration.ca_file if configuration.ca_file end headers = options.key?(:headers) ? options[:headers] : {} headers.merge!(default_headers) request = Net::HTTP::Post.new(path(uri), headers) request.body = body http.request(request) end def path(uri) uri.path == "" ? "/" : uri.path end def default_headers { "Content-Type" => "application/json", "Bugsnag-Sent-At" => Time.now.utc.iso8601(3) } end end end end end Bugsnag::Delivery.register(:synchronous, Bugsnag::Delivery::Synchronous)