195190baa73b0e574a4f6041fa65baf0b09318ef hiram Fri Apr 19 12:47:16 2019 -0700 adding error checking up front for API data functions and better sample data URLs refs #18869 diff --git src/hg/hubApi/hubApi.c src/hg/hubApi/hubApi.c index 1dfd95b..5f7d454 100644 --- src/hg/hubApi/hubApi.c +++ src/hg/hubApi/hubApi.c @@ -227,54 +227,54 @@ if (hub) genome = hub->genomeList->name; struct dyString *extraDyFlags = newDyString(128); if (debug) dyStringAppend(extraDyFlags, ";debug=1"); if (jsonOutputArrays) dyStringAppend(extraDyFlags, ";jsonOutputArrays=1"); char *extraFlags = dyStringCannibalize(&extraDyFlags); if (db) { if (hub) { char urlReference[2048]; - safef(urlReference, sizeof(urlReference), " (sample data)%s\n", urlPrefix, hub->url, genome, tdb->track, chrom, start, end, extraFlags, errorPrint); + safef(urlReference, sizeof(urlReference), " (sample data)%s\n", urlPrefix, hub->url, genome, tdb->track, extraFlags, errorPrint); if (tdb->parent) hPrintf("
  • %s: %s subtrack of parent: %s%s
  • \n", tdb->track, tdb->type, tdb->parent->track, urlReference); else hPrintf("
  • %s: %s%s
  • \n", tdb->track, tdb->type, urlReference); } else { char urlReference[2048]; - safef(urlReference, sizeof(urlReference), " (sample data)%s\n", urlPrefix, db, chrom, tdb->track, start, end, extraFlags, errorPrint); + safef(urlReference, sizeof(urlReference), " (sample data)%s\n", urlPrefix, db, tdb->track, extraFlags, errorPrint); if (superChild) hPrintf("
  • %s: %s superTrack child of parent: %s%s
  • \n", tdb->track, tdb->type, tdb->parent->track, urlReference); else if (tdb->parent) hPrintf("
  • %s: %s subtrack of parent: %s%s
  • \n", tdb->track, tdb->type, tdb->parent->track, urlReference); else hPrintf("
  • %s: %s%s
  • \n", tdb->track, tdb->type, urlReference ); } } else if (hub) { char urlReference[2048]; - safef(urlReference, sizeof(urlReference), " (sample data)%s\n", urlPrefix, hub->url, genome, tdb->track, chrom, start, end, extraFlags, errorPrint); + safef(urlReference, sizeof(urlReference), " (sample data)%s\n", urlPrefix, hub->url, genome, tdb->track, extraFlags, errorPrint); if (tdb->parent) hPrintf("
  • %s: %s subtrack of parent: %s%s
  • \n", tdb->track, tdb->type, tdb->parent->track, urlReference); else hPrintf("
  • %s: %s%s
  • \n", tdb->track, tdb->type, urlReference); } else hPrintf("
  • %s : %s not db hub track ?
  • \n", tdb->track, tdb->type); } static void hubSampleUrl(struct trackHub *hub, struct trackDb *tdb, long chromCount, long itemCount, char *chromName, unsigned chromSize, char *genome, char *errorString) { unsigned start = chromSize / 4; @@ -301,31 +301,31 @@ char countsMessage[512]; countsMessage[0] = 0; if (chromCount > 0 || itemCount > 0) { if (allowedBigBedType(tdb->type)) safef(countsMessage, sizeof(countsMessage), " : %ld chroms : %ld item count ", chromCount, itemCount); else if (startsWithWord("bigWig", tdb->type)) safef(countsMessage, sizeof(countsMessage), " : %ld chroms : %ld bases covered ", chromCount, itemCount); else safef(countsMessage, sizeof(countsMessage), " : %ld chroms : %ld count ", chromCount, itemCount); } if (isSupportedType(tdb->type)) { char urlReference[2048]; - safef(urlReference, sizeof(urlReference), "(sample data)%s\n", urlPrefix, hub->url, genome, tdb->track, chromName, start, end, extraFlags, errorPrint); + safef(urlReference, sizeof(urlReference), "(sample data)%s\n", urlPrefix, hub->url, genome, tdb->track, extraFlags, errorPrint); if (allowedBigBedType(tdb->type)) hPrintf("
  • %s: %s%s%s
  • \n", tdb->track, tdb->type, countsMessage, urlReference); else if (startsWithWord("bigWig", tdb->type)) hPrintf("
  • %s: %s%s%s
  • \n", tdb->track, tdb->type, countsMessage, urlReference); else hPrintf("
  • %s: %s%s%s
  • \n", tdb->track, tdb->type, countsMessage, urlReference); } else { if (allowedBigBedType(tdb->type)) hPrintf("
  • %s: %s%s
  • \n", tdb->track, tdb->type, countsMessage); else if (startsWithWord("bigWig", tdb->type)) hPrintf("
  • %s: %s%s
  • \n", tdb->track, tdb->type, countsMessage); else @@ -1277,43 +1277,94 @@ if (udcCacheTimeout() < timeout) udcSetCacheTimeout(timeout); knetUdcInstall(); char *pathInfo = getenv("PATH_INFO"); /* nothing on incoming path, then display the WEB page instead */ if (sameOk("/",pathInfo)) pathInfo = NULL; boolean commandError = FALSE; /*expect no more than MAX_PATH_INFO number of words*/ char *words[MAX_PATH_INFO]; if (isNotEmpty(pathInfo)) { + /* can immediately verify valid parameters right here right now */ + char *start = cgiOptionalString("start"); + char *end = cgiOptionalString("end"); + char *db = cgiOptionalString("db"); + struct dyString *errorMsg = newDyString(128); + + if (isNotEmpty(db)) + { + struct sqlConnection *conn = hAllocConnMaybe(db); + if (NULL == conn) + dyStringPrintf(errorMsg, "can not find database db='%s'", db); + else + hFreeConn(&conn); + } + if (isNotEmpty(start) || isNotEmpty(end)) + { + long long llStart = -1; + long long llEnd = -1; + struct errCatch *errCatch = errCatchNew(); + if (errCatchStart(errCatch)) + { + if (isNotEmpty(start)) + llStart = sqlLongLong(start); + if (isNotEmpty(end)) + llEnd = sqlLongLong(end); + } + errCatchEnd(errCatch); + if (errCatch->gotError) + { + if (isNotEmpty(errorMsg->string)) + dyStringPrintf(errorMsg, ", "); + dyStringPrintf(errorMsg, "%s", errCatch->message->string); + if (isNotEmpty(start) && (-1 == llStart)) + dyStringPrintf(errorMsg, ", can not recognize start coordinate: '%s'", start); + if (isNotEmpty(end) && (-1 == llEnd)) + dyStringPrintf(errorMsg, ", can not recognize end coordinate: '%s'", end); + } + else + { + if ( (llStart < 0) || (llEnd < 0) || (llEnd <= llStart) ) + { + if (isNotEmpty(errorMsg->string)) + dyStringPrintf(errorMsg, ", "); + dyStringPrintf(errorMsg, "illegal start,end coordinates given: %s,%s, 'end' must be greater than 'start', and start greater than or equal to zero", start, end); + } + } + errCatchFree(&errCatch); + } + + if (isNotEmpty(errorMsg->string)) + apiErrAbort(err400, err400Msg, "%s", errorMsg->string); + setupFunctionHash(); struct hashEl *hel = parsePathInfo(pathInfo, words); /* verify valid API command */ - if (hel) /* have valid command */ { hPrintDisable(); void (*apiFunction)(char **) = hel->val; (*apiFunction)(words); return; } else - commandError = TRUE; + apiErrAbort(err400, err400Msg, "no such command: '/%s/%s for endpoint '%s'", words[0], words[1], pathInfo); } (void) hubPublicDbLoadAll(); webStartJWest(cart, database, "UCSC JSON API interface"); // webStartGbNoBanner(cart, database, "UCSC JSON API interface"); // webStartGbOptionalBanner(cart, database, "UCSC JSON API interface", TRUE, FALSE); hPrintf("
    \n"); /* these style mentions need to go into custom css file */ hPrintf("
    \n"); if (debug) { hPrintf("