summaryrefslogtreecommitdiff
path: root/vendor/github.com/oschwald/geoip2-golang/reader.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/oschwald/geoip2-golang/reader.go')
-rw-r--r--vendor/github.com/oschwald/geoip2-golang/reader.go327
1 files changed, 327 insertions, 0 deletions
diff --git a/vendor/github.com/oschwald/geoip2-golang/reader.go b/vendor/github.com/oschwald/geoip2-golang/reader.go
new file mode 100644
index 0000000..ac5108f
--- /dev/null
+++ b/vendor/github.com/oschwald/geoip2-golang/reader.go
@@ -0,0 +1,327 @@
+// Package geoip2 provides an easy-to-use API for the MaxMind GeoIP2 and
+// GeoLite2 databases; this package does not support GeoIP Legacy databases.
+//
+// The structs provided by this package match the internal structure of
+// the data in the MaxMind databases.
+//
+// See github.com/oschwald/maxminddb-golang for more advanced used cases.
+package geoip2
+
+import (
+ "fmt"
+ "net"
+
+ "github.com/oschwald/maxminddb-golang"
+)
+
+// The City struct corresponds to the data in the GeoIP2/GeoLite2 City
+// databases.
+type City struct {
+ City struct {
+ GeoNameID uint `maxminddb:"geoname_id"`
+ Names map[string]string `maxminddb:"names"`
+ } `maxminddb:"city"`
+ Continent struct {
+ Code string `maxminddb:"code"`
+ GeoNameID uint `maxminddb:"geoname_id"`
+ Names map[string]string `maxminddb:"names"`
+ } `maxminddb:"continent"`
+ Country struct {
+ GeoNameID uint `maxminddb:"geoname_id"`
+ IsInEuropeanUnion bool `maxminddb:"is_in_european_union"`
+ IsoCode string `maxminddb:"iso_code"`
+ Names map[string]string `maxminddb:"names"`
+ } `maxminddb:"country"`
+ Location struct {
+ AccuracyRadius uint16 `maxminddb:"accuracy_radius"`
+ Latitude float64 `maxminddb:"latitude"`
+ Longitude float64 `maxminddb:"longitude"`
+ MetroCode uint `maxminddb:"metro_code"`
+ TimeZone string `maxminddb:"time_zone"`
+ } `maxminddb:"location"`
+ Postal struct {
+ Code string `maxminddb:"code"`
+ } `maxminddb:"postal"`
+ RegisteredCountry struct {
+ GeoNameID uint `maxminddb:"geoname_id"`
+ IsInEuropeanUnion bool `maxminddb:"is_in_european_union"`
+ IsoCode string `maxminddb:"iso_code"`
+ Names map[string]string `maxminddb:"names"`
+ } `maxminddb:"registered_country"`
+ RepresentedCountry struct {
+ GeoNameID uint `maxminddb:"geoname_id"`
+ IsInEuropeanUnion bool `maxminddb:"is_in_european_union"`
+ IsoCode string `maxminddb:"iso_code"`
+ Names map[string]string `maxminddb:"names"`
+ Type string `maxminddb:"type"`
+ } `maxminddb:"represented_country"`
+ Subdivisions []struct {
+ GeoNameID uint `maxminddb:"geoname_id"`
+ IsoCode string `maxminddb:"iso_code"`
+ Names map[string]string `maxminddb:"names"`
+ } `maxminddb:"subdivisions"`
+ Traits struct {
+ IsAnonymousProxy bool `maxminddb:"is_anonymous_proxy"`
+ IsSatelliteProvider bool `maxminddb:"is_satellite_provider"`
+ } `maxminddb:"traits"`
+}
+
+// The Country struct corresponds to the data in the GeoIP2/GeoLite2
+// Country databases.
+type Country struct {
+ Continent struct {
+ Code string `maxminddb:"code"`
+ GeoNameID uint `maxminddb:"geoname_id"`
+ Names map[string]string `maxminddb:"names"`
+ } `maxminddb:"continent"`
+ Country struct {
+ GeoNameID uint `maxminddb:"geoname_id"`
+ IsInEuropeanUnion bool `maxminddb:"is_in_european_union"`
+ IsoCode string `maxminddb:"iso_code"`
+ Names map[string]string `maxminddb:"names"`
+ } `maxminddb:"country"`
+ RegisteredCountry struct {
+ GeoNameID uint `maxminddb:"geoname_id"`
+ IsInEuropeanUnion bool `maxminddb:"is_in_european_union"`
+ IsoCode string `maxminddb:"iso_code"`
+ Names map[string]string `maxminddb:"names"`
+ } `maxminddb:"registered_country"`
+ RepresentedCountry struct {
+ GeoNameID uint `maxminddb:"geoname_id"`
+ IsInEuropeanUnion bool `maxminddb:"is_in_european_union"`
+ IsoCode string `maxminddb:"iso_code"`
+ Names map[string]string `maxminddb:"names"`
+ Type string `maxminddb:"type"`
+ } `maxminddb:"represented_country"`
+ Traits struct {
+ IsAnonymousProxy bool `maxminddb:"is_anonymous_proxy"`
+ IsSatelliteProvider bool `maxminddb:"is_satellite_provider"`
+ } `maxminddb:"traits"`
+}
+
+// The AnonymousIP struct corresponds to the data in the GeoIP2
+// Anonymous IP database.
+type AnonymousIP struct {
+ IsAnonymous bool `maxminddb:"is_anonymous"`
+ IsAnonymousVPN bool `maxminddb:"is_anonymous_vpn"`
+ IsHostingProvider bool `maxminddb:"is_hosting_provider"`
+ IsPublicProxy bool `maxminddb:"is_public_proxy"`
+ IsTorExitNode bool `maxminddb:"is_tor_exit_node"`
+}
+
+// The ASN struct corresponds to the data in the GeoLite2 ASN database.
+type ASN struct {
+ AutonomousSystemNumber uint `maxminddb:"autonomous_system_number"`
+ AutonomousSystemOrganization string `maxminddb:"autonomous_system_organization"`
+}
+
+// The ConnectionType struct corresponds to the data in the GeoIP2
+// Connection-Type database.
+type ConnectionType struct {
+ ConnectionType string `maxminddb:"connection_type"`
+}
+
+// The Domain struct corresponds to the data in the GeoIP2 Domain database.
+type Domain struct {
+ Domain string `maxminddb:"domain"`
+}
+
+// The ISP struct corresponds to the data in the GeoIP2 ISP database.
+type ISP struct {
+ AutonomousSystemNumber uint `maxminddb:"autonomous_system_number"`
+ AutonomousSystemOrganization string `maxminddb:"autonomous_system_organization"`
+ ISP string `maxminddb:"isp"`
+ Organization string `maxminddb:"organization"`
+}
+
+type databaseType int
+
+const (
+ isAnonymousIP = 1 << iota
+ isASN
+ isCity
+ isConnectionType
+ isCountry
+ isDomain
+ isEnterprise
+ isISP
+)
+
+// Reader holds the maxminddb.Reader struct. It can be created using the
+// Open and FromBytes functions.
+type Reader struct {
+ mmdbReader *maxminddb.Reader
+ databaseType databaseType
+}
+
+// InvalidMethodError is returned when a lookup method is called on a
+// database that it does not support. For instance, calling the ISP method
+// on a City database.
+type InvalidMethodError struct {
+ Method string
+ DatabaseType string
+}
+
+func (e InvalidMethodError) Error() string {
+ return fmt.Sprintf(`geoip2: the %s method does not support the %s database`,
+ e.Method, e.DatabaseType)
+}
+
+// UnknownDatabaseTypeError is returned when an unknown database type is
+// opened.
+type UnknownDatabaseTypeError struct {
+ DatabaseType string
+}
+
+func (e UnknownDatabaseTypeError) Error() string {
+ return fmt.Sprintf(`geoip2: reader does not support the "%s" database type`,
+ e.DatabaseType)
+}
+
+// Open takes a string path to a file and returns a Reader struct or an error.
+// The database file is opened using a memory map. Use the Close method on the
+// Reader object to return the resources to the system.
+func Open(file string) (*Reader, error) {
+ reader, err := maxminddb.Open(file)
+ if err != nil {
+ return nil, err
+ }
+ dbType, err := getDBType(reader)
+ return &Reader{reader, dbType}, err
+}
+
+// FromBytes takes a byte slice corresponding to a GeoIP2/GeoLite2 database
+// file and returns a Reader struct or an error. Note that the byte slice is
+// use directly; any modification of it after opening the database will result
+// in errors while reading from the database.
+func FromBytes(bytes []byte) (*Reader, error) {
+ reader, err := maxminddb.FromBytes(bytes)
+ if err != nil {
+ return nil, err
+ }
+ dbType, err := getDBType(reader)
+ return &Reader{reader, dbType}, err
+}
+
+func getDBType(reader *maxminddb.Reader) (databaseType, error) {
+ switch reader.Metadata.DatabaseType {
+ case "GeoIP2-Anonymous-IP":
+ return isAnonymousIP, nil
+ case "GeoLite2-ASN":
+ return isASN, nil
+ // We allow City lookups on Country for back compat
+ case "GeoLite2-City",
+ "GeoIP2-City",
+ "GeoIP2-City-Africa",
+ "GeoIP2-City-Asia-Pacific",
+ "GeoIP2-City-Europe",
+ "GeoIP2-City-North-America",
+ "GeoIP2-City-South-America",
+ "GeoIP2-Precision-City",
+ "GeoLite2-Country",
+ "GeoIP2-Country":
+ return isCity | isCountry, nil
+ case "GeoIP2-Connection-Type":
+ return isConnectionType, nil
+ case "GeoIP2-Domain":
+ return isDomain, nil
+ case "GeoIP2-Enterprise":
+ return isEnterprise | isCity | isCountry, nil
+ case "GeoIP2-ISP", "GeoIP2-Precision-ISP":
+ return isISP, nil
+ default:
+ return 0, UnknownDatabaseTypeError{reader.Metadata.DatabaseType}
+ }
+}
+
+// City takes an IP address as a net.IP struct and returns a City struct
+// and/or an error. Although this can be used with other databases, this
+// method generally should be used with the GeoIP2 or GeoLite2 City databases.
+func (r *Reader) City(ipAddress net.IP) (*City, error) {
+ if isCity&r.databaseType == 0 {
+ return nil, InvalidMethodError{"City", r.Metadata().DatabaseType}
+ }
+ var city City
+ err := r.mmdbReader.Lookup(ipAddress, &city)
+ return &city, err
+}
+
+// Country takes an IP address as a net.IP struct and returns a Country struct
+// and/or an error. Although this can be used with other databases, this
+// method generally should be used with the GeoIP2 or GeoLite2 Country
+// databases.
+func (r *Reader) Country(ipAddress net.IP) (*Country, error) {
+ if isCountry&r.databaseType == 0 {
+ return nil, InvalidMethodError{"Country", r.Metadata().DatabaseType}
+ }
+ var country Country
+ err := r.mmdbReader.Lookup(ipAddress, &country)
+ return &country, err
+}
+
+// AnonymousIP takes an IP address as a net.IP struct and returns a
+// AnonymousIP struct and/or an error.
+func (r *Reader) AnonymousIP(ipAddress net.IP) (*AnonymousIP, error) {
+ if isAnonymousIP&r.databaseType == 0 {
+ return nil, InvalidMethodError{"AnonymousIP", r.Metadata().DatabaseType}
+ }
+ var anonIP AnonymousIP
+ err := r.mmdbReader.Lookup(ipAddress, &anonIP)
+ return &anonIP, err
+}
+
+// ASN takes an IP address as a net.IP struct and returns a ASN struct and/or
+// an error
+func (r *Reader) ASN(ipAddress net.IP) (*ASN, error) {
+ if isASN&r.databaseType == 0 {
+ return nil, InvalidMethodError{"ASN", r.Metadata().DatabaseType}
+ }
+ var val ASN
+ err := r.mmdbReader.Lookup(ipAddress, &val)
+ return &val, err
+}
+
+// ConnectionType takes an IP address as a net.IP struct and returns a
+// ConnectionType struct and/or an error
+func (r *Reader) ConnectionType(ipAddress net.IP) (*ConnectionType, error) {
+ if isConnectionType&r.databaseType == 0 {
+ return nil, InvalidMethodError{"ConnectionType", r.Metadata().DatabaseType}
+ }
+ var val ConnectionType
+ err := r.mmdbReader.Lookup(ipAddress, &val)
+ return &val, err
+}
+
+// Domain takes an IP address as a net.IP struct and returns a
+// Domain struct and/or an error
+func (r *Reader) Domain(ipAddress net.IP) (*Domain, error) {
+ if isDomain&r.databaseType == 0 {
+ return nil, InvalidMethodError{"Domain", r.Metadata().DatabaseType}
+ }
+ var val Domain
+ err := r.mmdbReader.Lookup(ipAddress, &val)
+ return &val, err
+}
+
+// ISP takes an IP address as a net.IP struct and returns a ISP struct and/or
+// an error
+func (r *Reader) ISP(ipAddress net.IP) (*ISP, error) {
+ if isISP&r.databaseType == 0 {
+ return nil, InvalidMethodError{"ISP", r.Metadata().DatabaseType}
+ }
+ var val ISP
+ err := r.mmdbReader.Lookup(ipAddress, &val)
+ return &val, err
+}
+
+// Metadata takes no arguments and returns a struct containing metadata about
+// the MaxMind database in use by the Reader.
+func (r *Reader) Metadata() maxminddb.Metadata {
+ return r.mmdbReader.Metadata
+}
+
+// Close unmaps the database file from virtual memory and returns the
+// resources to the system.
+func (r *Reader) Close() error {
+ return r.mmdbReader.Close()
+}