maxmind-geoip2 1.0.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/README.md +13 -10
  4. data/lib/maxmind/geoip2/client.rb +18 -9
  5. data/lib/maxmind/geoip2/errors.rb +17 -8
  6. data/lib/maxmind/geoip2/model/city.rb +4 -5
  7. data/lib/maxmind/geoip2/model/connection_type.rb +3 -2
  8. data/lib/maxmind/geoip2/model/enterprise.rb +2 -3
  9. data/lib/maxmind/geoip2/model/insights.rb +3 -5
  10. data/lib/maxmind/geoip2/model/isp.rb +16 -0
  11. data/lib/maxmind/geoip2/reader.rb +1 -2
  12. data/lib/maxmind/geoip2/record/traits.rb +58 -26
  13. data/lib/maxmind/geoip2/version.rb +8 -0
  14. data/maxmind-geoip2.gemspec +8 -2
  15. data/test/data/MaxMind-DB-spec.md +15 -11
  16. data/test/data/cmd/write-test-data/main.go +68 -0
  17. data/test/data/go.mod +13 -0
  18. data/test/data/go.sum +16 -0
  19. data/test/data/perltidyrc +6 -0
  20. data/test/data/pkg/writer/decoder.go +178 -0
  21. data/test/data/pkg/writer/geoip2.go +182 -0
  22. data/test/data/pkg/writer/ip.go +39 -0
  23. data/test/data/pkg/writer/maxmind.go +245 -0
  24. data/test/data/pkg/writer/nestedstructures.go +73 -0
  25. data/test/data/pkg/writer/writer.go +58 -0
  26. data/test/data/source-data/GeoIP2-City-Test.json +402 -48
  27. data/test/data/source-data/GeoIP2-Connection-Type-Test.json +35 -10
  28. data/test/data/source-data/GeoIP2-Country-Test.json +145 -58
  29. data/test/data/source-data/GeoIP2-Domain-Test.json +5 -0
  30. data/test/data/source-data/GeoIP2-Enterprise-Test.json +408 -4
  31. data/test/data/source-data/GeoIP2-ISP-Test.json +10 -0
  32. data/test/data/source-data/GeoIP2-Precision-Enterprise-Sandbox-Test.json +296 -0
  33. data/test/data/source-data/GeoIP2-Precision-Enterprise-Test.json +473 -6
  34. data/test/data/source-data/GeoIP2-Static-IP-Score-Test.json +15 -0
  35. data/test/data/source-data/GeoIP2-User-Count-Test.json +18 -0
  36. data/test/data/source-data/GeoLite2-ASN-Test.json +4091 -8
  37. data/test/data/source-data/GeoLite2-City-Test.json +12972 -0
  38. data/test/data/source-data/GeoLite2-Country-Test.json +11372 -0
  39. data/test/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb +0 -0
  40. data/test/data/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb +0 -0
  41. data/test/data/test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb +0 -0
  42. data/test/data/test-data/GeoIP2-City-Test.mmdb +0 -0
  43. data/test/data/test-data/GeoIP2-Connection-Type-Test.mmdb +0 -0
  44. data/test/data/test-data/GeoIP2-Country-Test.mmdb +0 -0
  45. data/test/data/test-data/GeoIP2-DensityIncome-Test.mmdb +0 -0
  46. data/test/data/test-data/GeoIP2-Domain-Test.mmdb +0 -0
  47. data/test/data/test-data/GeoIP2-Enterprise-Test.mmdb +0 -0
  48. data/test/data/test-data/GeoIP2-ISP-Test.mmdb +0 -0
  49. data/test/data/test-data/GeoIP2-Precision-Enterprise-Test.mmdb +0 -0
  50. data/test/data/test-data/GeoIP2-Static-IP-Score-Test.mmdb +0 -0
  51. data/test/data/test-data/GeoIP2-User-Count-Test.mmdb +0 -0
  52. data/test/data/test-data/GeoLite2-ASN-Test.mmdb +0 -0
  53. data/test/data/test-data/GeoLite2-City-Test.mmdb +0 -0
  54. data/test/data/test-data/GeoLite2-Country-Test.mmdb +0 -0
  55. data/test/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb +0 -0
  56. data/test/data/test-data/MaxMind-DB-string-value-entries.mmdb +0 -0
  57. data/test/data/test-data/MaxMind-DB-test-broken-pointers-24.mmdb +0 -0
  58. data/test/data/test-data/MaxMind-DB-test-broken-search-tree-24.mmdb +0 -0
  59. data/test/data/test-data/MaxMind-DB-test-decoder.mmdb +0 -0
  60. data/test/data/test-data/MaxMind-DB-test-ipv4-24.mmdb +0 -0
  61. data/test/data/test-data/MaxMind-DB-test-ipv4-28.mmdb +0 -0
  62. data/test/data/test-data/MaxMind-DB-test-ipv4-32.mmdb +0 -0
  63. data/test/data/test-data/MaxMind-DB-test-ipv6-24.mmdb +0 -0
  64. data/test/data/test-data/MaxMind-DB-test-ipv6-28.mmdb +0 -0
  65. data/test/data/test-data/MaxMind-DB-test-ipv6-32.mmdb +0 -0
  66. data/test/data/test-data/MaxMind-DB-test-metadata-pointers.mmdb +0 -0
  67. data/test/data/test-data/MaxMind-DB-test-mixed-24.mmdb +0 -0
  68. data/test/data/test-data/MaxMind-DB-test-mixed-28.mmdb +0 -0
  69. data/test/data/test-data/MaxMind-DB-test-mixed-32.mmdb +0 -0
  70. data/test/data/test-data/MaxMind-DB-test-nested.mmdb +0 -0
  71. data/test/data/test-data/MaxMind-DB-test-pointer-decoder.mmdb +0 -0
  72. data/test/data/test-data/README.md +30 -14
  73. data/test/test_client.rb +18 -2
  74. data/test/test_reader.rb +37 -3
  75. metadata +21 -8
  76. data/test/data/MaxMind-DB-test-metadata-pointers.mmdb +0 -0
  77. data/test/data/source-data/README +0 -15
  78. data/test/data/test-data/write-test-data.pl +0 -691
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 874135d664c0af2e82c184ce30fffbdfe72bb6badc1aa53ee0ec5eba626e5a1d
4
- data.tar.gz: 7aec662f3893322c983f647545f4a155b27bda20b7fd6349201fc386264bdc88
3
+ metadata.gz: 9c1d04d352a8344e1e8d9c232ab7713bc0b74ddaa1e4a82aec61dbbf37bfd925
4
+ data.tar.gz: 20bcee370b35a4e098b48b36146eb7da9674f6c271ba94744a435addbd9c5e05
5
5
  SHA512:
6
- metadata.gz: 3b5d57920b467ccae6144b6f4aca8266721124481917014025390f02f6728138b704513137596593226506f82d554cf77afb215921a13fa8622e1b4e3a4f8b43
7
- data.tar.gz: 28be946c7ea163e61b641029f3094de7b47ac2ce8bec6d1c68f9ddd5d084f55419403daeb30762fce3d0346ea0fb083de0d946621f6d659eabe03cafe3c3d0dd
6
+ metadata.gz: 0331f1fe319379d035bd4f8675f775bbe31f0d3747d2f9a65754523cb6718160237d5a232d54cad7cd00cdcfe5243ff0f8a39276d749948116fc974221eb3d8a
7
+ data.tar.gz: 1d3e2f6c9a5847671b4b86004c7407bacf25cb271674d7dd49c5217b15d20a307ba416ec19a5f04d2050925ee689a97f01ca899f2edcb611bb44c5ee1a13ba35
data/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.2.0 (2023-12-04)
4
+
5
+ * `MaxMind::GeoIP2::Client` now validates the IP address before making a
6
+ request to the web service.
7
+ * `MaxMind::GeoIP2::Client` now includes the version of Ruby, the version
8
+ of the HTTP client library, and its own version in the User-Agent header.
9
+ * The `anycast?` method was added to `MaxMind::GeoIP2::Record::Traits`.
10
+ This returns `true` if the IP address belongs to an [anycast
11
+ network](https://en.wikipedia.org/wiki/Anycast). This is available for
12
+ the GeoIP2 Country, City Plus, and Insights web services and the GeoIP2
13
+ Country, City, and Enterprise databases.
14
+
15
+ ## 1.1.0 (2021-11-18)
16
+
17
+ * Exceptions from this gem now inherit from `MaxMind::GeoIP2::Error`. IP
18
+ address related exceptions now inherit from
19
+ `MaxMind::GeoIP2::AddressError`, which itself inherits from
20
+ `MaxMind::GeoIP2::Error`. Pull Request by gr8bit. GitHub #35.
21
+ * Support for mobile country code (MCC) and mobile network codes (MNC) was
22
+ added for the GeoIP2 ISP and Enterprise databases as well as the GeoIP2
23
+ City and Insights web services. `mobile_country_code` and
24
+ `mobile_network_code` attributes were added to
25
+ `MaxMind::GeoIP2::Model::ISP` for the GeoIP2 ISP database and
26
+ `MaxMind::GeoIP2::Record::Traits` for the Enterprise database and the
27
+ GeoIP2 City and Insights web services. We expect this data to be
28
+ available by late January, 2022.
29
+
3
30
  ## 1.0.0 (2021-05-14)
4
31
 
5
32
  * Ruby 2.4 is no longer supported. If you're using Ruby 2.4, please use
data/README.md CHANGED
@@ -2,11 +2,9 @@
2
2
 
3
3
  ## Description
4
4
 
5
- This is the Ruby API for the GeoIP2
6
- [webservices](https://dev.maxmind.com/geoip/geoip2/web-services) and
7
- [databases](https://dev.maxmind.com/geoip/geoip2/geolite2/). This API also
8
- works with the free [GeoLite2
9
- databases](https://dev.maxmind.com/geoip/geoip2/geolite2/).
5
+ This is the Ruby API for the GeoIP2 and GeoLite2
6
+ [webservices](https://dev.maxmind.com/geoip/docs/web-services?lang=en)
7
+ and [databases](https://dev.maxmind.com/geoip/docs/databases?lang=en).
10
8
 
11
9
  ## Installation
12
10
 
@@ -230,14 +228,19 @@ client = MaxMind::GeoIP2::Client.new(
230
228
  account_id: 42,
231
229
  license_key: 'license_key',
232
230
 
233
- # To use the GeoLite2 web service instead of GeoIP2 Precision, set
231
+ # To use the GeoLite2 web service instead of the GeoIP2 web service, set
234
232
  # the host parameter to "geolite.info":
235
233
  # host: 'geolite.info',
234
+
235
+ # To use the Sandbox GeoIP2 web service instead of the production GeoIP2
236
+ # web service, set the host parameter to "sandbox.maxmind.com":
237
+ # host: 'sandbox.maxmind.com',
236
238
  )
237
239
 
238
240
  # Replace "city" with the method corresponding to the web service that
239
241
  # you are using, e.g., "country", "insights". Please note that Insights
240
- # is only supported by GeoIP2 Precision and not the GeoLite2 web service.
242
+ # is only supported by the GeoIP2 web service and not the GeoLite2 web
243
+ # service.
241
244
  record = client.city('128.101.101.101')
242
245
 
243
246
  puts record.country.iso_code # US
@@ -281,8 +284,8 @@ which can be populated vary between end points. In addition, while an end
281
284
  point may offer a particular piece of data, MaxMind does not always have
282
285
  every piece of data for any given IP address.
283
286
 
284
- See the [GeoIP2 Precision web service
285
- docs](https://dev.maxmind.com/geoip/geoip2/web-services) for details on
287
+ See the [GeoIP2 web service
288
+ documentation](https://dev.maxmind.com/geoip/docs/web-services?lang=en) for details on
286
289
  what data each end point may return.
287
290
 
288
291
  The only piece of data which is always returned is the `ip_address`
@@ -342,7 +345,7 @@ This library uses [Semantic Versioning](https://semver.org/).
342
345
 
343
346
  ## Copyright and License
344
347
 
345
- This software is Copyright (c) 2020-2021 by MaxMind, Inc.
348
+ This software is Copyright (c) 2020-2023 by MaxMind, Inc.
346
349
 
347
350
  This is free software, licensed under the [Apache License, Version
348
351
  2.0](LICENSE-APACHE) or the [MIT License](LICENSE-MIT), at your option.
@@ -4,15 +4,17 @@ require 'connection_pool'
4
4
  require 'http'
5
5
  require 'json'
6
6
  require 'maxmind/geoip2/errors'
7
+ require 'maxmind/geoip2/version'
7
8
  require 'maxmind/geoip2/model/city'
8
9
  require 'maxmind/geoip2/model/country'
9
10
  require 'maxmind/geoip2/model/insights'
11
+ require 'resolv'
10
12
 
11
13
  module MaxMind
12
14
  module GeoIP2
13
15
  # This class provides a client API for all the
14
- # {https://dev.maxmind.com/geoip/geoip2/web-services/ GeoIP2 Precision web
15
- # services}. The services are Country, City, and Insights. Each service
16
+ # {https://dev.maxmind.com/geoip/docs/web-services?lang=en GeoIP2 web
17
+ # services}. The services are Country, City Plus, and Insights. Each service
16
18
  # returns a different set of data about an IP address, with Country returning
17
19
  # the least data and Insights the most.
18
20
  #
@@ -58,7 +60,7 @@ module MaxMind
58
60
  # rubocop:disable Metrics/CyclomaticComplexity
59
61
  # rubocop:disable Metrics/PerceivedComplexity
60
62
 
61
- # Create a Client that may be used to query a GeoIP2 Precision web service.
63
+ # Create a Client that may be used to query a GeoIP2 web service.
62
64
  #
63
65
  # Once created, the Client is safe to use for lookups from multiple
64
66
  # threads.
@@ -71,8 +73,10 @@ module MaxMind
71
73
  # property from most preferred to least preferred.
72
74
  #
73
75
  # @param host [String] the host to use when querying the web service. Set
74
- # this to "geolite.info" to use the GeoLite2 web service instead of
75
- # GeoIP2 Precision.
76
+ # this to "geolite.info" to use the GeoLite2 web service instead of the
77
+ # GeoIP2 web service. Set this to "sandbox.maxmind.com" to use the
78
+ # Sandbox environment. The sandbox allows you to experiment with the
79
+ # API without affecting your production data.
76
80
  #
77
81
  # @param timeout [Integer] the number of seconds to wait for a request
78
82
  # before timing out. If 0, no timeout is set.
@@ -117,7 +121,7 @@ module MaxMind
117
121
  # rubocop:enable Metrics/CyclomaticComplexity
118
122
  # rubocop:enable Metrics/ParameterLists
119
123
 
120
- # This method calls the City web service.
124
+ # This method calls the City Plus web service.
121
125
  #
122
126
  # @param ip_address [String] IPv4 or IPv6 address as a string. If no
123
127
  # address is provided, the address that the web service is called from is
@@ -193,8 +197,8 @@ module MaxMind
193
197
 
194
198
  # This method calls the Insights web service.
195
199
  #
196
- # Insights is only supported by the GeoIP2 Precision web service. The
197
- # GeoLite2 web service does not support it.
200
+ # Insights is only supported by the GeoIP2 web service. The GeoLite2 web
201
+ # service does not support it.
198
202
  #
199
203
  # @param ip_address [String] IPv4 or IPv6 address as a string. If no
200
204
  # address is provided, the address that the web service is called from is
@@ -234,6 +238,10 @@ module MaxMind
234
238
  private
235
239
 
236
240
  def response_for(endpoint, model_class, ip_address)
241
+ if ip_address != 'me' && ip_address !~ Resolv::AddressRegex
242
+ raise AddressInvalidError, "The value \"#{ip_address}\" is not a valid IP address"
243
+ end
244
+
237
245
  record = get(endpoint, ip_address)
238
246
 
239
247
  model_class.new(record, @locales)
@@ -243,8 +251,9 @@ module MaxMind
243
251
  headers = HTTP.basic_auth(user: @account_id, pass: @license_key)
244
252
  .headers(
245
253
  accept: 'application/json',
246
- user_agent: 'MaxMind-GeoIP2-ruby',
254
+ user_agent: "MaxMind-GeoIP2-ruby/#{VERSION} ruby/#{RUBY_VERSION} http/#{HTTP::VERSION}"
247
255
  )
256
+
248
257
  timeout = @timeout > 0 ? headers.timeout(@timeout) : headers
249
258
 
250
259
  proxy = timeout
@@ -2,40 +2,49 @@
2
2
 
3
3
  module MaxMind
4
4
  module GeoIP2
5
+ # Module's base error class
6
+ class Error < StandardError
7
+ end
8
+
9
+ # Base error class for all errors that originate from the IP address
10
+ # itself and will not change when retried.
11
+ class AddressError < Error
12
+ end
13
+
5
14
  # An AddressNotFoundError means the IP address was not found in the
6
15
  # database or the web service said the IP address was not found.
7
- class AddressNotFoundError < RuntimeError
16
+ class AddressNotFoundError < AddressError
8
17
  end
9
18
 
10
19
  # An HTTPError means there was an unexpected HTTP status or response.
11
- class HTTPError < RuntimeError
20
+ class HTTPError < Error
12
21
  end
13
22
 
14
23
  # An AddressInvalidError means the IP address was invalid.
15
- class AddressInvalidError < RuntimeError
24
+ class AddressInvalidError < AddressError
16
25
  end
17
26
 
18
27
  # An AddressReservedError means the IP address is reserved.
19
- class AddressReservedError < RuntimeError
28
+ class AddressReservedError < AddressError
20
29
  end
21
30
 
22
31
  # An AuthenticationError means there was a problem authenticating to the
23
32
  # web service.
24
- class AuthenticationError < RuntimeError
33
+ class AuthenticationError < Error
25
34
  end
26
35
 
27
36
  # An InsufficientFundsError means the account is out of credits.
28
- class InsufficientFundsError < RuntimeError
37
+ class InsufficientFundsError < Error
29
38
  end
30
39
 
31
40
  # A PermissionRequiredError means the account does not have permission to
32
41
  # use the requested service.
33
- class PermissionRequiredError < RuntimeError
42
+ class PermissionRequiredError < Error
34
43
  end
35
44
 
36
45
  # An InvalidRequestError means the web service returned an error and there
37
46
  # is no more specific error class.
38
- class InvalidRequestError < RuntimeError
47
+ class InvalidRequestError < Error
39
48
  end
40
49
  end
41
50
  end
@@ -9,12 +9,11 @@ require 'maxmind/geoip2/record/subdivision'
9
9
  module MaxMind
10
10
  module GeoIP2
11
11
  module Model
12
- # Model class for the data returned by the GeoIP2 City web service and
13
- # database. It is also used for GeoLite2 City lookups.
12
+ # Model class for the data returned by the GeoIP2 City Plus web service
13
+ # and the City database. It is also used for GeoLite2 City lookups.
14
14
  #
15
- # The only difference between the City and Insights model classes is which
16
- # fields in each record may be populated. See
17
- # https://dev.maxmind.com/geoip/geoip2/web-services for more details.
15
+ # See https://dev.maxmind.com/geoip/docs/web-services?lang=en for more
16
+ # details.
18
17
  #
19
18
  # See {MaxMind::GeoIP2::Model::Country} for inherited methods.
20
19
  class City < Country
@@ -7,8 +7,9 @@ module MaxMind
7
7
  module Model
8
8
  # Model class for the GeoIP2 Connection Type database.
9
9
  class ConnectionType < Abstract
10
- # The connection type may take the following values: "Dialup", "Cable/DSL",
11
- # "Corporate", "Cellular". Additional values may be added in the future.
10
+ # The connection type may take the following values: "Dialup",
11
+ # "Cable/DSL", "Corporate", "Cellular", and "Satellite". Additional
12
+ # values may be added in the future.
12
13
  #
13
14
  # @return [String, nil]
14
15
  def connection_type
@@ -7,9 +7,8 @@ module MaxMind
7
7
  module Model
8
8
  # Model class for the data returned by GeoIP2 Enterprise database lookups.
9
9
  #
10
- # The only difference between the City and Insights model classes is which
11
- # fields in each record may be populated. See
12
- # https://dev.maxmind.com/geoip/geoip2/web-services for more details.
10
+ # See https://dev.maxmind.com/geoip/docs/web-services?lang=en for more
11
+ # details.
13
12
  #
14
13
  # See {MaxMind::GeoIP2::Model::City} for inherited methods.
15
14
  class Enterprise < City
@@ -5,12 +5,10 @@ require 'maxmind/geoip2/model/city'
5
5
  module MaxMind
6
6
  module GeoIP2
7
7
  module Model
8
- # Model class for the data returned by the GeoIP2 Precision Insights web
9
- # service.
8
+ # Model class for the data returned by the GeoIP2 Insights web service.
10
9
  #
11
- # The only difference between the City and Insights model classes is which
12
- # fields in each record may be populated. See
13
- # https://dev.maxmind.com/geoip/geoip2/web-services for more details.
10
+ # See https://dev.maxmind.com/geoip/docs/web-services?lang=en for more
11
+ # details.
14
12
  class Insights < City
15
13
  end
16
14
  end
@@ -36,6 +36,22 @@ module MaxMind
36
36
  get('isp')
37
37
  end
38
38
 
39
+ # The {https://en.wikipedia.org/wiki/Mobile_country_code mobile country
40
+ # code (MCC)} associated with the IP address and ISP.
41
+ #
42
+ # @return [String, nil]
43
+ def mobile_country_code
44
+ get('mobile_country_code')
45
+ end
46
+
47
+ # The {https://en.wikipedia.org/wiki/Mobile_country_code mobile network
48
+ # code (MNC)} associated with the IP address and ISP.
49
+ #
50
+ # @return [String, nil]
51
+ def mobile_network_code
52
+ get('mobile_network_code')
53
+ end
54
+
39
55
  # The network in CIDR notation associated with the record. In particular,
40
56
  # this is the largest network where all of the fields besides ip_address
41
57
  # have the same value.
@@ -37,8 +37,7 @@ module MaxMind
37
37
  # Reader and reuse it.
38
38
  #
39
39
  # Once created, the Reader is safe to use for lookups from multiple
40
- # threads. It is safe to use after forking only if you use
41
- # MaxMind::DB::MODE_MEMORY or if your version of Ruby supports IO#pread.
40
+ # threads. It is safe to use after forking.
42
41
  #
43
42
  # @overload initialize(database:, locales: ['en'], mode: MaxMind::DB::MODE_AUTO)
44
43
  # @param database [String] a path to a GeoIP2/GeoLite2 database file.
@@ -16,16 +16,14 @@ module MaxMind
16
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
- # We could use ip.prefix instead of record['prefix_length'], but that
20
- # method only becomes available in Ruby 2.5+.
21
- record['network'] = format('%s/%d', ip.to_s, record['prefix_length'])
19
+ record['network'] = format('%s/%d', ip.to_s, ip.prefix)
22
20
  end
23
21
  end
24
22
 
25
23
  # The autonomous system number associated with the IP address. See
26
24
  # Wikipedia[https://en.wikipedia.org/wiki/Autonomous_system_(Internet)].
27
- # This attribute is only available from the City and Insights web service
28
- # and the GeoIP2 Enterprise database.
25
+ # This attribute is only available from the City Plus and Insights web
26
+ # services and the Enterprise database.
29
27
  #
30
28
  # @return [Integer, nil]
31
29
  def autonomous_system_number
@@ -35,8 +33,8 @@ module MaxMind
35
33
  # The organization associated with the registered autonomous system number
36
34
  # for the IP address. See
37
35
  # Wikipedia[https://en.wikipedia.org/wiki/Autonomous_system_(Internet)].
38
- # This attribute is only available from the City and Insights web service
39
- # and the GeoIP2 Enterprise database.
36
+ # This attribute is only available from the City Plus and Insights web
37
+ # services and the Enterprise database.
40
38
  #
41
39
  # @return [String, nil]
42
40
  def autonomous_system_organization
@@ -44,8 +42,9 @@ module MaxMind
44
42
  end
45
43
 
46
44
  # The connection type may take the following values: "Dialup",
47
- # "Cable/DSL", "Corporate", "Cellular". Additional values may be added in
48
- # the future. This attribute is only available in the GeoIP2 Enterprise
45
+ # "Cable/DSL", "Corporate", "Cellular", and "Satellite". Additional
46
+ # values may be added in the future. This attribute is only available
47
+ # from the City Plus and Insights web services and the Enterprise
49
48
  # database.
50
49
  #
51
50
  # @return [String, nil]
@@ -55,8 +54,8 @@ module MaxMind
55
54
 
56
55
  # The second level domain associated with the IP address. This will be
57
56
  # something like "example.com" or "example.co.uk", not "foo.example.com".
58
- # This attribute is only available from the City and Insights web service
59
- # and the GeoIP2 Enterprise database.
57
+ # This attribute is only available from the City Plus and Insights web
58
+ # services and the Enterprise database.
60
59
  #
61
60
  # @return [String, nil]
62
61
  def domain
@@ -75,7 +74,7 @@ module MaxMind
75
74
  end
76
75
 
77
76
  # This is true if the IP address belongs to any sort of anonymous network.
78
- # This property is only available from GeoIP2 Precision Insights.
77
+ # This property is only available from Insights.
79
78
  #
80
79
  # @return [Boolean]
81
80
  def anonymous?
@@ -85,17 +84,28 @@ module MaxMind
85
84
  # This is true if the IP address is registered to an anonymous VPN
86
85
  # provider. If a VPN provider does not register subnets under names
87
86
  # associated with them, we will likely only flag their IP ranges using the
88
- # hosting_provider? property. This property is only available from GeoIP2
89
- # Precision Insights.
87
+ # hosting_provider? property. This property is only available from Insights.
90
88
  #
91
89
  # @return [Boolean]
92
90
  def anonymous_vpn?
93
91
  get('is_anonymous_vpn')
94
92
  end
95
93
 
94
+ # This is true if the IP address belongs to an
95
+ # {https://en.wikipedia.org/wiki/Anycast anycast network}.
96
+ #
97
+ # This property is only available from the Country, City Plus, and
98
+ # Insights web services and the GeoIP2 Country, City, and Enterprise
99
+ # databases.
100
+ #
101
+ # @return [Boolean]
102
+ def anycast?
103
+ get('is_anycast')
104
+ end
105
+
96
106
  # This is true if the IP address belongs to a hosting or VPN provider (see
97
107
  # description of the anonymous_vpn? property). This property is only
98
- # available from GeoIP2 Precision Insights.
108
+ # available from Insights.
99
109
  #
100
110
  # @return [Boolean]
101
111
  def hosting_provider?
@@ -104,15 +114,37 @@ module MaxMind
104
114
 
105
115
  # This attribute is true if MaxMind believes this IP address to be a
106
116
  # legitimate proxy, such as an internal VPN used by a corporation. This
107
- # attribute is only available in the GeoIP2 Enterprise database.
117
+ # attribute is only available in the Enterprise database.
108
118
  #
109
119
  # @return [Boolean]
110
120
  def legitimate_proxy?
111
121
  get('is_legitimate_proxy')
112
122
  end
113
123
 
124
+ # The {https://en.wikipedia.org/wiki/Mobile_country_code mobile country
125
+ # code (MCC)} associated with the IP address and ISP.
126
+ #
127
+ # This attribute is only available from the City Plus and Insights web
128
+ # services and the Enterprise database.
129
+ #
130
+ # @return [String, nil]
131
+ def mobile_country_code
132
+ get('mobile_country_code')
133
+ end
134
+
135
+ # The {https://en.wikipedia.org/wiki/Mobile_country_code mobile network
136
+ # code (MNC)} associated with the IP address and ISP.
137
+ #
138
+ # This attribute is only available from the City Plus and Insights web
139
+ # services and the Enterprise database.
140
+ #
141
+ # @return [String, nil]
142
+ def mobile_network_code
143
+ get('mobile_network_code')
144
+ end
145
+
114
146
  # This is true if the IP address belongs to a public proxy. This property
115
- # is only available from GeoIP2 Precision Insights.
147
+ # is only available from Insights.
116
148
  #
117
149
  # @return [Boolean]
118
150
  def public_proxy?
@@ -121,7 +153,7 @@ module MaxMind
121
153
 
122
154
  # This is true if the IP address is on a suspected anonymizing network
123
155
  # and belongs to a residential ISP. This property is only available
124
- # from GeoIP2 Precision Insights.
156
+ # from Insights.
125
157
  #
126
158
  # @return [Boolean]
127
159
  def residential_proxy?
@@ -129,7 +161,7 @@ module MaxMind
129
161
  end
130
162
 
131
163
  # This is true if the IP address is a Tor exit node. This property is only
132
- # available from GeoIP2 Precision Insights.
164
+ # available from Insights.
133
165
  #
134
166
  # @return [Boolean]
135
167
  def tor_exit_node?
@@ -137,7 +169,7 @@ module MaxMind
137
169
  end
138
170
 
139
171
  # The name of the ISP associated with the IP address. This attribute is
140
- # only available from the City and Insights web services and the GeoIP2
172
+ # only available from the City Plus and Insights web services and the
141
173
  # Enterprise database.
142
174
  #
143
175
  # @return [String, nil]
@@ -155,8 +187,8 @@ module MaxMind
155
187
  end
156
188
 
157
189
  # The name of the organization associated with the IP address. This
158
- # attribute is only available from the City and Insights web services and
159
- # the GeoIP2 Enterprise database.
190
+ # attribute is only available from the City Plus and Insights web services
191
+ # and the Enterprise database.
160
192
  #
161
193
  # @return [String, nil]
162
194
  def organization
@@ -164,7 +196,7 @@ module MaxMind
164
196
  end
165
197
 
166
198
  # An indicator of how static or dynamic an IP address is. This property is
167
- # only available from GeoIP2 Precision Insights.
199
+ # only available from Insights.
168
200
  #
169
201
  # @return [Float, nil]
170
202
  def static_ip_score
@@ -173,8 +205,7 @@ module MaxMind
173
205
 
174
206
  # The estimated number of users sharing the IP/network during the past 24
175
207
  # hours. For IPv4, the count is for the individual IP. For IPv6, the count
176
- # is for the /64 network. This property is only available from GeoIP2
177
- # Precision Insights.
208
+ # is for the /64 network. This property is only available from Insights.
178
209
  #
179
210
  # @return [Integer, nil]
180
211
  def user_count
@@ -188,6 +219,7 @@ module MaxMind
188
219
  # * cafe
189
220
  # * cellular
190
221
  # * college
222
+ # * consumer_privacy_network
191
223
  # * content_delivery_network
192
224
  # * dialup
193
225
  # * government
@@ -201,7 +233,7 @@ module MaxMind
201
233
  # * traveler
202
234
  #
203
235
  # This attribute is only available from the Insights web service and the
204
- # GeoIP2 Enterprise database.
236
+ # Enterprise database.
205
237
  #
206
238
  # @return [String, nil]
207
239
  def user_type
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MaxMind
4
+ module GeoIP2
5
+ # The Gem version.
6
+ VERSION = '1.2.0'
7
+ end
8
+ end
@@ -1,11 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'maxmind/geoip2/version'
7
+
3
8
  Gem::Specification.new do |s|
4
9
  s.authors = ['William Storey']
5
10
  s.files = Dir['**/*']
6
11
  s.name = 'maxmind-geoip2'
7
12
  s.summary = 'A gem for interacting with the GeoIP2 webservices and databases.'
8
- s.version = '1.0.0'
13
+ s.version = MaxMind::GeoIP2::VERSION
9
14
 
10
15
  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
16
  s.email = 'support@maxmind.com'
@@ -16,13 +21,14 @@ Gem::Specification.new do |s|
16
21
  'changelog_uri' => 'https://github.com/maxmind/GeoIP2-ruby/blob/main/CHANGELOG.md',
17
22
  'documentation_uri' => 'https://www.rubydoc.info/gems/maxmind-geoip2',
18
23
  'homepage_uri' => 'https://github.com/maxmind/GeoIP2-ruby',
24
+ 'rubygems_mfa_required' => 'true',
19
25
  'source_code_uri' => 'https://github.com/maxmind/GeoIP2-ruby',
20
26
  }
21
27
  s.required_ruby_version = '>= 2.5.0'
22
28
 
23
29
  s.add_runtime_dependency 'connection_pool', ['~> 2.2']
24
30
  s.add_runtime_dependency 'http', '>= 4.3', '< 6.0'
25
- s.add_runtime_dependency 'maxmind-db', ['~> 1.1']
31
+ s.add_runtime_dependency 'maxmind-db', ['~> 1.2']
26
32
 
27
33
  s.add_development_dependency 'minitest'
28
34
  s.add_development_dependency 'rake'
@@ -26,9 +26,10 @@ not be broken by minor version changes to the format.
26
26
  The binary database is split into three parts:
27
27
 
28
28
  1. The binary search tree. Each level of the tree corresponds to a single bit
29
- in the 128 bit representation of an IPv6 address.
30
- 2. The data section. These are the values returned to the client for a
31
- specific IP address, e.g. "US", "New York", or a more complex map type made up
29
+ in the prefix of the network the IP address belongs to.
30
+ 2. The data section with the values for the networks in the binary search
31
+ tree. These values may be comprised of a single data type, e.g., the string
32
+ "US" or "New York", or they may be a more complex map or array type made up
32
33
  of multiple fields.
33
34
  3. Database metadata. Information about the database itself.
34
35
 
@@ -48,15 +49,15 @@ of this sequence.
48
49
  The maximum allowable size for the metadata section, including the marker that
49
50
  starts the metadata, is 128KiB.
50
51
 
51
- The metadata is stored as a map data structure. This structure is described
52
- later in the spec. Changing a key's data type or removing a key would
53
- constitute a major version change for this spec.
52
+ The metadata is stored as a separate data section comprised of a map data
53
+ structure starting at the beginning of that section. This structure is
54
+ described later in the spec.
54
55
 
55
56
  Except where otherwise specified, each key listed is required for the database
56
57
  to be considered valid.
57
58
 
58
- Adding a key constitutes a minor version change. Removing a key or changing
59
- its type constitutes a major version change.
59
+ Changing a key's data type or removing a key would constitute a major version
60
+ change for this spec. Adding a key constitutes a minor version change.
60
61
 
61
62
  The list of known keys for the current version of the format is as follows:
62
63
 
@@ -304,7 +305,8 @@ will point to the beginning of a field. It is illegal for a pointer to point
304
305
  to another pointer.
305
306
 
306
307
  Pointer values start from the beginning of the data section, *not* the
307
- beginning of the file.
308
+ beginning of the file. Pointers in the metadata start from the beginning of
309
+ the metadata section.
308
310
 
309
311
  ### UTF-8 string - 2
310
312
 
@@ -337,8 +339,10 @@ by the length specifier in the control byte. See below for details.
337
339
 
338
340
  A length of zero always indicates the number 0.
339
341
 
340
- When storing a signed integer, the left-most bit is the sign. A 1 is negative
341
- and a 0 is positive.
342
+ When storing a signed integer, fields shorter than the maximum byte length
343
+ are always positive. When the field is the maximum length, e.g., 4 bytes for
344
+ 32-bit integers, the left-most bit is the sign. A 1 is negative and a 0 is
345
+ positive.
342
346
 
343
347
  The type numbers for our integer types are:
344
348