# typed: false # frozen_string_literal: true require_relative "page_match" module Homebrew module Livecheck module Strategy # The {HeaderMatch} strategy follows all URL redirections and scans # the resulting headers for matching text using the provided regex. # # @api private class HeaderMatch extend T::Sig NICE_NAME = "Header match" # A priority of zero causes livecheck to skip the strategy. We only # apply {HeaderMatch} using `strategy :header_match` in a `livecheck` # block, as we can't automatically determine when this can be # successfully applied to a URL. PRIORITY = 0 # The `Regexp` used to determine if the strategy applies to the URL. URL_MATCH_REGEX = %r{^https?://}i.freeze # Whether the strategy can be applied to the provided URL. # The strategy will technically match any HTTP URL but is # only usable with a `livecheck` block containing a regex # or block. sig { params(url: String).returns(T::Boolean) } def self.match?(url) URL_MATCH_REGEX.match?(url) end # Checks the final URL for new versions after following all redirections, # using the provided regex for matching. sig { params( url: String, regex: T.nilable(Regexp), cask: T.nilable(Cask::Cask), block: T.nilable(T.proc.params(arg0: T::Hash[String, String]) .returns(T.any(T::Array[String], String))), ).returns(T::Hash[Symbol, T.untyped]) } def self.find_versions(url, regex, cask: nil, &block) match_data = { matches: {}, regex: regex, url: url } headers = Strategy.page_headers(url) # Merge the headers from all responses into one hash merged_headers = headers.reduce(&:merge) if block match = yield merged_headers, regex else match = nil if (filename = merged_headers["content-disposition"]) if regex match ||= filename[regex, 1] else v = Version.parse(filename, detected_from_url: true) match ||= v.to_s unless v.null? end end if (location = merged_headers["location"]) if regex match ||= location[regex, 1] else v = Version.parse(location, detected_from_url: true) match ||= v.to_s unless v.null? end end end match_data[:matches][match] = Version.new(match) if match match_data end end end end end