671f8e4fac56f9dcd5497c1e45e7cda89d98cceb chmalee Wed Apr 19 14:45:03 2023 -0700 Adding an asynchronous logging function for the javascript diff --git src/hg/lib/cart.c src/hg/lib/cart.c index f3f295a..2c19627 100644 --- src/hg/lib/cart.c +++ src/hg/lib/cart.c @@ -21,30 +21,31 @@ #include "trashDir.h" #ifndef GBROWSE #include "customFactory.h" #include "googleAnalytics.h" #include "wikiLink.h" #endif /* GBROWSE */ #include "hgMaf.h" #include "hui.h" #include "geoMirror.h" #include "hubConnect.h" #include "trackHub.h" #include "cgiApoptosis.h" #include "customComposite.h" #include "regexHelper.h" #include "windowsToAscii.h" +#include "jsonWrite.h" static char *sessionVar = "hgsid"; /* Name of cgi variable session is stored in. */ static char *positionCgiName = "position"; DbConnector cartDefaultConnector = hConnectCart; DbDisconnect cartDefaultDisconnector = hDisconnectCart; static boolean cartDidContentType = FALSE; struct slPair *httpHeaders = NULL; // A list of headers to output before the content-type static void hashUpdateDynamicVal(struct hash *hash, char *name, void *val) /* Val is a dynamically allocated (freeMem-able) entity to put * in hash. Override existing hash item with that name if any. * Otherwise make new hash item. */ { @@ -2340,30 +2341,43 @@ char *redirect = cgiOptionalString("redirect"); if (redirect) { printf("Set-Cookie: redirect=%s; path=/; domain=%s; expires=%s\r\n", redirect, cgiServerName(), cookieDate()); } } /* Validate login cookies if login is enabled */ if (loginSystemEnabled()) { struct slName *newCookies = loginValidateCookies(cart), *sl; for (sl = newCookies; sl != NULL; sl = sl->next) printf("Set-Cookie: %s\r\n", sl->name); } } +static void cartJsonStart() +/* Write the necessary headers for Apache */ +{ +puts("Content-Type: application/json\n"); +} + +static void cartJsonEnd(struct jsonWrite *jw) +/* Write the final string which may have nothing in it */ +{ +if (jw) + puts(jw->dy->string); +} + struct cart *cartForSession(char *cookieName, char **exclude, struct hash *oldVars) /* This gets the cart without writing any HTTP lines at all to stdout. */ { /* Most cgis call this routine */ if (sameOk(cfgOption("signalsHandler"), "on")) /* most cgis call this routine */ initSigHandlers(hDumpStackEnabled()); /* HTTPS SSL Cert Checking Settings */ char *httpsCertCheck = cfgOption("httpsCertCheck"); if (httpsCertCheck) setenv("https_cert_check", httpsCertCheck, TRUE); char *httpsCertCheckVerbose = cfgOption("httpsCertCheckVerbose"); if (httpsCertCheckVerbose) setenv("https_cert_check_verbose", httpsCertCheckVerbose, TRUE); @@ -2394,30 +2408,41 @@ setenv("log_proxy", logProxy, TRUE); /* noSqlInj settings so they are accessible in src/lib too */ char *noSqlInj_level = cfgOption("noSqlInj.level"); if (noSqlInj_level) setenv("noSqlInj_level", noSqlInj_level, TRUE); char *noSqlInj_dumpStack = cfgOption("noSqlInj.dumpStack"); if (noSqlInj_dumpStack) setenv("noSqlInj_dumpStack", noSqlInj_dumpStack, TRUE); // if ignoreCookie is on the URL, don't check for cookies char *hguid = NULL; if ( cgiOptionalString("ignoreCookie") == NULL ) hguid = getCookieId(cookieName); + +// if _dumpToLog is on the URL, we can exit early with whatever +// message we are trying to write to the stderr/error_log +char *logMsg = NULL; +if ( (logMsg = cgiOptionalString("_dumpToLog")) != NULL) + { + cartJsonStart(); + fprintf(stderr, "%s", cgiEncode(logMsg)); + cartJsonEnd(NULL); + exit(0); + } char *hgsid = getSessionId(); struct cart *cart = cartNew(hguid, hgsid, exclude, oldVars); cartExclude(cart, sessionVar); // activate optional debuging output for CGIs verboseCgi(cartCgiUsualString(cart, "verbose", NULL)); return cart; } static void addHttpHeaders() /* CGIs can initialize the global variable httpHeaders to control their own HTTP * headers. This allows, for example, to prevent web browser caching of hgTracks * responses, but implicitly allow web browser caching everywhere else */ {