diff --git a/internal/publicip/info.go b/internal/publicip/info.go index f6b3d5a3..6de30a0d 100644 --- a/internal/publicip/info.go +++ b/internal/publicip/info.go @@ -12,43 +12,49 @@ import ( "github.com/qdm12/gluetun/internal/constants" ) -type ipInfoData struct { +type Result struct { Region string `json:"region"` Country string `json:"country"` City string `json:"city"` } -var ErrBadHTTPStatus = errors.New("bad HTTP status received") +var ( + ErrTooManyRequests = errors.New("too many requests sent for this month") + ErrBadHTTPStatus = errors.New("bad HTTP status received") +) func Info(ctx context.Context, client *http.Client, ip net.IP) ( //nolint:interfacer - country, region, city string, err error) { + result Result, err error) { const baseURL = "https://ipinfo.io/" url := baseURL + ip.String() request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { - return "", "", "", err + return result, err } response, err := client.Do(request) if err != nil { - return "", "", "", err + return result, err } defer response.Body.Close() - if response.StatusCode != http.StatusOK { - return "", "", "", fmt.Errorf("%w: %d", ErrBadHTTPStatus, response.StatusCode) + switch response.StatusCode { + case http.StatusOK: + case http.StatusTooManyRequests: + return result, fmt.Errorf("%w: %s", ErrTooManyRequests, baseURL) + default: + return result, fmt.Errorf("%w: %d", ErrBadHTTPStatus, response.StatusCode) } decoder := json.NewDecoder(response.Body) - var data ipInfoData - if err := decoder.Decode(&data); err != nil { - return "", "", "", err + if err := decoder.Decode(&result); err != nil { + return result, err } - countryCode := strings.ToLower(data.Country) + countryCode := strings.ToLower(result.Country) country, ok := constants.CountryCodes()[countryCode] - if !ok { - country = data.Country + if ok { + result.Country = country } - return country, data.Region, data.City, nil + return result, nil } diff --git a/internal/publicip/loop.go b/internal/publicip/loop.go index f27c5eb2..5f7e4efc 100644 --- a/internal/publicip/loop.go +++ b/internal/publicip/loop.go @@ -154,11 +154,11 @@ func (l *looper) Run(ctx context.Context, wg *sync.WaitGroup) { l.state.setPublicIP(ip) message := "Public IP address is " + ip.String() - country, region, city, err := Info(ctx, l.client, ip) + result, err := Info(ctx, l.client, ip) if err != nil { l.logger.Warn(err) } else { - message += " (" + country + ", " + region + ", " + city + ")" + message += " (" + result.Country + ", " + result.Region + ", " + result.City + ")" } l.logger.Info(message) diff --git a/internal/updater/providers/purevpn/servers.go b/internal/updater/providers/purevpn/servers.go index b5c26211..5d14971d 100644 --- a/internal/updater/providers/purevpn/servers.go +++ b/internal/updater/providers/purevpn/servers.go @@ -76,13 +76,13 @@ func GetServers(ctx context.Context, client *http.Client, // Dedup by location lts := make(locationToServer) for _, server := range servers { - country, region, city, err := publicip.Info(ctx, client, server.IPs[0]) + ipInfo, err := publicip.Info(ctx, client, server.IPs[0]) if err != nil { return nil, warnings, err } // TODO split servers by host - lts.add(country, region, city, server.IPs) + lts.add(ipInfo.Country, ipInfo.Region, ipInfo.City, server.IPs) } if len(servers) < minServers {