Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added :verify => true option to #new. If you pass this option, it'll …

…verify that the favicon_url is valid (i.e. has 200 response code, an image content/type and something for the body).
  • Loading branch information...
commit cadd66b5eab5b3c53340b78157e26b6b57e23932 1 parent 5020c11
@myronmarston myronmarston authored
Showing with 78 additions and 11 deletions.
  1. +29 −11 lib/www/favicon.rb
  2. +49 −0 spec/www-favicon_spec.rb
View
40 lib/www/favicon.rb
@@ -7,25 +7,43 @@ module WWW
class Favicon
VERSION = '0.0.3'
+ def initialize(options = {})
+ @options = options
+ end
+
def find(url)
html = request(URI(url)).body
find_from_html(html, url)
end
-
+
def find_from_html(html, url)
uri = URI(url)
- find_from_link(html, uri) || try_default_path(uri)
+ favicon_url = find_from_link(html, uri) || try_default_path(uri)
+ if @options[:verify]
+ favicon_url = nil unless valid_favicon_url?(favicon_url)
+ end
+ favicon_url
+ end
+
+ def valid_favicon_url?(url)
+ response = request(URI.parse(url))
+
+ (
+ response.code =~ /\A2/ &&
+ response.body.to_s != '' &&
+ response.content_type =~ /image/i
+ ) ? true : false
end
- private
+ private
def find_from_link(html, uri)
doc = Hpricot(html)
-
+
doc.search('//link').each do |link|
if link[:rel] =~ /^(shortcut )?icon$/i
favicon_url_or_path = link[:href]
-
+
if favicon_url_or_path =~ /^http/
return favicon_url_or_path
else
@@ -33,7 +51,7 @@ def find_from_link(html, uri)
end
end
end
-
+
nil
end
@@ -51,21 +69,21 @@ def try_default_path(uri)
when '3'
return response['Location']
end
-
+
nil
end
-
+
def request(uri, method = 'get')
http = Net::HTTP.new(uri.host, uri.port)
-
+
if uri.scheme == 'https'
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
http.start do |http|
- path =
- (uri.path.empty? ? '/' : uri.path) +
+ path =
+ (uri.path.empty? ? '/' : uri.path) +
(uri.query ? '?' + uri.query : '') +
(uri.fragment ? '#' + uri.fragment : '')
response = http.send(method, path)
View
49 spec/www-favicon_spec.rb
@@ -46,6 +46,55 @@
end
end
+describe WWW::Favicon, 'with the :verify => true option' do
+ before do
+ @favicon = WWW::Favicon.new(:verify => true)
+ @favicon.stub!(:request).and_return(expectaction(:body => '<html></html>'), expectaction(:code => '200'))
+ end
+
+ it "should validate the favicon_url" do
+ @favicon.should_receive(:valid_favicon_url?).with('http://www.example.com/favicon.ico')
+ @favicon.find('http://www.example.com/')
+ end
+
+ it "should return nil if #valid_favicon_url? returns false" do
+ @favicon.stub!(:valid_favicon_url?).and_return(false)
+ @favicon.find('http://www.example.com/').should be_nil
+ end
+
+ it "should return the url if #valid_favicon_url? returns true" do
+ @favicon.stub!(:valid_favicon_url?).and_return(true)
+ @favicon.find('http://www.example.com/').should == 'http://www.example.com/favicon.ico'
+ end
+
+ describe '#valid_favicon_url?' do
+ before do
+ @url = 'http://www.example.com/favicon.ico'
+ @response = expectaction(:code => '200', :body => 'an image', :content_type => 'image/jpeg')
+ @favicon.stub!(:request).and_return(@response)
+ end
+
+ it 'should return true if it is valid' do
+ @favicon.valid_favicon_url?(@url).should == true
+ end
+
+ it 'should return false if the code is not 200' do
+ @response.code = '500'
+ @favicon.valid_favicon_url?(@url).should == false
+ end
+
+ it 'should return false if the body is blank' do
+ @response.body = ''
+ @favicon.valid_favicon_url?(@url).should == false
+ end
+
+ it 'should return false if the content type is not an image content type' do
+ @response.content_type = 'application/xml'
+ @favicon.valid_favicon_url?(@url).should == false
+ end
+ end
+end
+
def expectaction(attr)
OpenStruct.new(attr)
end
Please sign in to comment.
Something went wrong with that request. Please try again.