google-safe-browsing-lookup 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +13 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +36 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/lib/google-safe-browsing-lookup.rb +171 -0
- data/test/helper.rb +32 -0
- data/test/test_google-safe-browsing-lookup.rb +72 -0
- metadata +115 -0
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your google-safe-browsing-lookup.
|
3
|
+
|
4
|
+
gem "url", ">= 0"
|
5
|
+
|
6
|
+
|
7
|
+
# Dependencies to develop google-safe-browsing-lookup.
|
8
|
+
group :development do
|
9
|
+
gem "shoulda", ">= 0"
|
10
|
+
gem "bundler", "~> 1.0.0"
|
11
|
+
gem "jeweler", "~> 1.6.4"
|
12
|
+
gem "rcov", ">= 0"
|
13
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Julien Sobrier
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
= google-safe-browsing-lookup
|
2
|
+
|
3
|
+
Google Safe Browsing Lookup library for Ruby.
|
4
|
+
|
5
|
+
If you need to check less than 10,000 URLs a day against the Google Safe Browsing v2 API (http://code.google.com/apis/safebrowsing/), you can use the Lookup API (http://code.google.com/apis/safebrowsing/lookup_guide.html) as a lighter alternative to the more complex API (http://code.google.com/apis/safebrowsing/developers_guide_v2.html).
|
6
|
+
|
7
|
+
You need to get an API key from Google at http://code.google.com/apis/safebrowsing/key_signup.html
|
8
|
+
|
9
|
+
== Build and install google-safe-browsing-lookup
|
10
|
+
|
11
|
+
git clone https://github.com/juliensobrier/google-safe-browsing-lookup-ruby
|
12
|
+
rake build
|
13
|
+
rake test
|
14
|
+
rake install
|
15
|
+
|
16
|
+
Or
|
17
|
+
|
18
|
+
gem install google-safe-browsing-lookup
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
== Contributing to google-safe-browsing-lookup
|
23
|
+
|
24
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
25
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
26
|
+
* Fork the project
|
27
|
+
* Start a feature/bugfix branch
|
28
|
+
* Commit and push until you are happy with your contribution
|
29
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
30
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
31
|
+
|
32
|
+
== Copyright
|
33
|
+
|
34
|
+
Copyright (c) 2011 Julien Sobrier. See LICENSE.txt for
|
35
|
+
further details.
|
36
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "google-safe-browsing-lookup"
|
18
|
+
gem.homepage = "http://github.com/juliensobrier/google-safe-browsing-lookup"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = "Ruby library for the Google Safe Browsing v2 Lookup API"
|
21
|
+
gem.description = "Google Safe Browsing v2 Lookup is a lighter alternative to the full API. The service allows users to check up to 10,000 URLs a day against their list og phishing and malicious sites. A free API key is required."
|
22
|
+
gem.email = "julien@sobrier.net"
|
23
|
+
gem.authors = ["Julien Sobrier"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
Rake::TestTask.new(:test) do |test|
|
30
|
+
test.libs << 'lib' << 'test'
|
31
|
+
test.pattern = 'test/**/test_*.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
|
35
|
+
require 'rcov/rcovtask'
|
36
|
+
Rcov::RcovTask.new do |test|
|
37
|
+
test.libs << 'test'
|
38
|
+
test.pattern = 'test/**/test_*.rb'
|
39
|
+
test.verbose = true
|
40
|
+
test.rcov_opts << '--exclude "gems/*"'
|
41
|
+
end
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
# require 'rake/rdoctask'
|
46
|
+
require 'rdoc/task'
|
47
|
+
Rake::RDocTask.new do |rdoc|
|
48
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
49
|
+
|
50
|
+
rdoc.rdoc_dir = 'rdoc'
|
51
|
+
rdoc.title = "google-safe-browsing-lookup #{version}"
|
52
|
+
rdoc.rdoc_files.include('README*')
|
53
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
54
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,171 @@
|
|
1
|
+
# The library requires an API key from Google.
|
2
|
+
# Sign up for a free key a http://code.google.com/apis/safebrowsing/key_signup.html
|
3
|
+
#
|
4
|
+
# See README.rdoc for more information about Google Safe Browsing v2 API
|
5
|
+
# and this library.
|
6
|
+
#
|
7
|
+
# Author:: Julien Sobrier (mailto:jsobrier@browshot.com)
|
8
|
+
# Copyright:: Copyright (c) 2011 Julien Sobrier
|
9
|
+
# License:: Distributes under the same terms as Ruby
|
10
|
+
|
11
|
+
require 'uri'
|
12
|
+
require 'url'
|
13
|
+
require 'net/https'
|
14
|
+
|
15
|
+
class SafeBrowsingLookup
|
16
|
+
# API key
|
17
|
+
attr_reader :key
|
18
|
+
# Enable debug & error output to the standard output
|
19
|
+
attr_reader :debug
|
20
|
+
# Enable error output to the standard output
|
21
|
+
attr_reader :error
|
22
|
+
# Contain last error
|
23
|
+
attr_reader :last_error
|
24
|
+
# Library version
|
25
|
+
attr_reader :version
|
26
|
+
# Google API version
|
27
|
+
attr_reader :api_version
|
28
|
+
|
29
|
+
# New client
|
30
|
+
#
|
31
|
+
# +key+:: API key
|
32
|
+
# +debug+:: Set to true to print debug & error output to the standard output. false (disabled) by default.
|
33
|
+
# +debug+:: Set to true to print error output to the standard output. false (disabled) by default.
|
34
|
+
def initialize(key='', debug=false, error=false)
|
35
|
+
@key = key || ''
|
36
|
+
@debug = debug || false
|
37
|
+
@error = error || false
|
38
|
+
@last_error = ''
|
39
|
+
|
40
|
+
@version = '0.1'
|
41
|
+
@api_version = '3.0'
|
42
|
+
|
43
|
+
|
44
|
+
raise ArgumentError, "Missing API key" if (@key == '')
|
45
|
+
end
|
46
|
+
|
47
|
+
# Lookup a list URLs against the Google Safe Browsing v2 lists.
|
48
|
+
#
|
49
|
+
# Returns a hash <url>: <Gooogle match>. The possible list of values for <Gooogle match> are: "ok" (no match), "malware", "phishing", "malware,phishing" (match both lists) and "error".
|
50
|
+
#
|
51
|
+
# +urls+:: List of URLs to lookup. The Lookup API allows only 10,000 URL checks a day. if you need more, find a Ruby implementation of the full Google Safe brosing v2 API. Each requests must contain 500 URLs at most. The lookup() method will split the list of URLS in blocks of 500 URLs if needed.
|
52
|
+
def lookup(urls='')
|
53
|
+
if (urls.respond_to?('each') == false)
|
54
|
+
urls = Array.new(1, urls)
|
55
|
+
end
|
56
|
+
# urls_copy = Array.new(urls)
|
57
|
+
|
58
|
+
results = { }
|
59
|
+
|
60
|
+
# while (urls_copy.length > 0)
|
61
|
+
# inputs = urls_copy.slice!(0, 500)
|
62
|
+
count = 0
|
63
|
+
while (count * 500 < urls.length)
|
64
|
+
inputs = urls.slice(count * 500, 500)
|
65
|
+
body = inputs.length.to_s
|
66
|
+
inputs.each do |url|
|
67
|
+
body = body + "\n" + canonical(url)
|
68
|
+
end
|
69
|
+
|
70
|
+
debug("BODY:\n#{body}\n\n");
|
71
|
+
uri = URI.parse("https://sb-ssl.google.com/safebrowsing/api/lookup?client=ruby&apikey=#{@key}&appver=#{@version}&pver=#{@api_version}")
|
72
|
+
|
73
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
74
|
+
http.open_timeout = 30
|
75
|
+
http.read_timeout = 30
|
76
|
+
http.use_ssl = true
|
77
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
78
|
+
|
79
|
+
response = http.request_post("#{uri.path}?#{uri.query}", body)
|
80
|
+
|
81
|
+
case response
|
82
|
+
when Net::HTTPOK # 200
|
83
|
+
debug("At least 1 match\n")
|
84
|
+
results.merge!( parse(inputs, response.body) )
|
85
|
+
|
86
|
+
when Net::HTTPNoContent # 204
|
87
|
+
debug("No match\n")
|
88
|
+
results.merge!( ok(inputs) )
|
89
|
+
|
90
|
+
when Net::HTTPBadRequest # 400
|
91
|
+
error("Invalid request")
|
92
|
+
results.merge( errors(inputs) )
|
93
|
+
|
94
|
+
when Net::HTTPUnauthorized # 401
|
95
|
+
error("Invalid API key")
|
96
|
+
results.merge!( errors(inputs) )
|
97
|
+
|
98
|
+
when Net::HTTPServiceUnavailable # 503
|
99
|
+
error("Server error, client may have sent too many requests")
|
100
|
+
results.merge!( errors(inputs) )
|
101
|
+
|
102
|
+
else
|
103
|
+
self.error("Unexpected server response: #{response.code}")
|
104
|
+
results.merge!( errors(inputs) )
|
105
|
+
end
|
106
|
+
|
107
|
+
count = count + 1
|
108
|
+
end
|
109
|
+
|
110
|
+
return results
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
# Not much is actually done, full URL canonicalization is not required with the Lookup library according to the API documentation
|
117
|
+
def canonical(url='')
|
118
|
+
# remove leading/ending white spaces
|
119
|
+
url.strip!
|
120
|
+
|
121
|
+
# make sure whe have a scheme
|
122
|
+
if (url !~ /^https?\:\/\//i)
|
123
|
+
url = "http://#{url}"
|
124
|
+
end
|
125
|
+
|
126
|
+
uri = URL.new(url)
|
127
|
+
|
128
|
+
return uri.to_s
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
def parse(urls=[], response)
|
133
|
+
lines = response.split("\n")
|
134
|
+
|
135
|
+
if (urls.length != lines.length)
|
136
|
+
error("Number of URLs in the reponse does not match the number of URLs in the request");
|
137
|
+
error("#{urls.length} / #{lines.length}");
|
138
|
+
error(response);
|
139
|
+
return errors(urls);
|
140
|
+
end
|
141
|
+
|
142
|
+
results = { }
|
143
|
+
for i in (0..lines.length - 1)
|
144
|
+
results[urls[i]] = lines[i]
|
145
|
+
debug(urls[i] + " => " + lines[i])
|
146
|
+
end
|
147
|
+
|
148
|
+
return results
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
def errors(urls=[])
|
153
|
+
return Hash[*urls.map {|url| [url, 'error']}.flatten]
|
154
|
+
end
|
155
|
+
|
156
|
+
def ok(urls=[])
|
157
|
+
return Hash[*urls.map {|url| [url, 'ok']}.flatten]
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
def debug(message='')
|
162
|
+
puts message if (@debug == true)
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
def error(message='')
|
167
|
+
puts "#{message}\n" if (@debug == true or @error == true)
|
168
|
+
@last_error = message
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
require 'shoulda'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
require 'google-safe-browsing-lookup'
|
16
|
+
|
17
|
+
class Test::Unit::TestCase
|
18
|
+
end
|
19
|
+
|
20
|
+
class MockClient < SafeBrowsingLookup
|
21
|
+
def errors(urls=[])
|
22
|
+
super(urls)
|
23
|
+
end
|
24
|
+
|
25
|
+
def ok(urls=[])
|
26
|
+
super(urls)
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse(urls=[], response)
|
30
|
+
super(urls, response)
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestGoogleSafeBrowsingLookup < Test::Unit::TestCase
|
4
|
+
context "Lookup client" do
|
5
|
+
setup do
|
6
|
+
@client = SafeBrowsingLookup.new('put_the_Google_API_key_here')
|
7
|
+
@mock = MockClient.new('put_the_Google_API_key_here')
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
should "create a hash URL => 'error'" do
|
12
|
+
results = @mock.errors(['http://www.google.com/', 'http://www.google.org/'])
|
13
|
+
|
14
|
+
assert_equal 2, results.length, "Number of keys should match number of URLs"
|
15
|
+
assert_equal 'error', results['http://www.google.com/'], "An error should be returned"
|
16
|
+
assert_equal 'error', results['http://www.google.org/'], "An error should be returned"
|
17
|
+
end
|
18
|
+
|
19
|
+
should "create a hash URL => 'ok'" do
|
20
|
+
results = @mock.ok(['http://www.google.com/', 'http://www.google.org/'])
|
21
|
+
|
22
|
+
assert_equal 2, results.length, "Number of keys should match number of URLs"
|
23
|
+
assert_equal 'ok', results['http://www.google.com/'], "ok should be returned"
|
24
|
+
assert_equal 'ok', results['http://www.google.org/'], "ok should be returned"
|
25
|
+
end
|
26
|
+
|
27
|
+
should "parse the server response" do
|
28
|
+
response = "ok\nphishing"
|
29
|
+
|
30
|
+
results = @mock.parse(['http://www.google.com/', 'http://www.google.org/'], response)
|
31
|
+
|
32
|
+
assert_equal 2, results.length, "Number of keys should match number of URLs"
|
33
|
+
assert_equal 'ok', results['http://www.google.com/'], "ok should be returned"
|
34
|
+
assert_equal 'phishing', results['http://www.google.org/'], "phishing should be returned"
|
35
|
+
end
|
36
|
+
|
37
|
+
should "create find an error with server response" do
|
38
|
+
response = "ok\nphishing\nok"
|
39
|
+
|
40
|
+
results = @mock.parse(['http://www.google.com/', 'http://www.google.org/'], response)
|
41
|
+
|
42
|
+
assert_equal 2, results.length, "Number of keys should match number of URLs"
|
43
|
+
assert_equal 'error', results['http://www.google.com/'], "An error should be returned"
|
44
|
+
assert_equal 'error', results['http://www.google.org/'], "An error should be returned"
|
45
|
+
end
|
46
|
+
|
47
|
+
should "do live tests" do
|
48
|
+
if (@client.key == 'put_the_Google_API_key_here')
|
49
|
+
return # An valid key is required
|
50
|
+
end
|
51
|
+
|
52
|
+
results = @client.lookup('http://www.gumblar.cn/')
|
53
|
+
assert_equal 1, results.length, "Number of keys should match number of URLs"
|
54
|
+
assert_equal 'malware', results['http://www.gumblar.cn/'], "malware should be returned"
|
55
|
+
end
|
56
|
+
|
57
|
+
should "send more than 500 URLs" do
|
58
|
+
if (@client.key == 'put_the_Google_API_key_here')
|
59
|
+
return # An valid key is required
|
60
|
+
end
|
61
|
+
|
62
|
+
urls = []
|
63
|
+
(1..600).each do |id|
|
64
|
+
urls.push("http://www.gumblar.cn/#{id}")
|
65
|
+
end
|
66
|
+
|
67
|
+
results = @client.lookup(urls)
|
68
|
+
assert_equal urls.length, results.length, "Number of keys should match number of URLs"
|
69
|
+
assert_equal 'malware', results['http://www.gumblar.cn/1'], "malware should be returned"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: google-safe-browsing-lookup
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Julien Sobrier
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-12-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: url
|
16
|
+
requirement: &130589580 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *130589580
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: shoulda
|
27
|
+
requirement: &130589080 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *130589080
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: bundler
|
38
|
+
requirement: &130588580 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.0.0
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *130588580
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: jeweler
|
49
|
+
requirement: &130588100 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.6.4
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *130588100
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rcov
|
60
|
+
requirement: &130587600 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *130587600
|
69
|
+
description: Google Safe Browsing v2 Lookup is a lighter alternative to the full API.
|
70
|
+
The service allows users to check up to 10,000 URLs a day against their list og
|
71
|
+
phishing and malicious sites. A free API key is required.
|
72
|
+
email: julien@sobrier.net
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files:
|
76
|
+
- LICENSE.txt
|
77
|
+
- README.rdoc
|
78
|
+
files:
|
79
|
+
- Gemfile
|
80
|
+
- LICENSE.txt
|
81
|
+
- README.rdoc
|
82
|
+
- Rakefile
|
83
|
+
- VERSION
|
84
|
+
- lib/google-safe-browsing-lookup.rb
|
85
|
+
- test/helper.rb
|
86
|
+
- test/test_google-safe-browsing-lookup.rb
|
87
|
+
homepage: http://github.com/juliensobrier/google-safe-browsing-lookup
|
88
|
+
licenses:
|
89
|
+
- MIT
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ! '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
hash: 3258559681229541740
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
requirements: []
|
110
|
+
rubyforge_project:
|
111
|
+
rubygems_version: 1.8.11
|
112
|
+
signing_key:
|
113
|
+
specification_version: 3
|
114
|
+
summary: Ruby library for the Google Safe Browsing v2 Lookup API
|
115
|
+
test_files: []
|