maxmind-geoip2 0.1.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 +4 -4
- data/CHANGELOG.md +32 -0
- data/Gemfile +1 -5
- data/README.dev.md +1 -1
- data/README.md +82 -8
- data/lib/maxmind/geoip2.rb +1 -0
- data/lib/maxmind/geoip2/client.rb +333 -0
- data/lib/maxmind/geoip2/errors.rb +37 -3
- data/lib/maxmind/geoip2/model/abstract.rb +19 -15
- data/lib/maxmind/geoip2/model/anonymous_ip.rb +62 -50
- data/lib/maxmind/geoip2/model/asn.rb +33 -29
- data/lib/maxmind/geoip2/model/city.rb +59 -55
- data/lib/maxmind/geoip2/model/connection_type.rb +27 -23
- data/lib/maxmind/geoip2/model/country.rb +64 -53
- data/lib/maxmind/geoip2/model/domain.rb +27 -23
- data/lib/maxmind/geoip2/model/enterprise.rb +13 -9
- data/lib/maxmind/geoip2/model/insights.rb +18 -0
- data/lib/maxmind/geoip2/model/isp.rb +45 -41
- data/lib/maxmind/geoip2/reader.rb +260 -233
- data/lib/maxmind/geoip2/record/abstract.rb +17 -13
- data/lib/maxmind/geoip2/record/city.rb +33 -29
- data/lib/maxmind/geoip2/record/continent.rb +32 -28
- data/lib/maxmind/geoip2/record/country.rb +47 -43
- data/lib/maxmind/geoip2/record/location.rb +64 -60
- data/lib/maxmind/geoip2/record/maxmind.rb +21 -0
- data/lib/maxmind/geoip2/record/place.rb +22 -18
- data/lib/maxmind/geoip2/record/postal.rb +26 -22
- data/lib/maxmind/geoip2/record/represented_country.rb +20 -16
- data/lib/maxmind/geoip2/record/subdivision.rb +42 -38
- data/lib/maxmind/geoip2/record/traits.rb +204 -191
- data/maxmind-geoip2.gemspec +11 -3
- data/test/data/bad-data/maxminddb-python/bad-unicode-in-map-key.mmdb +0 -0
- data/test/data/source-data/GeoIP2-Anonymous-IP-Test.json +1 -0
- data/test/data/source-data/GeoIP2-ISP-Test.json +3 -1
- data/test/data/source-data/GeoIP2-Precision-Enterprise-Test.json +87 -0
- data/test/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb +0 -0
- data/test/data/test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb +0 -0
- data/test/data/test-data/GeoIP2-City-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Connection-Type-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Country-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-DensityIncome-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Domain-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Enterprise-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-ISP-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Precision-Enterprise-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Static-IP-Score-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-User-Count-Test.mmdb +0 -0
- data/test/data/test-data/GeoLite2-ASN-Test.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-string-value-entries.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-broken-pointers-24.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-broken-search-tree-24.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-decoder.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv4-24.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv4-28.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv4-32.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv6-24.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv6-28.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv6-32.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-metadata-pointers.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-mixed-24.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-mixed-28.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-mixed-32.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-nested.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-pointer-decoder.mmdb +0 -0
- data/test/data/test-data/write-test-data.pl +68 -18
- data/test/test_client.rb +426 -0
- data/test/test_model_country.rb +16 -0
- data/test/test_reader.rb +59 -0
- metadata +113 -10
- data/Gemfile.lock +0 -38
@@ -2,62 +2,73 @@
|
|
2
2
|
|
3
3
|
require 'maxmind/geoip2/record/continent'
|
4
4
|
require 'maxmind/geoip2/record/country'
|
5
|
+
require 'maxmind/geoip2/record/maxmind'
|
5
6
|
require 'maxmind/geoip2/record/represented_country'
|
6
7
|
require 'maxmind/geoip2/record/traits'
|
7
8
|
|
8
|
-
module MaxMind
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
locales
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
9
|
+
module MaxMind
|
10
|
+
module GeoIP2
|
11
|
+
module Model
|
12
|
+
# Model class for the data returned by the GeoIP2 Country web service and
|
13
|
+
# database. It is also used for GeoLite2 Country lookups.
|
14
|
+
class Country
|
15
|
+
# Continent data for the IP address.
|
16
|
+
#
|
17
|
+
# @return [MaxMind::GeoIP2::Record::Continent]
|
18
|
+
attr_reader :continent
|
19
|
+
|
20
|
+
# Country data for the IP address. This object represents the country where
|
21
|
+
# MaxMind believes the end user is located.
|
22
|
+
#
|
23
|
+
# @return [MaxMind::GeoIP2::Record::Country]
|
24
|
+
attr_reader :country
|
25
|
+
|
26
|
+
# Data related to your MaxMind account.
|
27
|
+
#
|
28
|
+
# @return [MaxMind::GeoIP2::Record::MaxMind]
|
29
|
+
attr_reader :maxmind
|
30
|
+
|
31
|
+
# Registered country data for the IP address. This record represents the
|
32
|
+
# country where the ISP has registered a given IP block and may differ from
|
33
|
+
# the user's country.
|
34
|
+
#
|
35
|
+
# @return [MaxMind::GeoIP2::Record::Country]
|
36
|
+
attr_reader :registered_country
|
37
|
+
|
38
|
+
# Represented country data for the IP address. The represented country is
|
39
|
+
# used for things like military bases. It is only present when the
|
40
|
+
# represented country differs from the country.
|
41
|
+
#
|
42
|
+
# @return [MaxMind::GeoIP2::Record::RepresentedCountry]
|
43
|
+
attr_reader :represented_country
|
44
|
+
|
45
|
+
# Data for the traits of the IP address.
|
46
|
+
#
|
47
|
+
# @return [MaxMind::GeoIP2::Record::Traits]
|
48
|
+
attr_reader :traits
|
49
|
+
|
50
|
+
# @!visibility private
|
51
|
+
def initialize(record, locales)
|
52
|
+
@continent = MaxMind::GeoIP2::Record::Continent.new(
|
53
|
+
record['continent'],
|
54
|
+
locales,
|
55
|
+
)
|
56
|
+
@country = MaxMind::GeoIP2::Record::Country.new(
|
57
|
+
record['country'],
|
58
|
+
locales,
|
59
|
+
)
|
60
|
+
@maxmind = MaxMind::GeoIP2::Record::MaxMind.new(record['maxmind'])
|
61
|
+
@registered_country = MaxMind::GeoIP2::Record::Country.new(
|
62
|
+
record['registered_country'],
|
63
|
+
locales,
|
64
|
+
)
|
65
|
+
@represented_country = MaxMind::GeoIP2::Record::RepresentedCountry.new(
|
66
|
+
record['represented_country'],
|
67
|
+
locales,
|
68
|
+
)
|
69
|
+
@traits = MaxMind::GeoIP2::Record::Traits.new(record['traits'])
|
70
|
+
end
|
71
|
+
end
|
61
72
|
end
|
62
73
|
end
|
63
74
|
end
|
@@ -2,31 +2,35 @@
|
|
2
2
|
|
3
3
|
require 'maxmind/geoip2/model/abstract'
|
4
4
|
|
5
|
-
module MaxMind
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
5
|
+
module MaxMind
|
6
|
+
module GeoIP2
|
7
|
+
module Model
|
8
|
+
# Model class for the GeoIP2 Domain database.
|
9
|
+
class Domain < Abstract
|
10
|
+
# The second level domain associated with the IP address. This will be
|
11
|
+
# something like "example.com" or "example.co.uk", not "foo.example.com".
|
12
|
+
#
|
13
|
+
# @return [String, nil]
|
14
|
+
def domain
|
15
|
+
get('domain')
|
16
|
+
end
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
# The IP address that the data in the model is for.
|
19
|
+
#
|
20
|
+
# @return [String]
|
21
|
+
def ip_address
|
22
|
+
get('ip_address')
|
23
|
+
end
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
# The network in CIDR notation associated with the record. In particular,
|
26
|
+
# this is the largest network where all of the fields besides ip_address
|
27
|
+
# have the same value.
|
28
|
+
#
|
29
|
+
# @return [String]
|
30
|
+
def network
|
31
|
+
get('network')
|
32
|
+
end
|
33
|
+
end
|
30
34
|
end
|
31
35
|
end
|
32
36
|
end
|
@@ -2,14 +2,18 @@
|
|
2
2
|
|
3
3
|
require 'maxmind/geoip2/model/city'
|
4
4
|
|
5
|
-
module MaxMind
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
5
|
+
module MaxMind
|
6
|
+
module GeoIP2
|
7
|
+
module Model
|
8
|
+
# Model class for the data returned by GeoIP2 Enterprise database lookups.
|
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.
|
13
|
+
#
|
14
|
+
# See {MaxMind::GeoIP2::Model::City} for inherited methods.
|
15
|
+
class Enterprise < City
|
16
|
+
end
|
17
|
+
end
|
14
18
|
end
|
15
19
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'maxmind/geoip2/model/city'
|
4
|
+
|
5
|
+
module MaxMind
|
6
|
+
module GeoIP2
|
7
|
+
module Model
|
8
|
+
# Model class for the data returned by the GeoIP2 Precision Insights web
|
9
|
+
# service.
|
10
|
+
#
|
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.
|
14
|
+
class Insights < City
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -2,52 +2,56 @@
|
|
2
2
|
|
3
3
|
require 'maxmind/geoip2/model/abstract'
|
4
4
|
|
5
|
-
module MaxMind
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
5
|
+
module MaxMind
|
6
|
+
module GeoIP2
|
7
|
+
module Model
|
8
|
+
# Model class for the GeoIP2 ISP database.
|
9
|
+
class ISP < Abstract
|
10
|
+
# The autonomous system number associated with the IP address.
|
11
|
+
#
|
12
|
+
# @return [Integer, nil]
|
13
|
+
def autonomous_system_number
|
14
|
+
get('autonomous_system_number')
|
15
|
+
end
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
# The organization associated with the registered autonomous system number
|
18
|
+
# for the IP address.
|
19
|
+
#
|
20
|
+
# @return [String, nil]
|
21
|
+
def autonomous_system_organization
|
22
|
+
get('autonomous_system_organization')
|
23
|
+
end
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
# The IP address that the data in the model is for.
|
26
|
+
#
|
27
|
+
# @return [String]
|
28
|
+
def ip_address
|
29
|
+
get('ip_address')
|
30
|
+
end
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
# The name of the ISP associated with the IP address.
|
33
|
+
#
|
34
|
+
# @return [String, nil]
|
35
|
+
def isp
|
36
|
+
get('isp')
|
37
|
+
end
|
36
38
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
# The network in CIDR notation associated with the record. In particular,
|
40
|
+
# this is the largest network where all of the fields besides ip_address
|
41
|
+
# have the same value.
|
42
|
+
#
|
43
|
+
# @return [String]
|
44
|
+
def network
|
45
|
+
get('network')
|
46
|
+
end
|
45
47
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
# The name of the organization associated with the IP address.
|
49
|
+
#
|
50
|
+
# @return [String, nil]
|
51
|
+
def organization
|
52
|
+
get('organization')
|
53
|
+
end
|
54
|
+
end
|
51
55
|
end
|
52
56
|
end
|
53
57
|
end
|
@@ -11,267 +11,294 @@ require 'maxmind/geoip2/model/domain'
|
|
11
11
|
require 'maxmind/geoip2/model/enterprise'
|
12
12
|
require 'maxmind/geoip2/model/isp'
|
13
13
|
|
14
|
-
module MaxMind
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
# == Example
|
19
|
-
#
|
20
|
-
# require 'maxmind/geoip2'
|
21
|
-
#
|
22
|
-
# reader = MaxMind::GeoIP2::Reader.new('GeoIP2-Country.mmdb')
|
23
|
-
#
|
24
|
-
# record = reader.country('1.2.3.4')
|
25
|
-
# puts record.country.iso_code
|
26
|
-
#
|
27
|
-
# reader.close
|
28
|
-
class Reader
|
29
|
-
# Create a Reader for looking up IP addresses in a GeoIP2/GeoLite2 database
|
30
|
-
# file.
|
14
|
+
module MaxMind
|
15
|
+
module GeoIP2
|
16
|
+
# Reader is a reader for the GeoIP2/GeoLite2 database format. IP addresses
|
17
|
+
# can be looked up using the database specific methods.
|
31
18
|
#
|
32
|
-
#
|
33
|
-
# Reader and reuse it.
|
19
|
+
# == Example
|
34
20
|
#
|
35
|
-
#
|
36
|
-
# threads. It is safe to use after forking only if you use
|
37
|
-
# MaxMind::DB::MODE_MEMORY or if your version of Ruby supports IO#pread.
|
21
|
+
# require 'maxmind/geoip2'
|
38
22
|
#
|
39
|
-
#
|
23
|
+
# reader = MaxMind::GeoIP2::Reader.new(database: 'GeoIP2-Country.mmdb')
|
40
24
|
#
|
41
|
-
#
|
42
|
-
#
|
25
|
+
# record = reader.country('1.2.3.4')
|
26
|
+
# puts record.country.iso_code
|
43
27
|
#
|
44
|
-
#
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
# be one of 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.
|
52
|
-
#
|
53
|
-
# @raise [MaxMind::DB::InvalidDatabaseError] if the database is corrupt or
|
54
|
-
# invalid.
|
55
|
-
#
|
56
|
-
# @raise [ArgumentError] if the mode is invalid.
|
57
|
-
def initialize(database, locales = ['en'], options = {})
|
58
|
-
@reader = MaxMind::DB.new(database, options)
|
59
|
-
@type = @reader.metadata.database_type
|
60
|
-
locales = ['en'] if locales.empty?
|
61
|
-
@locales = locales
|
62
|
-
end
|
28
|
+
# reader.close
|
29
|
+
class Reader
|
30
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
31
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
63
32
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
33
|
+
# Create a Reader for looking up IP addresses in a GeoIP2/GeoLite2 database
|
34
|
+
# file.
|
35
|
+
#
|
36
|
+
# If you're performing multiple lookups, it's most efficient to create one
|
37
|
+
# Reader and reuse it.
|
38
|
+
#
|
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.
|
42
|
+
#
|
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.
|
52
|
+
#
|
53
|
+
# @raise [MaxMind::DB::InvalidDatabaseError] if the database is corrupt
|
54
|
+
# or invalid.
|
55
|
+
#
|
56
|
+
# @raise [ArgumentError] if the mode is invalid.
|
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
|
87
72
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
# IPv4 or IPv6.
|
92
|
-
#
|
93
|
-
# @return [MaxMind::GeoIP2::Model::ASN]
|
94
|
-
#
|
95
|
-
# @raise [ArgumentError] if used against a non-ASN database or if you
|
96
|
-
# attempt to look up an IPv6 address in an IPv4 only database.
|
97
|
-
#
|
98
|
-
# @raise [AddressNotFoundError] if the IP address is not found in the
|
99
|
-
# database.
|
100
|
-
#
|
101
|
-
# @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
|
102
|
-
# corrupt.
|
103
|
-
def asn(ip_address)
|
104
|
-
flat_model_for(Model::ASN, 'asn', 'GeoLite2-ASN', ip_address)
|
105
|
-
end
|
73
|
+
if !database.instance_of?(String)
|
74
|
+
raise ArgumentError, 'Invalid database parameter'
|
75
|
+
end
|
106
76
|
|
107
|
-
|
108
|
-
#
|
109
|
-
# @param ip_address [String] a string in the standard notation. It may be
|
110
|
-
# IPv4 or IPv6.
|
111
|
-
#
|
112
|
-
# @return [MaxMind::GeoIP2::Model::City]
|
113
|
-
#
|
114
|
-
# @raise [ArgumentError] if used against a non-City database or if you
|
115
|
-
# attempt to look up an IPv6 address in an IPv4 only database.
|
116
|
-
#
|
117
|
-
# @raise [AddressNotFoundError] if the IP address is not found in the
|
118
|
-
# database.
|
119
|
-
#
|
120
|
-
# @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
|
121
|
-
# corrupt.
|
122
|
-
def city(ip_address)
|
123
|
-
model_for(Model::City, 'city', 'City', ip_address)
|
124
|
-
end
|
77
|
+
locales = ['en'] if locales.nil? || locales.empty?
|
125
78
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
# IPv4 or IPv6.
|
130
|
-
#
|
131
|
-
# @return [MaxMind::GeoIP2::Model::ConnectionType]
|
132
|
-
#
|
133
|
-
# @raise [ArgumentError] if used against a non-Connection Type database or if
|
134
|
-
# you attempt to look up an IPv6 address in an IPv4 only database.
|
135
|
-
#
|
136
|
-
# @raise [AddressNotFoundError] if the IP address is not found in the
|
137
|
-
# database.
|
138
|
-
#
|
139
|
-
# @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
|
140
|
-
# corrupt.
|
141
|
-
def connection_type(ip_address)
|
142
|
-
flat_model_for(
|
143
|
-
Model::ConnectionType,
|
144
|
-
'connection_type',
|
145
|
-
'GeoIP2-Connection-Type',
|
146
|
-
ip_address,
|
147
|
-
)
|
148
|
-
end
|
79
|
+
options = {}
|
80
|
+
options[:mode] = mode if !mode.nil?
|
81
|
+
@reader = MaxMind::DB.new(database, options)
|
149
82
|
|
150
|
-
|
151
|
-
#
|
152
|
-
# @param ip_address [String] a string in the standard notation. It may be
|
153
|
-
# IPv4 or IPv6.
|
154
|
-
#
|
155
|
-
# @return [MaxMind::GeoIP2::Model::Country]
|
156
|
-
#
|
157
|
-
# @raise [ArgumentError] if used against a non-Country database or if you
|
158
|
-
# attempt to look up an IPv6 address in an IPv4 only database.
|
159
|
-
#
|
160
|
-
# @raise [AddressNotFoundError] if the IP address is not found in the
|
161
|
-
# database.
|
162
|
-
#
|
163
|
-
# @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
|
164
|
-
# corrupt.
|
165
|
-
def country(ip_address)
|
166
|
-
model_for(Model::Country, 'country', 'Country', ip_address)
|
167
|
-
end
|
83
|
+
@type = @reader.metadata.database_type
|
168
84
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
#
|
174
|
-
# @return [MaxMind::GeoIP2::Model::Domain]
|
175
|
-
#
|
176
|
-
# @raise [ArgumentError] if used against a non-Domain database or if you
|
177
|
-
# attempt to look up an IPv6 address in an IPv4 only database.
|
178
|
-
#
|
179
|
-
# @raise [AddressNotFoundError] if the IP address is not found in the
|
180
|
-
# database.
|
181
|
-
#
|
182
|
-
# @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
|
183
|
-
# corrupt.
|
184
|
-
def domain(ip_address)
|
185
|
-
flat_model_for(Model::Domain, 'domain', 'GeoIP2-Domain', ip_address)
|
186
|
-
end
|
85
|
+
@locales = locales
|
86
|
+
end
|
87
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
88
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
187
89
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
90
|
+
# Look up the IP address in the database.
|
91
|
+
#
|
92
|
+
# @param ip_address [String] a string in the standard notation. It may be
|
93
|
+
# IPv4 or IPv6.
|
94
|
+
#
|
95
|
+
# @return [MaxMind::GeoIP2::Model::AnonymousIP]
|
96
|
+
#
|
97
|
+
# @raise [ArgumentError] if used against a non-Anonymous IP database or if
|
98
|
+
# you attempt to look up an IPv6 address in an IPv4 only database.
|
99
|
+
#
|
100
|
+
# @raise [AddressNotFoundError] if the IP address is not found in the
|
101
|
+
# database.
|
102
|
+
#
|
103
|
+
# @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
|
104
|
+
# corrupt.
|
105
|
+
def anonymous_ip(ip_address)
|
106
|
+
flat_model_for(
|
107
|
+
Model::AnonymousIP,
|
108
|
+
'anonymous_ip',
|
109
|
+
'GeoIP2-Anonymous-IP',
|
110
|
+
ip_address,
|
111
|
+
)
|
112
|
+
end
|
206
113
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
114
|
+
# Look up the IP address in an ASN database.
|
115
|
+
#
|
116
|
+
# @param ip_address [String] a string in the standard notation. It may be
|
117
|
+
# IPv4 or IPv6.
|
118
|
+
#
|
119
|
+
# @return [MaxMind::GeoIP2::Model::ASN]
|
120
|
+
#
|
121
|
+
# @raise [ArgumentError] if used against a non-ASN database or if you
|
122
|
+
# attempt to look up an IPv6 address in an IPv4 only database.
|
123
|
+
#
|
124
|
+
# @raise [AddressNotFoundError] if the IP address is not found in the
|
125
|
+
# database.
|
126
|
+
#
|
127
|
+
# @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
|
128
|
+
# corrupt.
|
129
|
+
def asn(ip_address)
|
130
|
+
flat_model_for(Model::ASN, 'asn', 'GeoLite2-ASN', ip_address)
|
131
|
+
end
|
225
132
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
133
|
+
# Look up the IP address in a City database.
|
134
|
+
#
|
135
|
+
# @param ip_address [String] a string in the standard notation. It may be
|
136
|
+
# IPv4 or IPv6.
|
137
|
+
#
|
138
|
+
# @return [MaxMind::GeoIP2::Model::City]
|
139
|
+
#
|
140
|
+
# @raise [ArgumentError] if used against a non-City database or if you
|
141
|
+
# attempt to look up an IPv6 address in an IPv4 only database.
|
142
|
+
#
|
143
|
+
# @raise [AddressNotFoundError] if the IP address is not found in the
|
144
|
+
# database.
|
145
|
+
#
|
146
|
+
# @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
|
147
|
+
# corrupt.
|
148
|
+
def city(ip_address)
|
149
|
+
model_for(Model::City, 'city', 'City', ip_address)
|
150
|
+
end
|
232
151
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
152
|
+
# Look up the IP address in a Connection Type database.
|
153
|
+
#
|
154
|
+
# @param ip_address [String] a string in the standard notation. It may be
|
155
|
+
# IPv4 or IPv6.
|
156
|
+
#
|
157
|
+
# @return [MaxMind::GeoIP2::Model::ConnectionType]
|
158
|
+
#
|
159
|
+
# @raise [ArgumentError] if used against a non-Connection Type database or if
|
160
|
+
# you attempt to look up an IPv6 address in an IPv4 only database.
|
161
|
+
#
|
162
|
+
# @raise [AddressNotFoundError] if the IP address is not found in the
|
163
|
+
# database.
|
164
|
+
#
|
165
|
+
# @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
|
166
|
+
# corrupt.
|
167
|
+
def connection_type(ip_address)
|
168
|
+
flat_model_for(
|
169
|
+
Model::ConnectionType,
|
170
|
+
'connection_type',
|
171
|
+
'GeoIP2-Connection-Type',
|
172
|
+
ip_address,
|
173
|
+
)
|
174
|
+
end
|
239
175
|
|
240
|
-
|
176
|
+
# Look up the IP address in a Country database.
|
177
|
+
#
|
178
|
+
# @param ip_address [String] a string in the standard notation. It may be
|
179
|
+
# IPv4 or IPv6.
|
180
|
+
#
|
181
|
+
# @return [MaxMind::GeoIP2::Model::Country]
|
182
|
+
#
|
183
|
+
# @raise [ArgumentError] if used against a non-Country database or if you
|
184
|
+
# attempt to look up an IPv6 address in an IPv4 only database.
|
185
|
+
#
|
186
|
+
# @raise [AddressNotFoundError] if the IP address is not found in the
|
187
|
+
# database.
|
188
|
+
#
|
189
|
+
# @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
|
190
|
+
# corrupt.
|
191
|
+
def country(ip_address)
|
192
|
+
model_for(Model::Country, 'country', 'Country', ip_address)
|
193
|
+
end
|
241
194
|
|
242
|
-
|
243
|
-
|
195
|
+
# Look up the IP address in a Domain database.
|
196
|
+
#
|
197
|
+
# @param ip_address [String] a string in the standard notation. It may be
|
198
|
+
# IPv4 or IPv6.
|
199
|
+
#
|
200
|
+
# @return [MaxMind::GeoIP2::Model::Domain]
|
201
|
+
#
|
202
|
+
# @raise [ArgumentError] if used against a non-Domain database or if you
|
203
|
+
# attempt to look up an IPv6 address in an IPv4 only database.
|
204
|
+
#
|
205
|
+
# @raise [AddressNotFoundError] if the IP address is not found in the
|
206
|
+
# database.
|
207
|
+
#
|
208
|
+
# @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
|
209
|
+
# corrupt.
|
210
|
+
def domain(ip_address)
|
211
|
+
flat_model_for(Model::Domain, 'domain', 'GeoIP2-Domain', ip_address)
|
212
|
+
end
|
244
213
|
|
245
|
-
|
246
|
-
|
247
|
-
|
214
|
+
# Look up the IP address in an Enterprise database.
|
215
|
+
#
|
216
|
+
# @param ip_address [String] a string in the standard notation. It may be
|
217
|
+
# IPv4 or IPv6.
|
218
|
+
#
|
219
|
+
# @return [MaxMind::GeoIP2::Model::Enterprise]
|
220
|
+
#
|
221
|
+
# @raise [ArgumentError] if used against a non-Enterprise database or if
|
222
|
+
# you attempt to look up an IPv6 address in an IPv4 only database.
|
223
|
+
#
|
224
|
+
# @raise [AddressNotFoundError] if the IP address is not found in the
|
225
|
+
# database.
|
226
|
+
#
|
227
|
+
# @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
|
228
|
+
# corrupt.
|
229
|
+
def enterprise(ip_address)
|
230
|
+
model_for(Model::Enterprise, 'enterprise', 'Enterprise', ip_address)
|
231
|
+
end
|
248
232
|
|
249
|
-
|
250
|
-
|
233
|
+
# Look up the IP address in an ISP database.
|
234
|
+
#
|
235
|
+
# @param ip_address [String] a string in the standard notation. It may be
|
236
|
+
# IPv4 or IPv6.
|
237
|
+
#
|
238
|
+
# @return [MaxMind::GeoIP2::Model::ISP]
|
239
|
+
#
|
240
|
+
# @raise [ArgumentError] if used against a non-ISP database or if you
|
241
|
+
# attempt to look up an IPv6 address in an IPv4 only database.
|
242
|
+
#
|
243
|
+
# @raise [AddressNotFoundError] if the IP address is not found in the
|
244
|
+
# database.
|
245
|
+
#
|
246
|
+
# @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
|
247
|
+
# corrupt.
|
248
|
+
def isp(ip_address)
|
249
|
+
flat_model_for(Model::ISP, 'isp', 'GeoIP2-ISP', ip_address)
|
250
|
+
end
|
251
251
|
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
252
|
+
# Return the metadata associated with the database.
|
253
|
+
#
|
254
|
+
# @return [MaxMind::DB::Metadata]
|
255
|
+
def metadata
|
256
|
+
@reader.metadata
|
256
257
|
end
|
257
258
|
|
258
|
-
|
259
|
+
# Close the Reader and return resources to the system.
|
260
|
+
#
|
261
|
+
# @return [void]
|
262
|
+
def close
|
263
|
+
@reader.close
|
264
|
+
end
|
259
265
|
|
260
|
-
|
261
|
-
|
262
|
-
|
266
|
+
private
|
267
|
+
|
268
|
+
def model_for(model_class, method, type, ip_address)
|
269
|
+
record, prefix_length = get_record(method, type, ip_address)
|
270
|
+
|
271
|
+
record['traits'] = {} if !record.key?('traits')
|
272
|
+
record['traits']['ip_address'] = ip_address
|
273
|
+
record['traits']['prefix_length'] = prefix_length
|
274
|
+
|
275
|
+
model_class.new(record, @locales)
|
263
276
|
end
|
264
277
|
|
265
|
-
|
266
|
-
|
278
|
+
def get_record(method, type, ip_address)
|
279
|
+
if !@type.include?(type)
|
280
|
+
raise ArgumentError,
|
281
|
+
"The #{method} method cannot be used with the #{@type} database."
|
282
|
+
end
|
267
283
|
|
268
|
-
|
269
|
-
record, prefix_length = get_record(method, type, ip_address)
|
284
|
+
record, prefix_length = @reader.get_with_prefix_length(ip_address)
|
270
285
|
|
271
|
-
|
272
|
-
|
286
|
+
if record.nil?
|
287
|
+
raise AddressNotFoundError,
|
288
|
+
"The address #{ip_address} is not in the database."
|
289
|
+
end
|
273
290
|
|
274
|
-
|
291
|
+
[record, prefix_length]
|
292
|
+
end
|
293
|
+
|
294
|
+
def flat_model_for(model_class, method, type, ip_address)
|
295
|
+
record, prefix_length = get_record(method, type, ip_address)
|
296
|
+
|
297
|
+
record['ip_address'] = ip_address
|
298
|
+
record['prefix_length'] = prefix_length
|
299
|
+
|
300
|
+
model_class.new(record)
|
301
|
+
end
|
275
302
|
end
|
276
303
|
end
|
277
304
|
end
|