global

def do_http_request(method, base, path, body:, extra_headers:)

def do_http_request(method, base, path, body:, extra_headers:)
  uri  = URI.parse("#{base}#{path}")
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl      = uri.scheme == "https"
  http.open_timeout = OPEN_TIMEOUT
  http.read_timeout = READ_TIMEOUT

  req_class = { "POST" => Net::HTTP::Post, "PATCH" => Net::HTTP::Patch,
                "DELETE" => Net::HTTP::Delete }[method]
  req = req_class.new(uri.path)
  hmac_headers.each { |k, v| req[k] = v }
  extra_headers.each { |k, v| req[k] = v }
  req.body = body.to_json if body

  response = http.request(req)
  parsed   = JSON.parse(response.body) rescue { "raw" => response.body }
  [response.code.to_i, parsed]
rescue Net::OpenTimeout, Net::ReadTimeout,
       Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH,
       Errno::ECONNRESET, EOFError, OpenSSL::SSL::SSLError => e
  raise RetryableError, e.message
end