@@ -28,9 +28,9 @@ const parallelism = 10
2828
2929func main () {
3030 log := slog .New (slog .NewTextHandler (os .Stdout , nil ))
31- googleCIDRs , err := helper .FetchGooglebotIPs (log , http .DefaultClient , "https://developers.google.com/static/search/apis/ipranges/googlebot.json" )
31+ googleCIDRs , err := helper .FetchGoogleCrawlerIPs (log , http .DefaultClient , helper . GoogleCrawlerIPRangeURLs )
3232 if err != nil {
33- slog .Error ("unable to fetch google bot ips" , "err" , err )
33+ slog .Error ("unable to fetch google crawler ips" , "err" , err )
3434 os .Exit (1 )
3535 }
3636
@@ -56,18 +56,18 @@ func main() {
5656 runCommand ("docker" , "compose" , "up" , "-d" )
5757 waitForService ("http://localhost" )
5858 waitForService ("http://localhost/app2" )
59+ waitForGoogleExemptionReady (googleCIDRs )
5960
6061 fmt .Printf ("Making sure %d attempt(s) pass\n " , rateLimit )
6162 runParallelChecks (ips , rateLimit , "http://localhost" )
62-
63- time .Sleep (cp .StateSaveInterval + cp .StateSaveJitter + (1 * time .Second ))
64- runCommand ("jq" , "." , "tmp/state.json" )
63+ statePath := "./tmp/state.json"
64+ runCommand ("jq" , "." , statePath )
6565
6666 fmt .Printf ("Making sure attempt #%d causes a redirect to the challenge page\n " , rateLimit + 1 )
6767 ensureRedirect (ips , "http://localhost" )
6868
6969 fmt .Println ("\n Testing state sharing between nginx instances..." )
70- time .Sleep (cp .StateSaveInterval + cp .StateSaveJitter + (1 * time .Second ))
70+ time .Sleep (cp .StateSaveInterval + cp .StateSaveJitter + (5 * time .Second ))
7171
7272 testStateSharing (ips )
7373 testGoogleBotGetsThrough (googleCIDRs )
@@ -81,7 +81,7 @@ func main() {
8181 time .Sleep (10 * time .Second )
8282 checkStateReload ()
8383
84- runCommand ("rm" , "tmp/state.json" )
84+ runCommand ("rm" , "-f" , statePath )
8585
8686}
8787
@@ -147,7 +147,7 @@ func runParallelChecks(ips []string, rateLimit int, url string) {
147147 var wg sync.WaitGroup
148148 sem := make (chan struct {}, parallelism )
149149
150- for i := 0 ; i < rateLimit ; i ++ {
150+ for range rateLimit {
151151 for _ , ip := range ips {
152152 wg .Add (1 )
153153 sem <- struct {}{}
@@ -305,7 +305,7 @@ func checkStateReload() {
305305 os .Exit (1 )
306306 }
307307
308- if len (botsMap ) != numIPs {
308+ if len (botsMap ) < numIPs {
309309 slog .Error ("Unexpected number of bots" , "expected" , numIPs , "received" , len (botsMap ))
310310 os .Exit (1 )
311311 }
@@ -400,7 +400,7 @@ func testGoogleBotGetsThrough(googleCIDRs []string) {
400400
401401 // Prime the rate limiter for the GoogleBot IP with parameters
402402 fmt .Printf ("Priming rate limiter for GoogleBot IP %s with params (%d requests)\n " , googleIP , rateLimit )
403- for i := 0 ; i < rateLimit ; i ++ {
403+ for i := range rateLimit {
404404 output = httpRequest (googleIP , "http://localhost/?foo=bar" ) // Assign value
405405 if output != "" {
406406 slog .Error (fmt .Sprintf ("GoogleBot with params was challenged prematurely on request #%d" , i + 1 ), "ip" , googleIP , "output" , output )
@@ -421,3 +421,45 @@ func testGoogleBotGetsThrough(googleCIDRs []string) {
421421 // set things back to normal for other tests
422422 runCommand ("docker" , "compose" , "down" )
423423}
424+
425+ func waitForGoogleExemptionReady (googleCIDRs []string ) {
426+ googleIP , err := firstUsableIPv4FromCIDRs (googleCIDRs )
427+ if err != nil {
428+ slog .Warn ("Unable to select Google IP for readiness check; skipping warmup" , "err" , err )
429+ return
430+ }
431+
432+ deadline := time .Now ().Add (90 * time .Second )
433+ for time .Now ().Before (deadline ) {
434+ ready := true
435+ for i := 0 ; i < rateLimit + 1 ; i ++ {
436+ if output := httpRequest (googleIP , "http://localhost" ); output != "" {
437+ ready = false
438+ break
439+ }
440+ }
441+ if ready {
442+ fmt .Printf ("Google exemption is active for %s\n " , googleIP )
443+ return
444+ }
445+ time .Sleep (500 * time .Millisecond )
446+ }
447+
448+ slog .Error ("Timed out waiting for Google crawler IP exemption to become active" , "googleIP" , googleIP )
449+ os .Exit (1 )
450+ }
451+
452+ func firstUsableIPv4FromCIDRs (cidrs []string ) (string , error ) {
453+ for _ , cidr := range cidrs {
454+ ip , err := getIPFromCIDR (cidr )
455+ if err != nil {
456+ continue
457+ }
458+ parsed := net .ParseIP (ip )
459+ if parsed != nil && parsed .To4 () != nil {
460+ return ip , nil
461+ }
462+ }
463+
464+ return "" , fmt .Errorf ("no usable IPv4 found in CIDR list" )
465+ }
0 commit comments