905b9cb05eeaca7f2dcda42fc6abdb95a2d2da7f max Wed Sep 9 05:29:28 2026 -0700 no captcha for a command-line CGI run, and version the detailsScript module URL Two small fixes to things noticed while adding the scatterPlot plot type. A CGI run from the command line got the Cloudflare Turnstile challenge page instead of the output the caller asked for, which makes "./hgc db=hg38 g=x" - the quickest way to see what a CGI emits - useless without a hand-made hg.conf. There is no browser to solve a captcha in that situation. printCaptcha() now returns early when cgiWasSpoofed(). That flag cannot be set from an HTTP request: cgiFromCommandLine() returns early and leaves it FALSE whenever the web server has set REQUEST_METHOD. Checked that a plain argument-style run is now clean, that a run which fakes the web environment with QUERY_STRING still gets the captcha, and that an HTTP request behaves exactly as the unmodified binary does. The detailsScript module was loaded from a hardcoded import('../js/hgc.X.js'), bypassing webTimeStampedLinkToResource(), so it was the one script on the page with no ?v=. That is the mechanism that flushes a browser's cache when the CGI version changes and that keeps a mirror from pairing an old static file with new CGIs, and without it a cached module could be handed newer bedDetails JSON than it was written for. Now built through the helper, which also fixes the already-shipped histogram type. The helper errAborts on a missing file and the plot type comes from a hub, so a plot type with no module installed falls back to the plain path: a silent failed import as before, rather than one bad hub setting taking down the whole details page. refs #35415 diff --git src/hg/lib/cart.c src/hg/lib/cart.c index 7a6035e03ac..e6a36af1074 100644 --- src/hg/lib/cart.c +++ src/hg/lib/cart.c @@ -1687,30 +1687,38 @@ return res; } // hg.conf key with the cloud flare secret key, used twice here, so a global macro #define CLOUDFLARESITEKEY "cloudFlareSiteKey" static char *getSessionId() /* Get session id if any from CGI. */ { return cgiOptionalString("hgsid"); } void printCaptcha() /* print an html page that shows the captcha and on success, reloads the page with the token added as token=x */ { + // A CGI run from the command line has no browser to solve a captcha, so the + // challenge page would just replace the output the caller asked for. Only a + // real command-line run reaches here with wasSpoofed set: cgiFromCommandLine() + // returns early, leaving it FALSE, whenever the web server has set + // REQUEST_METHOD, so this cannot be reached from an HTTP request. + if (cgiWasSpoofed()) + return; + char *cfSiteKey = cfgVal(CLOUDFLARESITEKEY); if (!cfSiteKey) return; if (cfgOptionBooleanDefault("captchaDebug", FALSE)) fprintf(stderr, "CAPTCHA_PRINT %s\n", getSessionId()); cspWriteResponseHeader(); puts("Content-Type:text/html\n"); // puts outputs one newline. Header requires two newlines. puts(""); printf("