diff --git a/internal/engine/geolocate/cloudflare.go b/internal/engine/geolocate/cloudflare.go new file mode 100644 index 0000000..61664e9 --- /dev/null +++ b/internal/engine/geolocate/cloudflare.go @@ -0,0 +1,33 @@ +package geolocate + +import ( + "context" + "net/http" + "regexp" + "strings" + + "github.com/ooni/probe-cli/v3/internal/engine/httpheader" + "github.com/ooni/probe-cli/v3/internal/httpx" + "github.com/ooni/probe-cli/v3/internal/model" +) + +func cloudflareIPLookup( + ctx context.Context, + httpClient *http.Client, + logger model.Logger, + userAgent string, +) (string, error) { + data, err := (&httpx.APIClientTemplate{ + BaseURL: "https://www.cloudflare.com", + HTTPClient: httpClient, + Logger: logger, + UserAgent: httpheader.CLIUserAgent(), + }).WithBodyLogging().Build().FetchResource(ctx, "/cdn-cgi/trace") + if err != nil { + return DefaultProbeIP, err + } + r := regexp.MustCompile("(?:ip)=(.*)") + ip := strings.Trim(string(r.Find(data)), "ip=") + logger.Debugf("cloudflare: body: %s", ip) + return ip, nil +} diff --git a/internal/engine/geolocate/cloudflare_test.go b/internal/engine/geolocate/cloudflare_test.go new file mode 100644 index 0000000..a3a9ef3 --- /dev/null +++ b/internal/engine/geolocate/cloudflare_test.go @@ -0,0 +1,26 @@ +package geolocate + +import ( + "context" + "net" + "net/http" + "testing" + + "github.com/apex/log" + "github.com/ooni/probe-cli/v3/internal/engine/httpheader" +) + +func TestIPLookupWorksUsingcloudlflare(t *testing.T) { + ip, err := cloudflareIPLookup( + context.Background(), + http.DefaultClient, + log.Log, + httpheader.UserAgent(), + ) + if err != nil { + t.Fatal(err) + } + if net.ParseIP(ip) == nil { + t.Fatalf("not an IP address: '%s'", ip) + } +} diff --git a/internal/engine/geolocate/iplookup.go b/internal/engine/geolocate/iplookup.go index 4cb46f0..52438a0 100644 --- a/internal/engine/geolocate/iplookup.go +++ b/internal/engine/geolocate/iplookup.go @@ -40,6 +40,10 @@ var ( name: "avast", fn: avastIPLookup, }, + { + name: "cloudflare", + fn: cloudflareIPLookup, + }, { name: "ipconfig", fn: ipConfigIPLookup,