Documentation
¶
Overview ¶
Package geolocation provides IP geolocation lookups via MaxMind GeoIP2/GeoLite2 databases.
It defines a Provider interface for pluggable backends and ships a MaxMindProvider that memory-maps a MaxMind database file for high-performance, thread-safe lookups.
Usage ¶
provider, err := geolocation.NewMaxMindProvider("/path/to/GeoLite2-City.mmdb")
if err != nil {
log.Fatal(err)
}
defer provider.Close()
loc, err := provider.Lookup(ctx, "81.2.69.142")
if err != nil {
log.Fatal(err)
}
if loc != nil {
fmt.Println(loc) // "London, England, GB"
fmt.Println(loc.Country) // "GB"
fmt.Println(loc.Timezone) // "Europe/London"
}
Private and Loopback IPs ¶
Lookups for private (RFC 1918/4193), loopback, link-local, and unspecified addresses return (nil, nil) instead of an error. This allows middleware and application code to handle local development gracefully:
loc, err := provider.Lookup(ctx, "127.0.0.1") // loc == nil, err == nil loc, err = provider.Lookup(ctx, "192.168.1.1") // loc == nil, err == nil
Error Handling ¶
The package defines sentinel errors for common failure modes:
- ErrClosed — operation on a closed provider
- ErrInvalidIP — IP string could not be parsed
Use errors.Is for checking:
if errors.Is(err, geolocation.ErrClosed) {
// provider was closed
}
Integration with clientip ¶
Combine with github.com/dmitrymomot/forge/pkg/clientip to extract the client IP from an HTTP request and geolocate it:
ip := clientip.GetIP(r) loc, err := provider.Lookup(ctx, ip)
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrClosed is returned when an operation is attempted on a closed provider. ErrClosed = errors.New("geolocation: provider is closed") // ErrInvalidIP is returned when an IP address string cannot be parsed. ErrInvalidIP = errors.New("geolocation: invalid IP address") )
Sentinel errors for geolocation operations.
Functions ¶
This section is empty.
Types ¶
type Location ¶
type Location struct {
// Country is the ISO 3166-1 alpha-2 country code (e.g., "US", "GB", "DE").
Country string
// City is the English name of the city (e.g., "London", "New York").
City string
// Region is the English name of the primary subdivision,
// typically a state or province (e.g., "California", "England").
Region string
// Timezone is the IANA timezone identifier (e.g., "America/New_York", "Europe/London").
Timezone string
}
Location represents geographic information resolved from an IP address.
type MaxMindProvider ¶
type MaxMindProvider struct {
// contains filtered or unexported fields
}
MaxMindProvider performs IP geolocation lookups using a MaxMind GeoIP2 or GeoLite2 database. It memory-maps the database file for efficient, zero-copy reads.
MaxMindProvider is safe for concurrent use. Multiple goroutines may call Lookup simultaneously.
func NewMaxMindProvider ¶
func NewMaxMindProvider(dbPath string) (*MaxMindProvider, error)
NewMaxMindProvider opens a MaxMind GeoIP2 or GeoLite2 database file and returns a provider ready for lookups.
The database file is memory-mapped for performance. The file must remain accessible on disk for the lifetime of the provider.
Call Close when the provider is no longer needed to release resources.
func (*MaxMindProvider) Close ¶
func (p *MaxMindProvider) Close() error
Close releases the memory-mapped database and marks the provider as closed. After Close returns, all subsequent Lookup calls return ErrClosed. Close is idempotent.
func (*MaxMindProvider) Lookup ¶
Lookup resolves the geographic location for the given IP address.
For private (RFC 1918/4193), loopback, link-local, and unspecified addresses, Lookup returns (nil, nil) to support graceful degradation in development and internal-network environments.
Returns ErrInvalidIP if the IP string cannot be parsed. Returns ErrClosed if Close has been called.
type Provider ¶
type Provider interface {
// Lookup resolves the geographic location of the given IP address.
// Returns (nil, nil) for private, loopback, link-local, and unspecified IPs.
// Returns ErrInvalidIP if the IP string cannot be parsed.
// Returns ErrClosed if the provider has been closed.
Lookup(ctx context.Context, ip string) (*Location, error)
// Close releases resources held by the provider.
// After Close returns, subsequent Lookup calls return ErrClosed.
Close() error
}
Provider abstracts IP geolocation lookups. Implementations must be safe for concurrent use.