# frozen_string_literal: true require "net/http" class Link < ApplicationRecord belongs_to :link_category has_and_belongs_to_many :checks has_rich_text :description validates :url, :text, presence: true validate :check_url validate :valid_url before_validation :ensure_absolute_url def t_text text end def ok? fail_count.zero? end def to_s "#{text} (#{url})" end private USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0" def check_url(input = url, add_error = true) response = begin Net::HTTP.get_response(URI.parse(input), 'User-Agent': USER_AGENT) rescue Socket::ResolutionError errors.add(:url, :invalid) if add_error return false end case response when Net::HTTPSuccess self.last_check_at = Time.zone.now self.fail_count = 0 true when Net::HTTPRedirection check_url(response[:location]) else self.last_check_at = Time.zone.now self.fail_count += 1 errors.add(:url, :invalid) if add_error false end end def ensure_absolute_url self.url = "https://#{url}" unless url.match?(%r{https{0,1}://.*}) end def valid_url errors.add(:url, :invalid) unless url.match(/\A#{URI::DEFAULT_PARSER.make_regexp(%w[http https])}\z/) end end