c91277b19fd78ae350bc9dc6953b56033784fed1
max
  Mon Jun 2 04:59:21 2025 -0700
bottleneck exception for captcha refs #35824, #35790

diff --git src/hg/lib/cart.c src/hg/lib/cart.c
index 471adae1e1e..0a2fa267f89 100644
--- src/hg/lib/cart.c
+++ src/hg/lib/cart.c
@@ -1543,34 +1543,39 @@
     puts("<h4>The Genome Browser is protecting itself from bots. This will just take a few seconds.</h4>");
     puts("<small>If you are a bot and were made for a research project, please contact us by email.</small>");
     puts("<script src='https://challenges.cloudflare.com/turnstile/v0/api.js?onload=showWidget' async defer></script>");
     puts("<div id='myWidget'></div>");
     puts("</body></html>");
     sqlCleanupAll(); // we are wondering about hanging connections, so just in case, close them.
     exit(0);
 }
 
 void forceUserIdOrCaptcha(struct cart* cart, char *userId, boolean userIdFound, boolean fromCommandLine)
 /* print captcha is user did not sent a valid hguid cookie or a valid cloudflare token. Always allow rtracklayer. */
 {
 if (fromCommandLine || !cfgOption(CLOUDFLARESITEKEY))
     return;
 
+// no captcha for our own QA scripts running on a server with our IP address
+if (botException())
+    return;
+
+// let rtracklayer user agent pass, but allow us to remove this exception in case the bots discover it one day
 if (!cfgOption("blockRtracklayer") && sameOk(cgiUserAgent(), "rtracklayer"))
     return;
 
-// so QA can add a user agent after release, in case someone complains
+// QA can add a user agent after release, in case someone complains that their library is blocked
 char *okUserAgent = cfgOption("okUserAgent");
 if (okUserAgent && sameOk(cgiUserAgent(), okUserAgent))
     return;
 
 if (userId && userIdFound)
     return;
 
 char *token = cgiOptionalString("token");
 
 if (token && isValidToken(token))
 {
     cartRemove(cart, "token");
     return;
 }