geo_ip 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGES.md +15 -8
- data/README.md +9 -6
- data/lib/geo_ip.rb +21 -18
- data/spec/geo_ip_spec.rb +244 -163
- metadata +81 -107
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3e8b93f82d94dbdc0c927c94fbaf67deaddfd90f
|
4
|
+
data.tar.gz: ff3426ed202eda04441b1e943648115c94b057c4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 90459b54612062710bfeeb504d166fb57b1218a067bd2ec7b97de9d23fa040f8e4b8389718eada133bbdcbfae29246a3e73e52f95d86b17288371e3dc1b95319
|
7
|
+
data.tar.gz: 88927d54c7011008f84710a8cb188062ae24f30862ff9a9ddaa9e75658a417ca95768eaf235f9fcae074e351a0530cf263f7f97ddda85c39deda954ce194e9ec
|
data/CHANGES.md
CHANGED
@@ -1,40 +1,47 @@
|
|
1
|
-
## 0.
|
1
|
+
## 0.6.0 (2015-09-21)
|
2
|
+
|
3
|
+
* Adds ruby 2.0, 2.1 and 2.2 to the Travis build matrix
|
4
|
+
* Drops support for ruby 1.8.7 and 1.9.2
|
5
|
+
* Improves formatting and fixes various rubocop (0.34.1) offencs
|
6
|
+
* Adds support for IPv6 addresses. By [dnswus](https://github.com/dnswus)
|
7
|
+
|
8
|
+
## 0.5.0 (2012-03-03)
|
2
9
|
|
3
10
|
* Wrap Ruby's Timeout module around the RestClient call to enforce timeout if caused by bad internet connection or slow or invalid DNS lookup. Added WebMock to tests to have reliable tests. By [harleyttd](https://github.com/harleyttd)
|
4
11
|
|
5
|
-
## 0.4.0
|
12
|
+
## 0.4.0 (2011-05-29)
|
6
13
|
|
7
14
|
* Uses API v3
|
8
15
|
|
9
|
-
## 0.3.2
|
16
|
+
## 0.3.2 (2011-05-20)
|
10
17
|
|
11
18
|
* Switches to [rest-client](https://github.com/adamwiggins/rest-client) for requests
|
12
19
|
* Sets default timeout to 1 second and adds option to override it
|
13
20
|
* More relaxed json dependency scoping
|
14
21
|
* Some internal code refactoring
|
15
22
|
|
16
|
-
## 0.3.1
|
23
|
+
## 0.3.1 (2011-03-26)
|
17
24
|
|
18
25
|
* Switches to bundler for gem deployment
|
19
26
|
* Uses Rspec 2.x from now on
|
20
27
|
|
21
|
-
## 0.3.0
|
28
|
+
## 0.3.0 (2010-11-16)
|
22
29
|
|
23
30
|
* Added support for API key requirement (Thanks to seanconaty and luigi)
|
24
31
|
* Explicit gem dependency for json and removed rubygems requirement (idris) (http://tomayko.com/writings/require-rubygems-antipattern)
|
25
32
|
* Removed deprecated GeoIp#remote_geolocation method
|
26
33
|
|
27
|
-
## 0.2.0
|
34
|
+
## 0.2.0 (2010-03-25)
|
28
35
|
|
29
36
|
* Added support for timezone information. Use the optional {:timezone => true|false} option
|
30
37
|
* Added support for country lookup. This will result in a faster reply since less queries need
|
31
38
|
to be done at ipinfodb's side. Use the optional {:precision => :city|:country} option
|
32
39
|
* API change: GeoIp.remote_geolocation(ip) is deprecated in favor of GeoIp.geolocation(ip)
|
33
40
|
|
34
|
-
## 0.1.1
|
41
|
+
## 0.1.1 (2010-02-15)
|
35
42
|
|
36
43
|
* Removed time zone information since this has been deprecated with the service
|
37
44
|
|
38
|
-
## 0.1.0
|
45
|
+
## 0.1.0 (2010-01-09)
|
39
46
|
|
40
47
|
* Initial commit
|
data/README.md
CHANGED
@@ -80,7 +80,7 @@ Obviously it is not possible to have the country precision enabled while retriev
|
|
80
80
|
|
81
81
|
Passing reserved, private or local IPs, such as `127.0.0.1` will return `-` for all location data, for example:
|
82
82
|
|
83
|
-
|
83
|
+
GeoIp.geolocation('127.0.0.1')
|
84
84
|
|
85
85
|
returns:
|
86
86
|
|
@@ -109,13 +109,15 @@ GeoIp can be installed as a Ruby Gem:
|
|
109
109
|
|
110
110
|
gem install geo_ip
|
111
111
|
|
112
|
+
*note:* As of v0.6.0 GeoIp is only compatible with ruby 1.9.3 or higher. You can still use v0.5.0 if you need ruby 1.8.7 or 1.9.2 compatiblity.
|
113
|
+
|
112
114
|
### Rails
|
113
115
|
|
114
|
-
#### Bundler enabled (Rails 3.
|
116
|
+
#### Bundler enabled (Rails 3.x and 2.3.x)
|
115
117
|
|
116
118
|
In your Gemfile:
|
117
119
|
|
118
|
-
gem 'geo_ip'
|
120
|
+
gem 'geo_ip'
|
119
121
|
|
120
122
|
Then create an initializer `config/initializers/geo_ip` (or name it whatever you want):
|
121
123
|
|
@@ -125,7 +127,7 @@ Then create an initializer `config/initializers/geo_ip` (or name it whatever you
|
|
125
127
|
|
126
128
|
In your `config/environment.rb`:
|
127
129
|
|
128
|
-
config.gem 'geo_ip'
|
130
|
+
config.gem 'geo_ip'
|
129
131
|
|
130
132
|
Then create an initializer `config/initializers/geo_ip` (or name it whatever you want):
|
131
133
|
|
@@ -148,6 +150,7 @@ If you get a LoadError, you should run the tests with:
|
|
148
150
|
* [idris](https://github.com/idris)
|
149
151
|
* [Rylon](https://github.com/Rylon)
|
150
152
|
* [harleyttd](https://github.com/harleyttd)
|
153
|
+
* [dnswus](https://github.com/dnswus)
|
151
154
|
|
152
155
|
## Bugs
|
153
156
|
|
@@ -156,7 +159,7 @@ for this project.
|
|
156
159
|
|
157
160
|
If you have a bug to report, please include the following information:
|
158
161
|
|
159
|
-
*
|
162
|
+
* Version information for geo_ip, ruby and/or rails.
|
160
163
|
* Stack trace and error message.
|
161
164
|
|
162
165
|
You may also fork this project on Github and create a pull request.
|
@@ -164,4 +167,4 @@ Do not forget to include tests.
|
|
164
167
|
|
165
168
|
## Copyright
|
166
169
|
|
167
|
-
Copyright (c) 2010-
|
170
|
+
Copyright (c) 2010-2013 Jeroen Jacobs. See LICENSE for details.
|
data/lib/geo_ip.rb
CHANGED
@@ -2,10 +2,14 @@ require 'json'
|
|
2
2
|
require 'rest-client'
|
3
3
|
|
4
4
|
class GeoIp
|
5
|
+
class InvalidPrecissionError < ArgumentError; end
|
6
|
+
class InvalidTimezoneError < ArgumentError; end
|
7
|
+
class InvalidIpError < ArgumentError; end
|
8
|
+
class ApiKeyError < ArgumentError; end
|
9
|
+
|
5
10
|
SERVICE_URL = 'http://api.ipinfodb.com/v3/ip-'
|
6
11
|
CITY_API = 'city'
|
7
12
|
COUNTRY_API = 'country'
|
8
|
-
IPV4_REGEXP = /\A(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)(?:\.(?:25[0-5]|(?:2[0-4]|1\d|[1-9])?\d)){3}\z/
|
9
13
|
|
10
14
|
@@api_key = nil
|
11
15
|
@@timeout = 1
|
@@ -16,7 +20,7 @@ class GeoIp
|
|
16
20
|
@@api_key
|
17
21
|
end
|
18
22
|
|
19
|
-
def api_key=
|
23
|
+
def api_key=(api_key)
|
20
24
|
@@api_key = api_key
|
21
25
|
end
|
22
26
|
|
@@ -24,7 +28,7 @@ class GeoIp
|
|
24
28
|
@@timeout
|
25
29
|
end
|
26
30
|
|
27
|
-
def timeout=
|
31
|
+
def timeout=(timeout)
|
28
32
|
@@timeout = timeout
|
29
33
|
end
|
30
34
|
|
@@ -32,21 +36,21 @@ class GeoIp
|
|
32
36
|
@@fallback_timeout
|
33
37
|
end
|
34
38
|
|
35
|
-
def fallback_timeout=
|
39
|
+
def fallback_timeout=(fallback_timeout)
|
36
40
|
@@fallback_timeout = fallback_timeout
|
37
41
|
end
|
38
42
|
|
39
|
-
def set_defaults_if_necessary
|
43
|
+
def set_defaults_if_necessary(options)
|
40
44
|
options[:precision] ||= :city
|
41
|
-
options[:timezone]
|
42
|
-
|
43
|
-
|
45
|
+
options[:timezone] ||= false
|
46
|
+
fail InvalidPrecisionError unless [:country, :city].include?(options[:precision])
|
47
|
+
fail InvalidTimezoneError unless [true, false].include?(options[:timezone])
|
44
48
|
end
|
45
49
|
|
46
|
-
def lookup_url
|
50
|
+
def lookup_url(ip, options = {})
|
47
51
|
set_defaults_if_necessary options
|
48
|
-
|
49
|
-
|
52
|
+
fail ApiKeyError.new('API key must be set first: GeoIp.api_key = \'YOURKEY\'') if api_key.nil?
|
53
|
+
fail InvalidIpError.new(ip) unless ip.to_s =~ Resolv::IPv4::Regex || ip.to_s =~ Resolv::IPv6::Regex
|
50
54
|
|
51
55
|
"#{SERVICE_URL}#{options[:precision] == :city || options[:timezone] ? CITY_API : COUNTRY_API}?key=#{api_key}&ip=#{ip}&format=json&timezone=#{options[:timezone]}"
|
52
56
|
end
|
@@ -59,10 +63,10 @@ class GeoIp
|
|
59
63
|
#
|
60
64
|
# ==== Example:
|
61
65
|
# GeoIp.geolocation('209.85.227.104', {:precision => :city, :timezone => true})
|
62
|
-
def geolocation
|
66
|
+
def geolocation(ip, options = {})
|
63
67
|
location = nil
|
64
|
-
Timeout.timeout(
|
65
|
-
parsed_response = JSON.parse RestClient::Request.execute(:
|
68
|
+
Timeout.timeout(fallback_timeout) do
|
69
|
+
parsed_response = JSON.parse RestClient::Request.execute(method: :get, url: lookup_url(ip, options), timeout: timeout)
|
66
70
|
location = convert_keys(parsed_response, options)
|
67
71
|
end
|
68
72
|
|
@@ -70,7 +74,8 @@ class GeoIp
|
|
70
74
|
end
|
71
75
|
|
72
76
|
private
|
73
|
-
|
77
|
+
|
78
|
+
def convert_keys(hash, options)
|
74
79
|
set_defaults_if_necessary options
|
75
80
|
location = {}
|
76
81
|
location[:ip] = hash['ipAddress']
|
@@ -84,9 +89,7 @@ class GeoIp
|
|
84
89
|
location[:zip_code] = hash['zipCode']
|
85
90
|
location[:latitude] = hash['latitude']
|
86
91
|
location[:longitude] = hash['longitude']
|
87
|
-
if options[:timezone]
|
88
|
-
location[:timezone] = hash['timeZone']
|
89
|
-
end
|
92
|
+
location[:timezone] = hash['timeZone'] if options[:timezone]
|
90
93
|
end
|
91
94
|
location
|
92
95
|
end
|
data/spec/geo_ip_spec.rb
CHANGED
@@ -2,6 +2,9 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
IP_GOOGLE_US = '209.85.227.104'
|
3
3
|
IP_PRIVATE = '10.0.0.1'
|
4
4
|
IP_LOCAL = '127.0.0.1'
|
5
|
+
IPV4_INVALID = '255.255.255'
|
6
|
+
IPV6_INVALID = '2001:cdba'
|
7
|
+
IPV6 = '2001:cdba:0000:0000:0000:0000:3257:9652'
|
5
8
|
# Use WebMock as default to speed up tests and for local development without a connection
|
6
9
|
# Change this to false to have tests make real http requests if you want. Perhaps to check whether IpInfoDb's API has changed
|
7
10
|
# However, you may need to increase the GeoIp.fallback_timeout variable if Timeout exceptions occur when tests are run
|
@@ -10,16 +13,16 @@ USE_WEBMOCK = true
|
|
10
13
|
describe 'GeoIp' do
|
11
14
|
before :all do
|
12
15
|
unless USE_WEBMOCK
|
13
|
-
puts
|
16
|
+
puts 'Running tests WITHOUT WebMock. You will need an internet connection. You may need to increase the GeoIp.fallback_timeout amount.'
|
14
17
|
WebMock.disable!
|
15
18
|
end
|
16
19
|
end
|
17
20
|
|
18
|
-
def stub_geolocation(ip, options = {}, &
|
21
|
+
def stub_geolocation(ip, options = {}, &_block)
|
19
22
|
if USE_WEBMOCK
|
20
|
-
stub_request(:get, GeoIp.lookup_url(ip, options))
|
21
|
-
|
22
|
-
|
23
|
+
stub_request(:get, GeoIp.lookup_url(ip, options))
|
24
|
+
.with(headers: { 'Accept' => '*/*; q=0.5, application/xml', 'Accept-Encoding' => 'gzip, deflate' })
|
25
|
+
.to_return(status: 200, body: yield, headers: {})
|
23
26
|
end
|
24
27
|
end
|
25
28
|
|
@@ -36,259 +39,337 @@ describe 'GeoIp' do
|
|
36
39
|
|
37
40
|
it 'should throw an error when API key is not set' do
|
38
41
|
GeoIp.api_key = nil
|
39
|
-
|
42
|
+
-> { GeoIp.geolocation(IP_GOOGLE_US) }.should raise_error
|
40
43
|
end
|
41
44
|
end
|
42
45
|
|
43
46
|
context 'city' do
|
44
47
|
it 'should return the correct city for a public ip address' do
|
45
48
|
stub_geolocation(IP_GOOGLE_US) do
|
46
|
-
%
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
}
|
49
|
+
%({
|
50
|
+
"statusCode" : "OK",
|
51
|
+
"statusMessage" : "",
|
52
|
+
"ipAddress" : "209.85.227.104",
|
53
|
+
"countryCode" : "US",
|
54
|
+
"countryName" : "UNITED STATES",
|
55
|
+
"regionName" : "CALIFORNIA",
|
56
|
+
"cityName" : "MONTEREY PARK",
|
57
|
+
"zipCode" : "91754",
|
58
|
+
"latitude" : "34.0505",
|
59
|
+
"longitude" : "-118.13",
|
60
|
+
"timeZone" : "-08:00"
|
61
|
+
})
|
59
62
|
end
|
60
63
|
|
61
64
|
geolocation = GeoIp.geolocation(IP_GOOGLE_US)
|
62
65
|
geolocation[:country_code].should == 'US'
|
63
66
|
geolocation[:country_name].should == 'UNITED STATES'
|
64
|
-
geolocation[:city].should
|
67
|
+
geolocation[:city].should == 'MONTEREY PARK'
|
65
68
|
end
|
66
69
|
|
67
70
|
it 'should return nothing city for a private ip address' do
|
68
71
|
stub_geolocation(IP_PRIVATE) do
|
69
|
-
%
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
}
|
72
|
+
%({
|
73
|
+
"statusCode" : "OK",
|
74
|
+
"statusMessage" : "",
|
75
|
+
"ipAddress" : "10.0.0.1",
|
76
|
+
"countryCode" : "-",
|
77
|
+
"countryName" : "-",
|
78
|
+
"regionName" : "-",
|
79
|
+
"cityName" : "-",
|
80
|
+
"zipCode" : "-",
|
81
|
+
"latitude" : "0",
|
82
|
+
"longitude" : "0",
|
83
|
+
"timeZone" : "-"
|
84
|
+
})
|
82
85
|
end
|
83
86
|
|
84
87
|
geolocation = GeoIp.geolocation(IP_PRIVATE)
|
85
88
|
geolocation[:country_code].should == '-'
|
86
89
|
geolocation[:country_name].should == '-'
|
87
|
-
geolocation[:city].should
|
90
|
+
geolocation[:city].should == '-'
|
88
91
|
end
|
89
92
|
|
90
93
|
it 'should return nothing for localhost ip address' do
|
91
94
|
stub_geolocation(IP_LOCAL) do
|
92
|
-
%
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
}
|
95
|
+
%({
|
96
|
+
"statusCode" : "OK",
|
97
|
+
"statusMessage" : "",
|
98
|
+
"ipAddress" : "127.0.0.1",
|
99
|
+
"countryCode" : "-",
|
100
|
+
"countryName" : "-",
|
101
|
+
"regionName" : "-",
|
102
|
+
"cityName" : "-",
|
103
|
+
"zipCode" : "-",
|
104
|
+
"latitude" : "0",
|
105
|
+
"longitude" : "0",
|
106
|
+
"timeZone" : "-"
|
107
|
+
})
|
105
108
|
end
|
106
109
|
|
107
110
|
geolocation = GeoIp.geolocation(IP_LOCAL)
|
108
111
|
geolocation[:country_code].should == '-'
|
109
112
|
geolocation[:country_name].should == '-'
|
110
|
-
geolocation[:city].should
|
113
|
+
geolocation[:city].should == '-'
|
111
114
|
end
|
112
115
|
|
113
116
|
it 'should return the correct city for a public ip address when explicitly requiring it' do
|
114
117
|
stub_geolocation(IP_GOOGLE_US) do
|
115
|
-
%
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
}
|
118
|
+
%({
|
119
|
+
"statusCode" : "OK",
|
120
|
+
"statusMessage" : "",
|
121
|
+
"ipAddress" : "209.85.227.104",
|
122
|
+
"countryCode" : "US",
|
123
|
+
"countryName" : "UNITED STATES",
|
124
|
+
"regionName" : "CALIFORNIA",
|
125
|
+
"cityName" : "MONTEREY PARK",
|
126
|
+
"zipCode" : "91754",
|
127
|
+
"latitude" : "34.0505",
|
128
|
+
"longitude" : "-118.13",
|
129
|
+
"timeZone" : "-08:00"
|
130
|
+
})
|
128
131
|
end
|
129
132
|
|
130
|
-
geolocation = GeoIp.geolocation(IP_GOOGLE_US, :
|
133
|
+
geolocation = GeoIp.geolocation(IP_GOOGLE_US, precision: :city)
|
131
134
|
geolocation[:country_code].should == 'US'
|
132
135
|
geolocation[:country_name].should == 'UNITED STATES'
|
133
|
-
geolocation[:city].should
|
136
|
+
geolocation[:city].should == 'MONTEREY PARK'
|
134
137
|
end
|
135
138
|
end
|
136
139
|
|
137
140
|
context 'country' do
|
138
141
|
it 'should return the correct country for a public ip address' do
|
139
|
-
stub_geolocation(IP_GOOGLE_US, :
|
140
|
-
%
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
}
|
142
|
+
stub_geolocation(IP_GOOGLE_US, precision: :country) do
|
143
|
+
%({
|
144
|
+
"statusCode" : "OK",
|
145
|
+
"statusMessage" : "",
|
146
|
+
"ipAddress" : "209.85.227.104",
|
147
|
+
"countryCode" : "US",
|
148
|
+
"countryName" : "UNITED STATES"
|
149
|
+
})
|
147
150
|
end
|
148
|
-
geolocation = GeoIp.geolocation(IP_GOOGLE_US, :
|
151
|
+
geolocation = GeoIp.geolocation(IP_GOOGLE_US, precision: :country)
|
149
152
|
geolocation[:country_code].should == 'US'
|
150
153
|
geolocation[:country_name].should == 'UNITED STATES'
|
151
154
|
end
|
152
155
|
|
153
156
|
it 'should return nothing country for a private ip address' do
|
154
|
-
stub_geolocation(IP_PRIVATE, :
|
155
|
-
%
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
}
|
157
|
+
stub_geolocation(IP_PRIVATE, precision: :country) do
|
158
|
+
%({
|
159
|
+
"statusCode" : "OK",
|
160
|
+
"statusMessage" : "",
|
161
|
+
"ipAddress" : "10.0.0.1",
|
162
|
+
"countryCode" : "-",
|
163
|
+
"countryName" : "-"
|
164
|
+
})
|
162
165
|
end
|
163
|
-
geolocation = GeoIp.geolocation(IP_PRIVATE, :
|
166
|
+
geolocation = GeoIp.geolocation(IP_PRIVATE, precision: :country)
|
164
167
|
geolocation[:country_code].should == '-'
|
165
168
|
geolocation[:country_name].should == '-'
|
166
169
|
end
|
167
170
|
|
168
171
|
it 'should return nothing country for localhost ip address' do
|
169
|
-
stub_geolocation(IP_LOCAL, :
|
170
|
-
%
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
}
|
172
|
+
stub_geolocation(IP_LOCAL, precision: :country) do
|
173
|
+
%({
|
174
|
+
"statusCode" : "OK",
|
175
|
+
"statusMessage" : "",
|
176
|
+
"ipAddress" : "127.0.0.1",
|
177
|
+
"countryCode" : "-",
|
178
|
+
"countryName" : "-"
|
179
|
+
})
|
177
180
|
end
|
178
|
-
geolocation = GeoIp.geolocation(IP_LOCAL, :
|
181
|
+
geolocation = GeoIp.geolocation(IP_LOCAL, precision: :country)
|
179
182
|
geolocation[:country_code].should == '-'
|
180
183
|
geolocation[:country_name].should == '-'
|
181
184
|
end
|
182
185
|
|
183
186
|
it 'should not return the city for a public ip address' do
|
184
|
-
stub_geolocation(IP_GOOGLE_US, :
|
185
|
-
%
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
}
|
187
|
+
stub_geolocation(IP_GOOGLE_US, precision: :country) do
|
188
|
+
%({
|
189
|
+
"statusCode" : "OK",
|
190
|
+
"statusMessage" : "",
|
191
|
+
"ipAddress" : "209.85.227.104",
|
192
|
+
"countryCode" : "US",
|
193
|
+
"countryName" : "UNITED STATES"
|
194
|
+
})
|
192
195
|
end
|
193
|
-
geolocation = GeoIp.geolocation(IP_GOOGLE_US, :
|
196
|
+
geolocation = GeoIp.geolocation(IP_GOOGLE_US, precision: :country)
|
194
197
|
geolocation[:country_code].should == 'US'
|
195
198
|
geolocation[:country_name].should == 'UNITED STATES'
|
196
|
-
geolocation[:city].should
|
199
|
+
geolocation[:city].should be_nil
|
197
200
|
end
|
198
201
|
end
|
199
202
|
|
200
203
|
context 'timezone' do
|
201
204
|
it 'should return the correct timezone information for a public ip address' do
|
202
|
-
stub_geolocation(IP_GOOGLE_US, :
|
203
|
-
%
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
}
|
205
|
+
stub_geolocation(IP_GOOGLE_US, timezone: true) do
|
206
|
+
%({
|
207
|
+
"statusCode" : "OK",
|
208
|
+
"statusMessage" : "",
|
209
|
+
"ipAddress" : "209.85.227.104",
|
210
|
+
"countryCode" : "US",
|
211
|
+
"countryName" : "UNITED STATES",
|
212
|
+
"regionName" : "CALIFORNIA",
|
213
|
+
"cityName" : "MONTEREY PARK",
|
214
|
+
"zipCode" : "91754",
|
215
|
+
"latitude" : "34.0505",
|
216
|
+
"longitude" : "-118.13",
|
217
|
+
"timeZone" : "-08:00"
|
218
|
+
})
|
216
219
|
end
|
217
|
-
geolocation = GeoIp.geolocation(IP_GOOGLE_US, :
|
220
|
+
geolocation = GeoIp.geolocation(IP_GOOGLE_US, timezone: true)
|
218
221
|
geolocation[:timezone].should == '-08:00' # This one is likely to break when dst changes.
|
219
222
|
end
|
220
223
|
|
221
224
|
it 'should not return the timezone information when explicitly not requesting it' do
|
222
|
-
stub_geolocation(IP_GOOGLE_US, :
|
223
|
-
%
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
}
|
225
|
+
stub_geolocation(IP_GOOGLE_US, timezone: false) do
|
226
|
+
%({
|
227
|
+
"statusCode" : "OK",
|
228
|
+
"statusMessage" : "",
|
229
|
+
"ipAddress" : "209.85.227.104",
|
230
|
+
"countryCode" : "US",
|
231
|
+
"countryName" : "UNITED STATES",
|
232
|
+
"regionName" : "CALIFORNIA",
|
233
|
+
"cityName" : "MONTEREY PARK",
|
234
|
+
"zipCode" : "91754",
|
235
|
+
"latitude" : "34.0505",
|
236
|
+
"longitude" : "-118.13",
|
237
|
+
"timeZone" : "-08:00"
|
238
|
+
})
|
236
239
|
end
|
237
|
-
geolocation = GeoIp.geolocation(IP_GOOGLE_US, :
|
240
|
+
geolocation = GeoIp.geolocation(IP_GOOGLE_US, timezone: false)
|
238
241
|
geolocation[:timezone].should be_nil
|
239
242
|
end
|
240
243
|
|
241
244
|
it 'should not return the timezone information when not requesting it' do
|
242
245
|
stub_geolocation(IP_GOOGLE_US) do
|
243
|
-
%
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
}
|
246
|
+
%({
|
247
|
+
"statusCode" : "OK",
|
248
|
+
"statusMessage" : "",
|
249
|
+
"ipAddress" : "209.85.227.104",
|
250
|
+
"countryCode" : "US",
|
251
|
+
"countryName" : "UNITED STATES",
|
252
|
+
"regionName" : "CALIFORNIA",
|
253
|
+
"cityName" : "MONTEREY PARK",
|
254
|
+
"zipCode" : "91754",
|
255
|
+
"latitude" : "34.0505",
|
256
|
+
"longitude" : "-118.13",
|
257
|
+
"timeZone" : "-08:00"
|
258
|
+
})
|
256
259
|
end
|
257
260
|
geolocation = GeoIp.geolocation(IP_GOOGLE_US)
|
258
261
|
geolocation[:timezone].should be_nil
|
259
262
|
end
|
260
263
|
|
261
264
|
it 'should not return the timezone information when country precision is selected' do
|
262
|
-
stub_geolocation(IP_GOOGLE_US, :
|
263
|
-
%
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
}
|
265
|
+
stub_geolocation(IP_GOOGLE_US, precision: :country, timezone: true) do
|
266
|
+
%({
|
267
|
+
"statusCode" : "OK",
|
268
|
+
"statusMessage" : "",
|
269
|
+
"ipAddress" : "209.85.227.104",
|
270
|
+
"countryCode" : "US",
|
271
|
+
"countryName" : "UNITED STATES",
|
272
|
+
"regionName" : "CALIFORNIA",
|
273
|
+
"cityName" : "MONTEREY PARK",
|
274
|
+
"zipCode" : "91754",
|
275
|
+
"latitude" : "34.0505",
|
276
|
+
"longitude" : "-118.13",
|
277
|
+
"timeZone" : "-08:00"
|
278
|
+
})
|
276
279
|
end
|
277
|
-
geolocation = GeoIp.geolocation(IP_GOOGLE_US, :
|
280
|
+
geolocation = GeoIp.geolocation(IP_GOOGLE_US, precision: :country, timezone: true)
|
278
281
|
geolocation[:timezone].should be_nil
|
279
282
|
end
|
280
283
|
end
|
281
284
|
|
282
|
-
context
|
285
|
+
context 'timeout' do
|
283
286
|
it 'should trigger timeout when the request is taking too long' do
|
284
287
|
stub_request(:get, GeoIp.lookup_url(IP_GOOGLE_US)).to_timeout
|
285
|
-
|
288
|
+
-> { GeoIp.geolocation(IP_GOOGLE_US) }.should raise_exception('Request Timeout')
|
286
289
|
end
|
287
290
|
|
288
|
-
it 'should trigger fallback timeout when RestClient is taking too long to send the request', :
|
291
|
+
it 'should trigger fallback timeout when RestClient is taking too long to send the request', focus: true do
|
289
292
|
GeoIp.fallback_timeout = 1
|
290
|
-
RestClient::Request.stub(:execute) { sleep
|
291
|
-
|
293
|
+
RestClient::Request.stub(:execute) { sleep 2 }
|
294
|
+
-> { GeoIp.geolocation(IP_GOOGLE_US) }.should raise_exception(Timeout::Error)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
context 'ip' do
|
299
|
+
it 'should trigger invalid ip when invalid IPv4 address is provided' do
|
300
|
+
RestClient::Request.stub(:execute) do
|
301
|
+
%({
|
302
|
+
"statusCode" : "OK",
|
303
|
+
"statusMessage" : "",
|
304
|
+
"ipAddress" : "209.85.227.104",
|
305
|
+
"countryCode" : "US",
|
306
|
+
"countryName" : "UNITED STATES",
|
307
|
+
"regionName" : "CALIFORNIA",
|
308
|
+
"cityName" : "MONTEREY PARK",
|
309
|
+
"zipCode" : "91754",
|
310
|
+
"latitude" : "34.0505",
|
311
|
+
"longitude" : "-118.13",
|
312
|
+
"timeZone" : "-08:00"
|
313
|
+
})
|
314
|
+
end
|
315
|
+
-> { GeoIp.geolocation(IPV4_INVALID) }.should raise_error(GeoIp::InvalidIpError)
|
316
|
+
end
|
317
|
+
|
318
|
+
it 'should not trigger invalid ip when valid IPv4 address is provided' do
|
319
|
+
RestClient::Request.stub(:execute) do
|
320
|
+
%({
|
321
|
+
"statusCode" : "OK",
|
322
|
+
"statusMessage" : "",
|
323
|
+
"ipAddress" : "209.85.227.104",
|
324
|
+
"countryCode" : "US",
|
325
|
+
"countryName" : "UNITED STATES",
|
326
|
+
"regionName" : "CALIFORNIA",
|
327
|
+
"cityName" : "MONTEREY PARK",
|
328
|
+
"zipCode" : "91754",
|
329
|
+
"latitude" : "34.0505",
|
330
|
+
"longitude" : "-118.13",
|
331
|
+
"timeZone" : "-08:00"
|
332
|
+
})
|
333
|
+
end
|
334
|
+
-> { GeoIp.geolocation(IP_GOOGLE_US) }.should_not raise_error(GeoIp::InvalidIpError)
|
335
|
+
end
|
336
|
+
|
337
|
+
it 'should trigger invalid ip when invalid IPv6 address is provided' do
|
338
|
+
RestClient::Request.stub(:execute) do
|
339
|
+
%({
|
340
|
+
"statusCode" : "OK",
|
341
|
+
"statusMessage" : "",
|
342
|
+
"ipAddress" : "209.85.227.104",
|
343
|
+
"countryCode" : "US",
|
344
|
+
"countryName" : "UNITED STATES",
|
345
|
+
"regionName" : "CALIFORNIA",
|
346
|
+
"cityName" : "MONTEREY PARK",
|
347
|
+
"zipCode" : "91754",
|
348
|
+
"latitude" : "34.0505",
|
349
|
+
"longitude" : "-118.13",
|
350
|
+
"timeZone" : "-08:00"
|
351
|
+
})
|
352
|
+
end
|
353
|
+
-> { GeoIp.geolocation(IPV6_INVALID) }.should raise_error(GeoIp::InvalidIpError)
|
354
|
+
end
|
355
|
+
|
356
|
+
it 'should not trigger invalid ip when valid IPv6 address is provided' do
|
357
|
+
RestClient::Request.stub(:execute) do
|
358
|
+
%({
|
359
|
+
"statusCode" : "OK",
|
360
|
+
"statusMessage" : "",
|
361
|
+
"ipAddress" : "209.85.227.104",
|
362
|
+
"countryCode" : "US",
|
363
|
+
"countryName" : "UNITED STATES",
|
364
|
+
"regionName" : "CALIFORNIA",
|
365
|
+
"cityName" : "MONTEREY PARK",
|
366
|
+
"zipCode" : "91754",
|
367
|
+
"latitude" : "34.0505",
|
368
|
+
"longitude" : "-118.13",
|
369
|
+
"timeZone" : "-08:00"
|
370
|
+
})
|
371
|
+
end
|
372
|
+
-> { GeoIp.geolocation(IPV6) }.should_not raise_error(GeoIp::InvalidIpError)
|
292
373
|
end
|
293
374
|
end
|
294
375
|
end
|
metadata
CHANGED
@@ -1,154 +1,128 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: geo_ip
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 5
|
9
|
-
- 0
|
10
|
-
version: 0.5.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.6.0
|
11
5
|
platform: ruby
|
12
|
-
authors:
|
6
|
+
authors:
|
13
7
|
- Jeroen Jacobs
|
14
8
|
autorequire:
|
15
9
|
bindir: bin
|
16
10
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2015-09-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
22
14
|
name: json
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
hash: 7
|
30
|
-
segments:
|
31
|
-
- 1
|
32
|
-
- 4
|
33
|
-
version: "1.4"
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.4'
|
34
20
|
type: :runtime
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: rest-client
|
38
21
|
prerelease: false
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rest-client
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
49
33
|
version: 1.6.1
|
50
34
|
type: :runtime
|
51
|
-
version_requirements: *id002
|
52
|
-
- !ruby/object:Gem::Dependency
|
53
|
-
name: rake
|
54
35
|
prerelease: false
|
55
|
-
|
56
|
-
|
57
|
-
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.6.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
58
45
|
- - ">="
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
|
61
|
-
segments:
|
62
|
-
- 0
|
63
|
-
version: "0"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
64
48
|
type: :development
|
65
|
-
version_requirements: *id003
|
66
|
-
- !ruby/object:Gem::Dependency
|
67
|
-
name: rspec
|
68
49
|
prerelease: false
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.5'
|
79
62
|
type: :development
|
80
|
-
version_requirements: *id004
|
81
|
-
- !ruby/object:Gem::Dependency
|
82
|
-
name: webmock
|
83
63
|
prerelease: false
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.5'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: webmock
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
94
75
|
version: 1.7.10
|
95
76
|
type: :development
|
96
|
-
|
97
|
-
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.7.10
|
83
|
+
description: A call to the ipinfodb.com will be done to retreive the geolocation based
|
84
|
+
on the IP address. No need to include a database file in the application.
|
98
85
|
email: gems@jeroenj.be
|
99
86
|
executables: []
|
100
|
-
|
101
87
|
extensions: []
|
102
|
-
|
103
88
|
extra_rdoc_files: []
|
104
|
-
|
105
|
-
files:
|
106
|
-
- README.md
|
89
|
+
files:
|
107
90
|
- CHANGES.md
|
108
91
|
- LICENSE
|
92
|
+
- README.md
|
109
93
|
- lib/geo_ip.rb
|
110
94
|
- spec/api.yml
|
111
95
|
- spec/api.yml.example
|
112
96
|
- spec/geo_ip_spec.rb
|
113
97
|
- spec/spec.opts
|
114
98
|
- spec/spec_helper.rb
|
115
|
-
has_rdoc: true
|
116
99
|
homepage: http://jeroenj.be
|
117
100
|
licenses: []
|
118
|
-
|
101
|
+
metadata: {}
|
119
102
|
post_install_message:
|
120
103
|
rdoc_options: []
|
121
|
-
|
122
|
-
require_paths:
|
104
|
+
require_paths:
|
123
105
|
- lib
|
124
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
-
|
126
|
-
requirements:
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
127
108
|
- - ">="
|
128
|
-
- !ruby/object:Gem::Version
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
version: "0"
|
133
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
|
-
none: false
|
135
|
-
requirements:
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
136
113
|
- - ">="
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
|
139
|
-
segments:
|
140
|
-
- 0
|
141
|
-
version: "0"
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
142
116
|
requirements: []
|
143
|
-
|
144
117
|
rubyforge_project:
|
145
|
-
rubygems_version:
|
118
|
+
rubygems_version: 2.4.5.1
|
146
119
|
signing_key:
|
147
|
-
specification_version:
|
120
|
+
specification_version: 4
|
148
121
|
summary: Retreive the geolocation of an IP address based on the ipinfodb.com webservice
|
149
|
-
test_files:
|
122
|
+
test_files:
|
150
123
|
- spec/api.yml
|
151
124
|
- spec/api.yml.example
|
152
125
|
- spec/geo_ip_spec.rb
|
153
126
|
- spec/spec.opts
|
154
127
|
- spec/spec_helper.rb
|
128
|
+
has_rdoc:
|