maxmind-geoip2 1.0.0 → 1.2.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.
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