From e594f2503cad54053c3173e7696b37a64ffcf4d7 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Mon, 20 Apr 2026 17:13:41 -0600 Subject: [PATCH] refactor(geoip): cache tarballs as _LATEST.tar.gz Adds geoip.TarGzName(edition) as the single source of truth for the cache filename. The _LATEST suffix signals that the file is whatever MaxMind served most recently (versus the dated Content-Disposition name) and keeps httpcache's ETag sidecar tied to a stable path across releases. --- cmd/check-ip/main.go | 4 ++-- net/geoip/cmd/geoip-update/main.go | 2 +- net/geoip/databases.go | 6 +++--- net/geoip/geoip.go | 8 ++++++++ net/geoip/geoip_integration_test.go | 4 ++-- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/cmd/check-ip/main.go b/cmd/check-ip/main.go index 8e57410..7adf74a 100644 --- a/cmd/check-ip/main.go +++ b/cmd/check-ip/main.go @@ -155,13 +155,13 @@ func main() { geoSet := dataset.NewSet( &httpcache.Cacher{ URL: geoip.DownloadBase + "/GeoLite2-City/download?suffix=tar.gz", - Path: filepath.Join(maxmindDir, "GeoLite2-City.tar.gz"), + Path: filepath.Join(maxmindDir, geoip.TarGzName(geoip.CityEdition)), MaxAge: 3 * 24 * time.Hour, Header: authHeader, }, &httpcache.Cacher{ URL: geoip.DownloadBase + "/GeoLite2-ASN/download?suffix=tar.gz", - Path: filepath.Join(maxmindDir, "GeoLite2-ASN.tar.gz"), + Path: filepath.Join(maxmindDir, geoip.TarGzName(geoip.ASNEdition)), MaxAge: 3 * 24 * time.Hour, Header: authHeader, }, diff --git a/net/geoip/cmd/geoip-update/main.go b/net/geoip/cmd/geoip-update/main.go index f848160..79e4451 100644 --- a/net/geoip/cmd/geoip-update/main.go +++ b/net/geoip/cmd/geoip-update/main.go @@ -51,7 +51,7 @@ func main() { exitCode := 0 for _, edition := range cfg.EditionIDs { - path := filepath.Join(outDir, edition+".tar.gz") + path := filepath.Join(outDir, geoip.TarGzName(edition)) cacher := &httpcache.Cacher{ URL: geoip.DownloadBase + "/" + edition + "/download?suffix=tar.gz", Path: path, diff --git a/net/geoip/databases.go b/net/geoip/databases.go index fac14ee..7a918a3 100644 --- a/net/geoip/databases.go +++ b/net/geoip/databases.go @@ -20,15 +20,15 @@ type Databases struct { ASN *geoip2.Reader } -// Open reads /GeoLite2-City.tar.gz and /GeoLite2-ASN.tar.gz, +// Open reads /_LATEST.tar.gz for City and ASN editions, // extracts the .mmdb entry from each archive in memory, and returns open // readers. No .mmdb files are written to disk. func Open(dir string) (*Databases, error) { - city, err := openMMDBTarGz(filepath.Join(dir, "GeoLite2-City.tar.gz")) + city, err := openMMDBTarGz(filepath.Join(dir, TarGzName(CityEdition))) if err != nil { return nil, fmt.Errorf("city: %w", err) } - asn, err := openMMDBTarGz(filepath.Join(dir, "GeoLite2-ASN.tar.gz")) + asn, err := openMMDBTarGz(filepath.Join(dir, TarGzName(ASNEdition))) if err != nil { _ = city.Close() return nil, fmt.Errorf("asn: %w", err) diff --git a/net/geoip/geoip.go b/net/geoip/geoip.go index 8756edb..fe8df2e 100644 --- a/net/geoip/geoip.go +++ b/net/geoip/geoip.go @@ -15,6 +15,14 @@ const ( DownloadBase = "https://download.maxmind.com/geoip/databases" ) +// TarGzName returns the cache filename for edition's tar.gz archive. +// MaxMind's Content-Disposition names include a release date +// (e.g. GeoLite2-ASN_20260101.tar.gz); we use _LATEST so httpcache's +// ETag sidecar stays tied to a stable path across releases. +func TarGzName(edition string) string { + return edition + "_LATEST.tar.gz" +} + // DefaultConfPaths returns the standard locations where GeoIP.conf is looked // up: ./GeoIP.conf, then ~/.config/maxmind/GeoIP.conf. func DefaultConfPaths() []string { diff --git a/net/geoip/geoip_integration_test.go b/net/geoip/geoip_integration_test.go index ff155c0..55a9893 100644 --- a/net/geoip/geoip_integration_test.go +++ b/net/geoip/geoip_integration_test.go @@ -64,7 +64,7 @@ func TestDownload_CityAndASN(t *testing.T) { td := testdataDir(t) for _, edition := range []string{geoip.CityEdition, geoip.ASNEdition} { - path := filepath.Join(td, edition+".tar.gz") + path := filepath.Join(td, geoip.TarGzName(edition)) os.Remove(path) os.Remove(path + ".meta") @@ -96,7 +96,7 @@ func TestDownload_ConditionalGet_FreshCacher(t *testing.T) { td := testdataDir(t) for _, edition := range []string{geoip.CityEdition, geoip.ASNEdition} { - path := filepath.Join(td, edition+".tar.gz") + path := filepath.Join(td, geoip.TarGzName(edition)) if _, err := newCacher(cfg, edition, path).Fetch(); err != nil { t.Fatalf("%s initial Fetch: %v", edition, err)