e389c29f0255935bc714c66ce7182c4a24427adc braney Fri Feb 6 12:13:44 2026 -0800 fixes hubApi trackDb cache bug #37064 diff --git src/hg/hubApi/apiUtils.c src/hg/hubApi/apiUtils.c index b9cc476def1..c2cdef3dbd0 100644 --- src/hg/hubApi/apiUtils.c +++ src/hg/hubApi/apiUtils.c @@ -262,31 +262,42 @@ i++; } *nameReturn = namesReturn; *typeReturn = typesReturn; *jsonTypes = jsonReturn; return columnCount; } struct trackHub *errCatchTrackHubOpen(char *hubUrl) /* use errCatch around a trackHub open in case it fails */ { struct trackHub *hub = NULL; struct errCatch *errCatch = errCatchNew(); if (errCatchStart(errCatch)) { - hub = trackHubOpen(hubUrl, ""); + unsigned getHubId(char *url, char **errorMessage); + char *errMessage; + unsigned hubId = hubFindOrAddUrlInStatusTable(NULL, hubUrl, &errMessage); + + // if we got an error, throw error + if (errMessage != NULL) + errAbort("%s", errMessage); + + // use hubId in hubName + char buffer[4096]; + safef(buffer, sizeof buffer, "hub_%d", hubId); + hub = trackHubOpen(hubUrl, buffer); } errCatchEnd(errCatch); if (errCatch->gotError) { apiErrAbort(err404, err404Msg, "error opening hubUrl: '%s', '%s'", hubUrl, errCatch->message->string); } errCatchFree(&errCatch); return hub; } static int trackDbTrackCmp(const void *va, const void *vb) /* Compare to sort based on 'track' name; use shortLabel as secondary sort key. * Note: parallel code to hgTracks.c:tgCmpPriority */ { const struct trackDb *a = *((struct trackDb **)va); @@ -313,35 +324,35 @@ return tdb; } struct trackDb *findTrackDb(char *track, struct trackDb *tdb) /* search tdb structure for specific track, recursion on subtracks */ { struct trackDb *trackFound = NULL; for (trackFound = tdb; trackFound; trackFound = trackFound->next) { if (trackFound->subtracks) { struct trackDb *subTrack = findTrackDb(track, trackFound->subtracks); if (subTrack) { - if (sameOk(subTrack->track, track)) + if (sameOk(trackHubSkipHubName(subTrack->track), track)) trackFound = subTrack; } } - if (sameOk(trackFound->track, track)) + if (sameOk(trackHubSkipHubName(trackFound->track), track)) break; } return trackFound; } boolean allowedBigBedType(char *type) /* return TRUE if the big* bed-like type is to be supported * add to this list as the big* bed-like supported types are expanded */ { if (startsWithWord("bigBarChart", type) || startsWithWord("bigBed", type) || startsWithWord("bigGenePred", type) || startsWithWord("bigInteract", type) || @@ -383,31 +394,31 @@ { const struct chromInfo *a = *((struct chromInfo **)va); const struct chromInfo *b = *((struct chromInfo **)vb); int dif; dif = (long) a->size - (long) b->size; return dif; } struct trackHubGenome *findHubGenome(struct trackHub *hub, char *genome, char *endpoint, char *hubUrl) /* given open 'hub', find the specified 'genome' called from 'endpoint' */ { struct trackHubGenome *hubGenome = NULL; for (hubGenome = hub->genomeList; hubGenome; hubGenome = hubGenome->next) { - if (sameString(genome, hubGenome->name)) + if (sameString(genome, trackHubSkipHubName(hubGenome->name))) break; } if (NULL == hubGenome) apiErrAbort(err400, err400Msg, "failed to find specified genome=%s for endpoint '%s' given hubUrl '%s'", genome, endpoint, hubUrl); return hubGenome; } char *verifyLegalArgs(char *validArgList[]) /* validArgList is an array of strings for valid arguments * returning string of any other arguments not on that list found in * cgiVarList(), NULL when none found. */ { struct hash *validHash = NULL; char *words[32]; @@ -651,30 +662,40 @@ if (tdb) { if (tdbIsContainer(tdb) || tdbIsComposite(tdb) || tdbIsCompositeView(tdb) || tdbIsSuper(tdb)) return FALSE; else return TRUE; } else return TRUE; /* might be true */ } 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 +if (isHubTrack(tableName)) + { + 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 return FALSE;