This repository has been archived by the owner on Jan 31, 2018. It is now read-only.
/
geoip.go
130 lines (110 loc) · 2.49 KB
/
geoip.go
1
2
3
4
5
6
7
8
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package geoip
import (
"sync"
geo "github.com/abh/geoip"
)
// GeoLookup defines functions to get properties of an IP address and Reload databases.
type GeoLookup interface {
GetRegion(string) string
GetCountry(string) string
GetCity(string) string
GetAsn(string) string
Reload() error
}
// GeoMMIP is a GeoLookup backed by MaxMind.
// Can build out a cache maybe?
type GeoMMIP struct {
geos *geo.GeoIP
asn *geo.GeoIP
geoLoc string
asnLoc string
sync.RWMutex
}
// NewGeoMMIp returns a GeoMMIP using the given geo and asn database locations.
func NewGeoMMIp(geoLoc string, asnLoc string) (*GeoMMIP, error) {
g := GeoMMIP{
geoLoc: geoLoc,
asnLoc: asnLoc,
}
err := g.Reload()
return &g, err
}
// Reload reloads the configured databases.
func (g *GeoMMIP) Reload() error {
g.Lock()
defer g.Unlock()
c, err := geo.Open(g.geoLoc)
if err != nil {
return err
}
asns, err := geo.Open(g.asnLoc)
if err != nil {
return err
}
g.geos = c
g.asn = asns
return nil
}
func (g *GeoMMIP) getGeosRecord(ip string) *geo.GeoIPRecord {
g.RLock()
defer g.RUnlock()
return g.geos.GetRecord(ip)
}
// GetRegion returns the region associated with the ip.
func (g *GeoMMIP) GetRegion(ip string) string {
loc := g.getGeosRecord(ip)
if loc == nil {
return ""
}
return loc.Region
}
// GetCountry returns the country associated with the ip.
func (g *GeoMMIP) GetCountry(ip string) string {
loc := g.getGeosRecord(ip)
if loc == nil {
return ""
}
return loc.CountryCode
}
// GetCity returns the city associated with the ip.
func (g *GeoMMIP) GetCity(ip string) string {
loc := g.getGeosRecord(ip)
if loc == nil {
return ""
}
return loc.City
}
// GetAsn returns the ASN associated with the ip.
func (g *GeoMMIP) GetAsn(ip string) string {
g.RLock()
defer g.RUnlock()
loc, _ := g.asn.GetName(ip)
return loc
}
// NoopGeoIP is a GeoLookup that always returns empty strings.
type NoopGeoIP struct{}
var nop GeoLookup = &NoopGeoIP{}
// Noop returns a GeoLookup that always returns empty strings.
func Noop() GeoLookup {
return nop
}
// GetRegion returns an empty string.
func (g *NoopGeoIP) GetRegion(ip string) string {
return ""
}
// GetCountry returns an empty string.
func (g *NoopGeoIP) GetCountry(ip string) string {
return ""
}
// GetAsn returns an empty string.
func (g *NoopGeoIP) GetAsn(ip string) string {
return ""
}
// GetCity returns an empty string.
func (g *NoopGeoIP) GetCity(ip string) string {
return ""
}
// Reload does nothing.
func (g *NoopGeoIP) Reload() error {
return nil
}