maxmind-geoip2 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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