ee89e6768015d512b5ca8db8a62e8a129dfd5c7f
braney
  Sun Aug 23 15:56:57 2026 -0700
hgSession, cartReset: send the content policy header on their own pages

Both CGIs write their own http header block, so neither reaches addHttpHeaders
in cart.c, the hook that carries the policy header.  hgSession lets each output
path write its own Content-Type, and cartReset gets its header from
htmShellWithHead.

Add the call ahead of each html Content-Type: the two main page functions in
hgSession.c, three more in backup.c, and the one in cartReset.  The json paths
and the tar download are left alone, since they print no html.

With the hg.conf option off this changes nothing.  With it on, both pages now
carry the header, and its nonce matches the one in the meta tag and on the
inline script tags.

diff --git src/hg/hgSession/hgSession.c src/hg/hgSession/hgSession.c
index e1230acd091..c63fcc0bd8e 100644
--- src/hg/hgSession/hgSession.c
+++ src/hg/hgSession/hgSession.c
@@ -728,30 +728,31 @@
        "please see the <A HREF=\"../goldenPath/help/sessions.html\" "
        "TARGET=_BLANK>Session Gallery</A>.</LI>\n",
        dyUrl->string);
 printf("</UL>\n");
 dyStringFree(&dyUrl);
 }
 
 void doMainPage(char *userName, char *message)
 /* Login status/links and session controls. */
 {
 if (sessionNewPageActive())
     {
     doMainPageNew(userName, message);
     return;
     }
+cspWriteResponseHeader();
 puts("Content-Type:text/html\n");
 if (loginSystemEnabled() || wikiLinkEnabled())
     {
     if (userName)
 	welcomeUser(userName);
     else
 	offerLogin();
     if (isNotEmpty(message))
 	{
 	if (cartVarExists(cart, hgsDoSessionDetail))
 	    webNewSection("Session Details");
 	else
 	    webNewSection("Updated Session");
 	puts(message);
 	}
@@ -2236,30 +2237,31 @@
             freez(&dateOnly);
             freez(&sessionName);
             }
         sqlFreeResult(&sr);
         }
     hDisconnectCentral(&conn);
     }
 jsonWriteListEnd(jw);   // sessions
 }
 
 void doMainPageNew(char *userName, char *message)
 /* Render the experimental client-rendered Sessions page: framework header (gold "My Sessions"
  * band), the experimental banner, an empty #sessionApp container, and the hgSessionData JSON that
  * hgSession.js reads to build the UI. */
 {
+cspWriteResponseHeader();
 puts("Content-Type:text/html\n");
 cartWebStart(cart, NULL, "My Sessions");
 jsInit();
 jsIncludeDataTablesLibs();
 webIncludeResourceFile("gbModern.css");
 webIncludeResourceFile("hgSession.css");
 jsIncludeFile("hgSession.js", NULL);
 
 printSessionNewPageBanner(TRUE);
 if (isNotEmpty(message))
     printf("<div class='gbBanner'>%s</div>\n", message);
 
 printf("<div id='sessionApp' class='gbApp'></div>\n");
 
 struct jsonWrite *jw = jsonWriteNew();