maxmind-geoip2 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f724b0db8ed7f0700617ba0d37cb08e0b1b10a4ed04d2a59bd8538451d503ffb
4
- data.tar.gz: 172ce815ec47fc1ea64350c9ae5a14880c77a11f429e5a3a7e2bda649903b634
3
+ metadata.gz: 2825710c836cdc4f085ac2e89f88753aa972124ac307af9669866bb355c61f10
4
+ data.tar.gz: c420943be58fd25b84afe0a51264333c4ef268259da7946b58cd7ef77dd8a46b
5
5
  SHA512:
6
- metadata.gz: ac670d5d555b89fd01fbc638ba32f25cb884c6d138ff60154661bcd75197a2f583f243a5431ae19d137752a4077d4ff160c0132c293428d9764e55c3aeee2b4b
7
- data.tar.gz: add54d450ec8f3d5440fb329bc6cd0299b70eb204fdf8b9d2fdec5338a487efe11f917a5630e5a7b02de498078015746deaa13a835823621c70699d44d5b0321
6
+ metadata.gz: 30d7e6caeaeded96d60fb981bcc2c4ce518620e973f3dae47433cd1582265fa315706a826c1bc62d29dfce013d5cee78ab1fefff54f51ef858589a54075b24f0
7
+ data.tar.gz: ca89534bc5f0572ad5b69c7c7b92be70089d6e7e600f962d71a38c8c073299d01ed141c6b1b5089cbca9694c6f49b5b8bcb77a45fb1d2ab668cf3f698c40abdb
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.0 (2021-03-23)
4
+
5
+ * Updated the `MaxMind::GeoIP2::Reader` constructor to support being called
6
+ using keyword arguments. For example, you may now create a `Reader` using
7
+ `MaxMind::GeoIP2::Reader.new(database: 'GeoIP2-Country.mmdb')` instead of
8
+ using positional arguments. This is intended to make it easier to pass in
9
+ optional arguments. Positional argument calling is still supported.
10
+ * Proxy support was fixed. Pull request by Manoj Dayaram. GitHub #30.
11
+
3
12
  ## 0.5.0 (2020-09-25)
4
13
 
5
14
  * Added the `residential_proxy?` method to
data/README.dev.md CHANGED
@@ -1,4 +1,4 @@
1
1
  # How to release
2
2
 
3
3
  See
4
- [here](https://github.com/maxmind/MaxMind-DB-Reader-ruby/blob/master/README.dev.md).
4
+ [here](https://github.com/maxmind/MaxMind-DB-Reader-ruby/blob/main/README.dev.md).
data/README.md CHANGED
@@ -47,7 +47,9 @@ for more details.
47
47
  require 'maxmind/geoip2'
48
48
 
49
49
  # This creates the Reader object which should be reused across lookups.
50
- reader = MaxMind::GeoIP2::Reader.new('/usr/share/GeoIP/GeoIP2-City.mmdb')
50
+ reader = MaxMind::GeoIP2::Reader.new(
51
+ database: '/usr/share/GeoIP/GeoIP2-City.mmdb',
52
+ )
51
53
 
52
54
  record = reader.city('128.101.101.101')
53
55
 
@@ -74,7 +76,9 @@ puts record.traits.network # 128.101.101.101/32
74
76
  require 'maxmind/geoip2'
75
77
 
76
78
  # This creates the Reader object which should be reused across lookups.
77
- reader = MaxMind::GeoIP2::Reader.new('/usr/share/GeoIP/GeoIP2-Country.mmdb')
79
+ reader = MaxMind::GeoIP2::Reader.new(
80
+ database: '/usr/share/GeoIP/GeoIP2-Country.mmdb',
81
+ )
78
82
 
79
83
  record = reader.country('128.101.101.101')
80
84
 
@@ -89,7 +93,9 @@ puts record.country.names['zh-CN'] # '美国'
89
93
  require 'maxmind/geoip2'
90
94
 
91
95
  # This creates the Reader object which should be reused across lookups.
92
- reader = MaxMind::GeoIP2::Reader.new('/usr/share/GeoIP/GeoIP2-Enterprise.mmdb')
96
+ reader = MaxMind::GeoIP2::Reader.new(
97
+ database: '/usr/share/GeoIP/GeoIP2-Enterprise.mmdb',
98
+ )
93
99
 
94
100
  record = reader.enterprise('128.101.101.101')
95
101
 
@@ -120,7 +126,9 @@ puts record.traits.network # 128.101.101.101/32
120
126
  require 'maxmind/geoip2'
121
127
 
122
128
  # This creates the Reader object which should be reused across lookups.
123
- reader = MaxMind::GeoIP2::Reader.new('/usr/share/GeoIP/GeoIP2-Anonymous-IP.mmdb')
129
+ reader = MaxMind::GeoIP2::Reader.new(
130
+ database: '/usr/share/GeoIP/GeoIP2-Anonymous-IP.mmdb',
131
+ )
124
132
 
125
133
  record = reader.anonymous_ip('128.101.101.101')
126
134
 
@@ -133,7 +141,9 @@ puts "Anonymous" if record.is_anonymous
133
141
  require 'maxmind/geoip2'
134
142
 
135
143
  # This creates the Reader object which should be reused across lookups.
136
- reader = MaxMind::GeoIP2::Reader.new('/usr/share/GeoIP/GeoLite2-ASN.mmdb')
144
+ reader = MaxMind::GeoIP2::Reader.new(
145
+ database: '/usr/share/GeoIP/GeoLite2-ASN.mmdb',
146
+ )
137
147
 
138
148
  record = reader.asn('128.101.101.101')
139
149
 
@@ -147,7 +157,9 @@ puts record.autonomous_system_organization # Example Ltd
147
157
  require 'maxmind/geoip2'
148
158
 
149
159
  # This creates the Reader object which should be reused across lookups.
150
- reader = MaxMind::GeoIP2::Reader.new('/usr/share/GeoIP/GeoIP2-Connection-Type.mmdb')
160
+ reader = MaxMind::GeoIP2::Reader.new(
161
+ database: '/usr/share/GeoIP/GeoIP2-Connection-Type.mmdb',
162
+ )
151
163
 
152
164
  record = reader.connection_type('128.101.101.101')
153
165
 
@@ -160,7 +172,9 @@ puts record.connection_type # Cable/DSL
160
172
  require 'maxmind/geoip2'
161
173
 
162
174
  # This creates the Reader object which should be reused across lookups.
163
- reader = MaxMind::GeoIP2::Reader.new('/usr/share/GeoIP/GeoIP2-Domain.mmdb')
175
+ reader = MaxMind::GeoIP2::Reader.new(
176
+ database: '/usr/share/GeoIP/GeoIP2-Domain.mmdb',
177
+ )
164
178
 
165
179
  record = reader.domain('128.101.101.101')
166
180
 
@@ -173,7 +187,9 @@ puts record.domain # example.com
173
187
  require 'maxmind/geoip2'
174
188
 
175
189
  # This creates the Reader object which should be reused across lookups.
176
- reader = MaxMind::GeoIP2::Reader.new('/usr/share/GeoIP/GeoIP2-ISP.mmdb')
190
+ reader = MaxMind::GeoIP2::Reader.new(
191
+ database: '/usr/share/GeoIP/GeoIP2-ISP.mmdb',
192
+ )
177
193
 
178
194
  record = reader.isp('128.101.101.101')
179
195
 
@@ -188,9 +204,10 @@ puts record.organization # University of Minnesota
188
204
  ### Usage
189
205
 
190
206
  To use this API, you must create a new `MaxMind::GeoIP2::Client` object
191
- with your account ID and license key, then you call the method
192
- corresponding to a specific end point, passing it the IP address you want
193
- to look up.
207
+ with your account ID and license key. To use the GeoLite2 web service, you
208
+ may also set the `host` parameter to `geolite.info`. You may then you call
209
+ the method corresponding to a specific end point, passing it the IP address
210
+ you want to look up.
194
211
 
195
212
  If the request succeeds, the method call will return a model class for the end
196
213
  point you called. This model in turn contains multiple record classes, each of
@@ -212,13 +229,18 @@ require 'maxmind/geoip2'
212
229
  client = MaxMind::GeoIP2::Client.new(
213
230
  account_id: 42,
214
231
  license_key: 'license_key',
232
+
233
+ # To use the GeoLite2 web service instead of GeoIP2 Precision, set
234
+ # the host parameter to "geolite.info":
235
+ # host: 'geolite.info',
215
236
  )
216
237
 
217
238
  # Replace "city" with the method corresponding to the web service that
218
- # you are using, e.g., "country", "insights".
239
+ # you are using, e.g., "country", "insights". Please note that Insights
240
+ # is only supported by GeoIP2 Precision and not the GeoLite2 web service.
219
241
  record = client.city('128.101.101.101')
220
242
 
221
- puts record.country.isoCode # US
243
+ puts record.country.iso_code # US
222
244
  puts record.country.name # United States
223
245
  puts record.country.names['zh-CN'] # 美国
224
246
 
@@ -68,7 +68,9 @@ module MaxMind
68
68
  # @param locales [Array<String>] a list of locale codes to use in the name
69
69
  # property from most preferred to least preferred.
70
70
  #
71
- # @param host [String] the host to use when querying the web service.
71
+ # @param host [String] the host to use when querying the web service. Set
72
+ # this to "geolite.info" to use the GeoLite2 web service instead of
73
+ # GeoIP2 Precision.
72
74
  #
73
75
  # @param timeout [Integer] the number of seconds to wait for a request
74
76
  # before timing out. If 0, no timeout is set.
@@ -111,7 +113,7 @@ module MaxMind
111
113
  end
112
114
  # rubocop:enable Metrics/ParameterLists
113
115
 
114
- # This method calls the GeoIP2 Precision City web service.
116
+ # This method calls the City web service.
115
117
  #
116
118
  # @param ip_address [String] IPv4 or IPv6 address as a string. If no
117
119
  # address is provided, the address that the web service is called from is
@@ -148,7 +150,7 @@ module MaxMind
148
150
  response_for('city', MaxMind::GeoIP2::Model::City, ip_address)
149
151
  end
150
152
 
151
- # This method calls the GeoIP2 Precision Country web service.
153
+ # This method calls the Country web service.
152
154
  #
153
155
  # @param ip_address [String] IPv4 or IPv6 address as a string. If no
154
156
  # address is provided, the address that the web service is called from is
@@ -185,7 +187,10 @@ module MaxMind
185
187
  response_for('country', MaxMind::GeoIP2::Model::Country, ip_address)
186
188
  end
187
189
 
188
- # This method calls the GeoIP2 Precision Insights web service.
190
+ # This method calls the Insights web service.
191
+ #
192
+ # Insights is only supported by the GeoIP2 Precision web service. The
193
+ # GeoLite2 web service does not support it.
189
194
  #
190
195
  # @param ip_address [String] IPv4 or IPv6 address as a string. If no
191
196
  # address is provided, the address that the web service is called from is
@@ -240,11 +245,11 @@ module MaxMind
240
245
 
241
246
  proxy = timeout
242
247
  if @proxy_address != ''
243
- opts = {}
244
- opts[:proxy_port] = @proxy_port if @proxy_port != 0
245
- opts[:proxy_username] = @proxy_username if @proxy_username != ''
246
- opts[:proxy_password] = @proxy_password if @proxy_password != ''
247
- proxy = timeout.via(@proxy_address, opts)
248
+ proxy_params = [@proxy_address]
249
+ proxy_params << (@proxy_port == 0 ? nil : @proxy_port)
250
+ proxy_params << (@proxy_username == '' ? nil : @proxy_username)
251
+ proxy_params << (@proxy_password == '' ? nil : @proxy_password)
252
+ proxy = timeout.via(*proxy_params)
248
253
  end
249
254
 
250
255
  proxy
@@ -20,13 +20,16 @@ module MaxMind
20
20
  #
21
21
  # require 'maxmind/geoip2'
22
22
  #
23
- # reader = MaxMind::GeoIP2::Reader.new('GeoIP2-Country.mmdb')
23
+ # reader = MaxMind::GeoIP2::Reader.new(database: 'GeoIP2-Country.mmdb')
24
24
  #
25
25
  # record = reader.country('1.2.3.4')
26
26
  # puts record.country.iso_code
27
27
  #
28
28
  # reader.close
29
29
  class Reader
30
+ # rubocop:disable Metrics/CyclomaticComplexity
31
+ # rubocop:disable Metrics/PerceivedComplexity
32
+
30
33
  # Create a Reader for looking up IP addresses in a GeoIP2/GeoLite2 database
31
34
  # file.
32
35
  #
@@ -37,30 +40,52 @@ module MaxMind
37
40
  # threads. It is safe to use after forking only if you use
38
41
  # MaxMind::DB::MODE_MEMORY or if your version of Ruby supports IO#pread.
39
42
  #
40
- # @param database [String] a path to a GeoIP2/GeoLite2 database file.
41
- #
42
- # @param locales [Array<String>] a list of locale codes to use in the name
43
- # property from most preferred to least preferred.
44
- #
45
- # @param options [Hash<Symbol, Symbol>] options controlling the behavior of
46
- # the Reader.
43
+ # @overload initialize(database:, locales: ['en'], mode: MaxMind::DB::MODE_AUTO)
44
+ # @param database [String] a path to a GeoIP2/GeoLite2 database file.
45
+ # @param locales [Array<String>] a list of locale codes to use in the name
46
+ # property from most preferred to least preferred.
47
+ # @param mode [Symbol] Defines how to open the database. It may be one of
48
+ # MaxMind::DB::MODE_AUTO, MaxMind::DB::MODE_FILE, or
49
+ # MaxMind::DB::MODE_MEMORY. If you don't provide one, the Reader uses
50
+ # MaxMind::DB::MODE_AUTO. Refer to the definition of those constants in
51
+ # MaxMind::DB for an explanation of their meaning.
47
52
  #
48
- # @option options [Symbol] :mode Defines how to open the database. It may
49
- # be one of MaxMind::DB::MODE_AUTO, MaxMind::DB::MODE_FILE, or
50
- # MaxMind::DB::MODE_MEMORY. If you don't provide one, the Reader uses
51
- # MaxMind::DB::MODE_AUTO. Refer to the definition of those constants in
52
- # MaxMind::DB for an explanation of their meaning.
53
- #
54
- # @raise [MaxMind::DB::InvalidDatabaseError] if the database is corrupt or
55
- # invalid.
53
+ # @raise [MaxMind::DB::InvalidDatabaseError] if the database is corrupt
54
+ # or invalid.
56
55
  #
57
56
  # @raise [ArgumentError] if the mode is invalid.
58
- def initialize(database, locales = ['en'], options = {})
57
+ def initialize(*args)
58
+ # This if statement is to let us support calling as though we are using
59
+ # Ruby 2.0 keyword arguments. We can't use keyword argument syntax as
60
+ # we want to be backwards compatible with the old way we accepted
61
+ # parameters, which looked like:
62
+ # def initialize(database, locales = ['en'], options = {})
63
+ if args.length == 1 && args[0].instance_of?(Hash)
64
+ database = args[0][:database]
65
+ locales = args[0][:locales]
66
+ mode = args[0][:mode]
67
+ else
68
+ database = args[0]
69
+ locales = args[1]
70
+ mode = args[2].instance_of?(Hash) ? args[2][:mode] : nil
71
+ end
72
+
73
+ if !database.instance_of?(String)
74
+ raise ArgumentError, 'Invalid database parameter'
75
+ end
76
+
77
+ locales = ['en'] if locales.nil? || locales.empty?
78
+
79
+ options = {}
80
+ options[:mode] = mode if !mode.nil?
59
81
  @reader = MaxMind::DB.new(database, options)
82
+
60
83
  @type = @reader.metadata.database_type
61
- locales = ['en'] if locales.empty?
84
+
62
85
  @locales = locales
63
86
  end
87
+ # rubocop:enable Metrics/CyclomaticComplexity
88
+ # rubocop:enable Metrics/PerceivedComplexity
64
89
 
65
90
  # Look up the IP address in the database.
66
91
  #
@@ -13,7 +13,7 @@ module MaxMind
13
13
  # @!visibility private
14
14
  def initialize(record)
15
15
  super(record)
16
- if !record.key?('network') && record.key?('ip_address') &&
16
+ if record && !record.key?('network') && record.key?('ip_address') &&
17
17
  record.key?('prefix_length')
18
18
  ip = IPAddr.new(record['ip_address']).mask(record['prefix_length'])
19
19
  # We could use ip.prefix instead of record['prefix_length'], but that
@@ -69,7 +69,7 @@ module MaxMind
69
69
  # NAT, this may differ from the IP address locally assigned to it. This
70
70
  # attribute is returned by all end points.
71
71
  #
72
- # @return [String]
72
+ # @return [String, nil]
73
73
  def ip_address
74
74
  get('ip_address')
75
75
  end
@@ -149,7 +149,7 @@ module MaxMind
149
149
  # this is the largest network where all of the fields besides ip_address
150
150
  # have the same value.
151
151
  #
152
- # @return [String]
152
+ # @return [String, nil]
153
153
  def network
154
154
  get('network')
155
155
  end
@@ -5,7 +5,7 @@ Gem::Specification.new do |s|
5
5
  s.files = Dir['**/*']
6
6
  s.name = 'maxmind-geoip2'
7
7
  s.summary = 'A gem for interacting with the GeoIP2 webservices and databases.'
8
- s.version = '0.5.0'
8
+ s.version = '0.6.0'
9
9
 
10
10
  s.description = 'A gem for interacting with the GeoIP2 webservices and databases. MaxMind provides geolocation data as downloadable databases as well as through a webservice.'
11
11
  s.email = 'support@maxmind.com'
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
13
13
  s.licenses = ['Apache-2.0', 'MIT']
14
14
  s.metadata = {
15
15
  'bug_tracker_uri' => 'https://github.com/maxmind/GeoIP2-ruby/issues',
16
- 'changelog_uri' => 'https://github.com/maxmind/GeoIP2-ruby/blob/master/CHANGELOG.md',
16
+ 'changelog_uri' => 'https://github.com/maxmind/GeoIP2-ruby/blob/main/CHANGELOG.md',
17
17
  'documentation_uri' => 'https://www.rubydoc.info/gems/maxmind-geoip2',
18
18
  'homepage_uri' => 'https://github.com/maxmind/GeoIP2-ruby',
19
19
  'source_code_uri' => 'https://github.com/maxmind/GeoIP2-ruby',
data/test/test_client.rb CHANGED
@@ -339,12 +339,12 @@ class ClientTest < Minitest::Test
339
339
  status: 400,
340
340
  },
341
341
  '1.2.3.71' => {
342
- body: JSON.generate({ 'code': 'HI' }),
342
+ body: JSON.generate({ code: 'HI' }),
343
343
  headers: { 'Content-Type': CONTENT_TYPES[:country] },
344
344
  status: 400,
345
345
  },
346
346
  '1.2.3.8' => {
347
- body: JSON.generate({ 'weird': 42 }),
347
+ body: JSON.generate({ weird: 42 }),
348
348
  headers: { 'Content-Type': CONTENT_TYPES[:country] },
349
349
  status: 400,
350
350
  },
@@ -77,4 +77,20 @@ class CountryModelTest < Minitest::Test
77
77
  model = MaxMind::GeoIP2::Model::Country.new(RAW, ['en'])
78
78
  assert_raises(NoMethodError) { model.traits.unknown }
79
79
  end
80
+
81
+ # This can happen if we're being created from a not fully populated response
82
+ # when used by minFraud. It shouldn't ever happen from GeoIP2 though.
83
+ def test_no_traits
84
+ model = MaxMind::GeoIP2::Model::Country.new(
85
+ {
86
+ 'continent' => {
87
+ 'code' => 'NA',
88
+ 'geoname_id' => 42,
89
+ 'names' => { 'en' => 'North America' },
90
+ },
91
+ },
92
+ ['en'],
93
+ )
94
+ assert_equal(42, model.continent.geoname_id)
95
+ end
80
96
  end
data/test/test_reader.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'ipaddr'
4
+ require 'maxmind/db'
4
5
  require 'maxmind/geoip2'
5
6
  require 'minitest/autorun'
6
7
 
@@ -469,4 +470,49 @@ class ReaderTest < Minitest::Test
469
470
  assert_equal('GeoIP2-City', reader.metadata.database_type)
470
471
  reader.close
471
472
  end
473
+
474
+ def test_constructor_with_minimum_keyword_arguments
475
+ reader = MaxMind::GeoIP2::Reader.new(
476
+ database: 'test/data/test-data/GeoIP2-Country-Test.mmdb',
477
+ )
478
+ record = reader.country('81.2.69.160')
479
+ assert_equal('United Kingdom', record.country.name)
480
+ reader.close
481
+ end
482
+
483
+ def test_constructor_with_all_keyword_arguments
484
+ reader = MaxMind::GeoIP2::Reader.new(
485
+ database: 'test/data/test-data/GeoIP2-Country-Test.mmdb',
486
+ locales: %w[ru],
487
+ mode: MaxMind::DB::MODE_MEMORY,
488
+ )
489
+ record = reader.country('81.2.69.160')
490
+ assert_equal('Великобритания', record.country.name)
491
+ reader.close
492
+ end
493
+
494
+ def test_constructor_missing_database
495
+ error = assert_raises(ArgumentError) do
496
+ MaxMind::GeoIP2::Reader.new
497
+ end
498
+ assert_equal('Invalid database parameter', error.message)
499
+
500
+ error = assert_raises(ArgumentError) do
501
+ MaxMind::GeoIP2::Reader.new(
502
+ locales: %w[ru],
503
+ )
504
+ end
505
+ assert_equal('Invalid database parameter', error.message)
506
+ end
507
+
508
+ def test_old_constructor_parameters
509
+ reader = MaxMind::GeoIP2::Reader.new(
510
+ 'test/data/test-data/GeoIP2-Country-Test.mmdb',
511
+ %w[ru],
512
+ mode: MaxMind::DB::MODE_MEMORY,
513
+ )
514
+ record = reader.country('81.2.69.160')
515
+ assert_equal('Великобритания', record.country.name)
516
+ reader.close
517
+ end
472
518
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maxmind-geoip2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Storey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-25 00:00:00.000000000 Z
11
+ date: 2021-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: connection_pool
@@ -235,7 +235,7 @@ licenses:
235
235
  - MIT
236
236
  metadata:
237
237
  bug_tracker_uri: https://github.com/maxmind/GeoIP2-ruby/issues
238
- changelog_uri: https://github.com/maxmind/GeoIP2-ruby/blob/master/CHANGELOG.md
238
+ changelog_uri: https://github.com/maxmind/GeoIP2-ruby/blob/main/CHANGELOG.md
239
239
  documentation_uri: https://www.rubydoc.info/gems/maxmind-geoip2
240
240
  homepage_uri: https://github.com/maxmind/GeoIP2-ruby
241
241
  source_code_uri: https://github.com/maxmind/GeoIP2-ruby