def open_uri(uri, options, follows_remaining: 0)
      uri.open(options)
    rescue OpenURI::HTTPRedirect => exception
      raise Down::TooManyRedirects, "too many redirects" if follows_remaining == 0

      # fail if redirect URI scheme is not http or https
      begin
        uri = ensure_uri(exception.uri)
      rescue Down::InvalidUrl
        response = rebuild_response_from_open_uri_exception(exception)

        raise ResponseError.new("Invalid Redirect URI: #{exception.uri}", response: response)
      end

      # forward cookies on the redirect
      if !exception.io.meta["set-cookie"].to_s.empty?
        options["Cookie"] = exception.io.meta["set-cookie"]
      end

      follows_remaining -= 1
      retry
    rescue OpenURI::HTTPError => exception
      response = rebuild_response_from_open_uri_exception(exception)

      # open-uri attempts to parse the redirect URI, so we re-raise that exception
      if exception.message.include?("(Invalid Location URI)")
        raise ResponseError.new("Invalid Redirect URI: #{response["Location"]}", response: response)
      end

      response_error!(response)
    rescue => exception
      request_error!(exception)
    end
def open_uri(uri, options, follows_remaining: 0)
      uri.open(options)
    rescue OpenURI::HTTPRedirect => exception
      raise Down::TooManyRedirects, "too many redirects" if follows_remaining == 0

      # fail if redirect URI scheme is not http or https
      begin
        uri = ensure_uri(exception.uri)
      rescue Down::InvalidUrl
        response = rebuild_response_from_open_uri_exception(exception)

        raise ResponseError.new("Invalid Redirect URI: #{exception.uri}", response: response)
      end

      # forward cookies on the redirect
      if !exception.io.meta["set-cookie"].to_s.empty?
        options["Cookie"] = exception.io.meta["set-cookie"]
      end

      follows_remaining -= 1
      retry
    rescue OpenURI::HTTPError => exception
      response = rebuild_response_from_open_uri_exception(exception)

      # open-uri attempts to parse the redirect URI, so we re-raise that exception
      if exception.message.include?("(Invalid Location URI)")
        raise ResponseError.new("Invalid Redirect URI: #{response["Location"]}", response: response)
      end

      response_error!(response)
    rescue => exception
      request_error!(exception)
    end
Calls open-uri's URI::HTTP#open method. Additionally handles redirects.