Class: Flavicon::Finder

Inherits:
Object
  • Object
show all
Defined in:
lib/flavicon/finder.rb

Constant Summary collapse

TooManyRedirects =
Class.new(StandardError)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url) ⇒ Finder

Returns a new instance of Finder.



13
14
15
# File 'lib/flavicon/finder.rb', line 13

def initialize(url)
  @url = url
end

Instance Attribute Details

#urlObject (readonly)

Returns the value of attribute url.



11
12
13
# File 'lib/flavicon/finder.rb', line 11

def url
  @url
end

Instance Method Details

#default_path(url) ⇒ Object



38
39
40
# File 'lib/flavicon/finder.rb', line 38

def default_path(url)
  URI.join(url, '/favicon.ico').to_s
end

#extract_from_html(html, url) ⇒ Object



32
33
34
35
36
# File 'lib/flavicon/finder.rb', line 32

def extract_from_html(html, url)
  Nokogiri::HTML(html).css('head link').filter_map do |node|
    URI.join(url, node[:href]).to_s if node[:rel] =~ /\A(shortcut )?icon\z/i
  end
end

#extract_location(response, url) ⇒ Object

While the soon-to-be obsolete IETF standard RFC 2616 (HTTP 1.1) requires a complete absolute URI for redirection, the most popular web browsers tolerate the passing of a relative URL as the value for a Location header field. Consequently, the current revision of HTTP/1.1 makes relative URLs conforming.



68
69
70
# File 'lib/flavicon/finder.rb', line 68

def extract_location(response, url)
  URI.join(url, response['location']).to_s
end

#findObject



17
18
19
20
21
22
23
# File 'lib/flavicon/finder.rb', line 17

def find
  response, resolved = request(url)

  extract_from_html(response.body, resolved)
    .push(default_path(resolved))
    .find { |url| verify_favicon_url(url) }
end

#request(url, limit = 10) ⇒ Object

rubocop:disable Metrics/AbcSize,Metrics/MethodLength

Raises:



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/flavicon/finder.rb', line 43

def request(url, limit = 10)
  raise TooManyRedirects if limit.negative?

  uri = URI.parse(url)
  http = Net::HTTP.new(uri.host, uri.port)
  request = Net::HTTP::Get.new(uri.request_uri)

  if uri.scheme == 'https'
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  end

  response = http.request(request)

  if response.is_a? Net::HTTPRedirection
    request(extract_location(response, url), limit - 1)
  else
    [response, url]
  end
end

#verify_favicon_url(url) ⇒ Object



25
26
27
28
29
30
# File 'lib/flavicon/finder.rb', line 25

def verify_favicon_url(url)
  response, resolved = request(url)
  return unless response.is_a?(Net::HTTPSuccess) && response.body.to_s != '' && response.content_type =~ /image/i

  resolved
end