ed2944f615eb64c06c10b868754a60926a04a412 max Tue Sep 15 05:47:46 2026 -0700 Four leftovers from the Content-Type sweep, refs #38353 edwWebAuthLogin and edwWebAuthLogout still printed a blank line of their own after cgiPrintContentType(), which already ends the header block, so every response began with an empty line in the body. hgPhyloPlace built its own Content-Type line from a macro in five places. hgChooseDb's fail() sent a Status line and no Content-Type at all, so a bad request came back with a body apache had no type for. diff --git src/hg/hgPhyloPlace/hgPhyloPlace.c src/hg/hgPhyloPlace/hgPhyloPlace.c index b794175da20..ed2cb874ef7 100644 --- src/hg/hgPhyloPlace/hgPhyloPlace.c +++ src/hg/hgPhyloPlace/hgPhyloPlace.c @@ -583,31 +583,36 @@ struct dyString *dySalted = dyStringCreate("%s-%s", salt, plainMd5); char *rightSalty = md5HexForString(dySalted->string); boolean ok = sameOk(salty, rightSalty); dyStringFree(&dySalted); return ok; } INLINE void maybeComment(char *comment) /* If comment is nonempty, append it to stderr. Then print a newline regardless of comment. */ { if (isNotEmpty(comment)) fprintf(stderr, ": %s", comment); fputc('\n', stderr); } -#define CONTENT_TYPE "Content-Type: text/plain\n\n" +INLINE void plainTextHeader() +/* Close the http header block with a text/plain Content-Type. Only the first call in the + * process writes anything, which is what the callers below want: they each end the request. */ +{ +cgiPrintContentType("text/plain"); +} static void sendServerCommand(char *org) /* If a recognized server command is requested (with minimal auth to prevent DoS), and usher server * is configured, then send the command to the usher server's manager fifo. */ { pushWarnHandler(htmlVaBadRequestAbort); pushAbortHandler(htmlVaBadRequestAbort); char *plain = cgiOptionalString(serverPlainVar); char *salty = cgiOptionalString(serverSaltyVar); if (isNotEmpty(plain) && isNotEmpty(salty) && serverAuthOk(plain, salty)) { if (serverIsConfigured(org)) { char *command = cgiString(serverCommandVar); char *comment = cgiOptionalString(serverCommentVar); @@ -630,78 +635,83 @@ { if (serverUp) errAbort("Server is already running for org %s, see %s", org, tnCheckServer.forCgi); struct tempName tnServerStartup; trashDirFile(&tnServerStartup, "ct", "usher_server_startup", ".txt"); errFile = mustOpen(tnServerStartup.forCgi, "w"); fprintf(stderr, "Usher server start for %s", org); maybeComment(comment); boolean success = startServer(org, treeChoices, errFile); carefulClose(&errFile); if (success) { fprintf(stderr, "Spawned usher server background process, details in %s", tnServerStartup.forCgi); - printf(CONTENT_TYPE"Started server for %s\n", org); + plainTextHeader(); + printf("Started server for %s\n", org); } else errAbort("Unable to spawn usher server background process, details in %s", tnServerStartup.forCgi); } else errAbort("No treeChoices for org=%s", org); } else if (serverUp) { if (sameString(command, "reload")) { struct treeChoices *treeChoices = loadTreeChoices(org, org); fprintf(stderr, "Usher server reload for %s", org); maybeComment(comment); serverReloadProtobufs(org, treeChoices); - printf(CONTENT_TYPE"Sent reload command for %s\n", org); + plainTextHeader(); + printf("Sent reload command for %s\n", org); } else if (sameString(command, "stop")) { fprintf(stderr, "Usher server stop for %s", org); maybeComment(comment); serverStop(org); - printf(CONTENT_TYPE"Sent stop command for %s\n", org); + plainTextHeader(); + printf("Sent stop command for %s\n", org); } else { char commandCopy[16]; safecpy(commandCopy, sizeof commandCopy, command); char *words[3]; int wordCount = chopLine(commandCopy, words); int val; if (wordCount == 2 && (val = atol(words[1])) > 0) { if (sameString(words[0], "thread")) { fprintf(stderr, "Usher server thread count set to %d", val); maybeComment(comment); serverSetThreadCount(org, val); - printf(CONTENT_TYPE"Sent thread %d command for %s\n", val, org); + plainTextHeader(); + printf("Sent thread %d command for %s\n", val, org); } else if (sameString(words[0], "timeout")) { fprintf(stderr, "Usher server timeout set to %d", val); maybeComment(comment); serverSetTimeout(org, val); - printf(CONTENT_TYPE"Sent timeout %d command for %s\n", val, org); + plainTextHeader(); + printf("Sent timeout %d command for %s\n", val, org); } else errAbort("Unrecognized command '%s'", command); } else errAbort("Unrecognized command '%s'", command); } } else errAbort("Server for %s is down (see %s), cannot send command '%s'", org, tnCheckServer.forCgi, command); } else errAbort("Usher server mode not configured for org=%s", org); }