ipify

ipify provides a small client to resolve the current instance public IP address using the ipify service (https://www.ipify.org/).

Part of nurago, a collection of independent Go packages for backend services.

import "github.com/tecnickcom/nurago/pkg/ipify"

Package ipify provides a small client to resolve the current instance public IP address using the ipify service (https://www.ipify.org/).

The Client API:

  • New creates a configurable ipify client.
  • Client.GetPublicIP performs the request and returns the resolved IP.
  • Client.HealthCheck probes endpoint reachability for parity with the other nurago HTTP clients.

The default configuration uses:

Use WithURL, WithTimeout, WithHTTPClient, and WithErrorIP to adapt the client to custom endpoints, transport stacks, and fallback policies. A non-positive timeout is clamped to the default; an API URL that is missing, unparseable, or not http/https with a host is rejected by New.

Error Fallback Behavior

When request creation, transport, status-code validation, or body reading fails, Client.GetPublicIP returns the configured error-IP value together with the error. By default the fallback string is empty, but it can be set (for example to “0.0.0.0”) via WithErrorIP. The response body is whitespace-trimmed and an empty body is treated as a failure.

Errors

Configuration problems are reported at construction time with errors matching the exported sentinel ErrInvalidOptions. A nil or empty response body from the endpoint surfaces as ErrInvalidResponse. Match the sentinels with errors.Is.

IPv6 Note

The default endpoint resolves standard ipify behavior. To force IPv6-capable resolution, point the client to https://api64.ipify.org via WithURL.

When To Use

  • A service needs to know its own egress address, for allow-listing or for logging.
  • You want a fallback value rather than an error when the lookup fails.

Example

// A stand-in for https://api.ipify.org, which returns the caller
// address as plain text. Real code omits WithURL and uses the default.
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
	_, _ = w.Write([]byte("192.0.2.1"))
}))

defer srv.Close()

client, err := ipify.New(
	ipify.WithURL(srv.URL),
	ipify.WithTimeout(2*time.Second),
	ipify.WithErrorIP("0.0.0.0"), // returned instead of an empty string on failure
)
if err != nil {
	fmt.Println(err)

	return
}

ip, err := client.GetPublicIP(context.TODO())

fmt.Println(ip, err)

// Output:
// 192.0.2.1 <nil>

Full source is in example_ipify_test.go. More runnable examples are on pkg.go.dev.

Dependencies

This package reaches no external module: it uses only the Go standard library.