Add support for geoip cache db writing

chubin/logging
Igor Chubin 2 years ago
parent a27541a25b
commit 4855adeaf6

@ -59,6 +59,9 @@ func NewCache(config *config.Config) (*Cache, error) {
return nil, err
}
// Needed for "upsert" implementation in Put()
db.UseErrorParser()
return &Cache{
config: config,
db: db,
@ -89,7 +92,7 @@ func (c *Cache) readFromCacheFile(addr string) (*Location, error) {
if err != nil {
return nil, ErrNotFound
}
return parseCacheEntry(addr, string(bytes))
return NewLocationFromString(addr, string(bytes))
}
func (c *Cache) readFromCacheDB(addr string) (*Location, error) {
@ -103,14 +106,42 @@ func (c *Cache) readFromCacheDB(addr string) (*Location, error) {
return &result, nil
}
func (c *Cache) Put(addr string, loc *Location) error {
if c.config.Geo.CacheType == types.CacheTypeDB {
return c.putToCacheDB(addr, loc)
}
return c.putToCacheFile(addr, loc)
}
func (c *Cache) putToCacheDB(addr string, loc *Location) error {
err := c.db.Insert(loc).Do()
// it should work like this:
//
// target := dberror.UniqueConstraint{}
// if errors.As(err, &target) {
//
// See: https://github.com/samonzeweb/godb/pull/23
//
// But for some reason it does not work,
// so the dirty hack is used:
if strings.Contains(fmt.Sprint(err), "UNIQUE constraint failed") {
return c.db.Update(loc).Do()
}
return err
}
func (c *Cache) putToCacheFile(addr string, loc *Location) error {
return os.WriteFile(c.cacheFile(addr), []byte(loc.String()), 0644)
}
// cacheFile retuns path to the cache entry for addr.
func (c *Cache) cacheFile(addr string) string {
return path.Join(c.config.Geo.IPCache, addr)
}
// parseCacheEntry parses the location cache entry s,
// NewLocationFromString parses the location cache entry s,
// and return location, or error, if the cache entry is invalid.
func parseCacheEntry(addr, s string) (*Location, error) {
func NewLocationFromString(addr, s string) (*Location, error) {
var (
lat float64 = -1000
long float64 = -1000
@ -172,7 +203,12 @@ func (c *Cache) Response(r *http.Request) *routing.Cadre {
return respERR
}
err := c.putRaw(ip, value)
location, err := NewLocationFromString(ip, value)
if err != nil {
return respERR
}
err = c.Put(ip, location)
if err != nil {
return respERR
}
@ -193,10 +229,6 @@ func (c *Cache) Response(r *http.Request) *routing.Cadre {
return nil
}
func (c *Cache) putRaw(addr, value string) error {
return os.WriteFile(c.cacheFile(addr), []byte(value), 0644)
}
func validIP4(ipAddress string) bool {
re, _ := regexp.Compile(`^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$`)
return re.MatchString(strings.Trim(ipAddress, " "))

@ -68,7 +68,7 @@ func TestParseCacheEntry(t *testing.T) {
}
for _, tt := range tests {
result, err := parseCacheEntry(tt.addr, tt.input)
result, err := NewLocationFromString(tt.addr, tt.input)
if tt.err == nil {
require.NoError(t, err)
require.Equal(t, *result, tt.expected)

Loading…
Cancel
Save