543c9ee045ba1832faaa9b75c6dc1e369dffce5a max Thu Sep 10 05:21:42 2026 -0700 Login and Sign out come back to a page that was reached by POST, refs #38192 Clicking a track name in the list below the browser image submits the hgTracks form to hgTrackUi, so the request is a POST even though the track name sits in the URL. The return URL builder threw the query string away for anything that was not a GET, which left a returnto of hgTrackUi?hgsid= alone, and hgTrackUi cannot draw a page from that because the track name is deliberately not kept in the cart. Login and Sign out therefore ended in an error instead of coming back. The query string of a POST lives in the form's action URL, which is the address the browser is showing, so returning to it is no different from the visitor pressing reload. Only the form body is left behind, and the cart already holds what mattered from it. hgTracks stays the exception: its query string can hold a one-shot zoom or drag. Also, hgTrackUi now says which parameter is missing when it is reached without a track name, rather than failing on a bare hash lookup, and hgCollection's own "you must be logged in" link brings the visitor back to hgCollection instead of the sessions page. diff --git src/hg/hgTrackUi/hgTrackUi.c src/hg/hgTrackUi/hgTrackUi.c index 7c2f3306e9e..c87a7ebbee7 100644 --- src/hg/hgTrackUi/hgTrackUi.c +++ src/hg/hgTrackUi/hgTrackUi.c @@ -4580,31 +4580,38 @@ char *track; struct customTrack *ct = NULL, *ctList = NULL; char *ignored; /* used to have hgBotDelayFrac(0.25) here, replaced with earlyBotCheck() * at the beginning of main() to output message here if in delay time * 2021-06-21 - Hiram */ if (issueBotWarning) { char *ip = getenv("REMOTE_ADDR"); botDelayMessage(ip, botDelayMillis); } cart = theCart; -track = cartString(cart, "g"); +/* The track name is not kept in the cart, so it has to come with the request. Without it + * there is no page to draw, and saying so beats the bare hash lookup failure that a + * hand-edited or truncated URL used to produce. */ +track = cartOptionalString(cart, "g"); +if (isEmpty(track)) + errAbort("This page needs to know which track to show, and the address it was reached by " + "does not name one. Open a track's settings from the browser, or add the track " + "name to the address with the g parameter, e.g. hgTrackUi?db=hg38&g=knownGene"); getDbAndGenome(cart, &database, &ignored, NULL); initGenbankTableNames(database); chromosome = cartUsualString(cart, "c", hDefaultChrom(database)); trackHash = trackHashMakeWithComposites(database,chromosome,&tdbList,FALSE); /* Handle dup of track related stuff */ char *dupeName = handleDupOp(track, trackHash); if (dupeName != NULL) track = dupeName; struct dupTrack *dupList = dupTrackListFromCart(cart); char *dupWholeName = NULL; boolean isDup = isDupTrack(track); if (isDup) { dupWholeName = track;