getPublicIP attempts to retrieve the public IP address from a list of external services. It iterates through the ipServices and returns the first successful response. Returns: - string: The public IP address as a string - error: An error if all services fail, nil otherwise
()
| 29 | // - string: The public IP address as a string |
| 30 | // - error: An error if all services fail, nil otherwise |
| 31 | func getPublicIP() (string, error) { |
| 32 | for _, service := range ipServices { |
| 33 | ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) |
| 34 | defer cancel() |
| 35 | req, err := http.NewRequestWithContext(ctx, "GET", service, nil) |
| 36 | if err != nil { |
| 37 | log.Debugf("Failed to create request to %s: %v", service, err) |
| 38 | continue |
| 39 | } |
| 40 | |
| 41 | resp, err := http.DefaultClient.Do(req) |
| 42 | if err != nil { |
| 43 | log.Debugf("Failed to get public IP from %s: %v", service, err) |
| 44 | continue |
| 45 | } |
| 46 | defer func() { |
| 47 | if closeErr := resp.Body.Close(); closeErr != nil { |
| 48 | log.Warnf("Failed to close response body from %s: %v", service, closeErr) |
| 49 | } |
| 50 | }() |
| 51 | |
| 52 | if resp.StatusCode != http.StatusOK { |
| 53 | log.Debugf("bad status code from %s: %d", service, resp.StatusCode) |
| 54 | continue |
| 55 | } |
| 56 | |
| 57 | ip, err := io.ReadAll(resp.Body) |
| 58 | if err != nil { |
| 59 | log.Debugf("Failed to read response body from %s: %v", service, err) |
| 60 | continue |
| 61 | } |
| 62 | return strings.TrimSpace(string(ip)), nil |
| 63 | } |
| 64 | return "", fmt.Errorf("all IP services failed") |
| 65 | } |
| 66 | |
| 67 | // getOutboundIP retrieves the preferred outbound IP address of this machine. |
| 68 | // It uses a UDP connection to a public DNS server to determine the local IP |
no test coverage detected