f880f8b822d19c049867d38998c93a03566ba13f
hiram
  Wed Aug 12 13:26:46 2026 -0700
fixing up errors found in code review refs #37946

diff --git src/hg/hubApi/apiUtils.c src/hg/hubApi/apiUtils.c
index 9ddde8a37df..9896faba317 100644
--- src/hg/hubApi/apiUtils.c
+++ src/hg/hubApi/apiUtils.c
@@ -692,42 +692,66 @@
  * When NO trackDb, can't tell at this point, will check that later
  */
 {
 if (tdb)
     {
     if (tdbIsContainer(tdb) || tdbIsComposite(tdb)
 	|| tdbIsCompositeView(tdb) || tdbIsSuper(tdb))
 	return FALSE;
     else
 	return TRUE;
     }
 else
     return TRUE;	/* might be true */
 }
 
+static struct hash *dbExistsCache = NULL;	/* memoize sqlDatabaseExists() below,
+	 * protectedTrack() is called once per track in a listing */
+
 boolean protectedTrack(char *db, struct trackDb *tdb, char *tableName)
 /* determine if track is off-limits protected data */
 {
-// if the table is from hub, assume db should be from hub as well
+// A hub track's table name always carries the hub_<id>_ prefix, but db only
+// needs that same prefix reconstructed when db itself is an assembly hub
+// genome (accessControlInit()/trackHubDatabase() look it up by its decorated
+// name).  When db is a real, existing database -- as it is for a hub track
+// that merely overlays an existing genome, e.g. a hub track on hg19 -- db
+// must be left alone, or accessControlInit()'s hAllocConn() aborts with
+// "Unknown database".
 if (isHubTrack(tableName))
+    {
+    if (dbExistsCache == NULL)
+        dbExistsCache = hashNew(0);
+    struct hashEl *hel = hashLookup(dbExistsCache, db);
+    boolean isRealDb;
+    if (hel == NULL)
+        {
+        isRealDb = sqlDatabaseExists(db);
+        hashAdd(dbExistsCache, db, isRealDb ? intToPt(1) : intToPt(0));
+        }
+    else
+        isRealDb = ptToInt(hel->val);
+
+    if (! isRealDb)
         {
         char buffer[4096];
 
         safef(buffer, sizeof buffer, "hub_%d_%s",hubIdFromTrackName(tableName), db);
 
         db = cloneString(buffer);
         }
+    }
 
 return cartTrackDbIsAccessDenied(db, tableName) || cartTrackDbIsNoGenome(db, tableName);
 }
 
 boolean isWiggleDataTable(char *type)
 /* is this a wiggle data track table */
 {
 if (startsWith("wig", type))
     {
     if (startsWith("wigMaf", type))
 	return FALSE;
     else
 	return TRUE;
     }
 else
@@ -840,31 +864,31 @@
     init = TRUE;
     }
 return host;
 }
 
 boolean inUcscEduDomain()
 /* Return TRUE if this machine is configured as belonging to the ucsc.edu
  * domain, per hg.conf's central.domain setting (the same setting used for
  * the cross-host login cookie domain).  This is deployment config rather
  * than something derived from the machine's own OS hostname/DNS: a box's
  * local/cloud-assigned hostname and its UCSC-facing name (e.g.
  * genome-euro.ucsc.edu) can be unrelated DNS labels with no way to bridge
  * them via gethostname()/getaddrinfo(). */
 {
 char *domain = cfgOption(CFG_CENTRAL_DOMAIN);
-return (domain != NULL && strstr(domain, ".ucsc.edu") != NULL);
+return (domain != NULL && endsWith(domain, ".ucsc.edu"));
 }
 
 boolean onGenomeRRMachine()
 /* Return TRUE if running on one of the genome.ucsc.edu round-robin
  * machines (hgw0, hgw1, hgw2, ...), which carry SQL grants on
  * hgcentral.gbMembers.  Only meaningful within inUcscEduDomain(). */
 {
 if (hIsPrivateHost())	// stay on localhost for hgwdev and hgwbeta
     return TRUE;
 char *hostName = thisHostName();
 if (isEmpty(hostName))
     return FALSE;
 if (startsWith("hgwbeta", hostName))
     return TRUE;
 if (!startsWith("hgw", hostName))
@@ -986,36 +1010,44 @@
 if (sd < 0)
     {
     dyStringFree(&url);
     return "error";
     }
 char *redirectedUrl = NULL;
 if (!netSkipHttpHeaderLinesWithRedirect(sd, dyStringContents(url), &redirectedUrl))
     {
     close(sd);
     dyStringFree(&url);
     return "error";
     }
 dyStringFree(&url);
 struct dyString *body = netSlurpFile(sd);
 close(sd);
+
+char *status = "error";
+struct errCatch *errCatch = errCatchNew();
+if (errCatchStart(errCatch))
+    {
     struct jsonElement *json = jsonParse(body->string);
+    char *statusField = jsonStringField(json, "status");
+    if (isNotEmpty(statusField))
+        status = cloneString(statusField);
+    }
+errCatchEnd(errCatch);
+errCatchFree(&errCatch);
 dyStringFree(&body);
-if (json == NULL)
-    return "error";
-char *status = jsonStringField(json, "status");
-return isNotEmpty(status) ? cloneString(status) : "error";
+return status;
 }
 
 void apiSubmitOttoRequest(char *words[MAX_PATH_INFO])
 /* Internal server-to-server endpoint: record a row in the ottoRequest table
  * on behalf of a hubApi host that lacks its own hgcentral write grants (see
  * relaySubmitOttoRequest()).  Requires the shared hg.conf secret
  * 'hubApi.relaySecret' to match, since this performs the actual database
  * write without the bot-challenge cookie check that /liftRequest and
  * /assemblyRequest do locally -- that check already ran on the relaying
  * host before it got here.  Always answers 200 + a JSON "status" field;
  * never apiErrAbort()s for a duplicate/rateLimited outcome, so the relay
  * caller can distinguish it from a hard failure. */
 {
 char *secret = cfgOption("hubApi.relaySecret");
 char *givenSecret = getenv("HTTP_X_RELAY_SECRET");