136481ed08005073b11b1b1f326ee7c85f4d2f58
hiram
  Tue Mar 26 13:14:56 2019 -0700
adding the botDelay functions refs #18869

diff --git src/hg/hubApi/hubApi.c src/hg/hubApi/hubApi.c
index 1956113..a280fe4 100644
--- src/hg/hubApi/hubApi.c
+++ src/hg/hubApi/hubApi.c
@@ -1,39 +1,43 @@
 /* hubApi - access mechanism to hub data resources. */
 #include "dataApi.h"
+#include "botDelay.h"
 
 /*
 +------------------+------------------+------+-----+---------+-------+
 | Field            | Type             | Null | Key | Default | Extra |
 +------------------+------------------+------+-----+---------+-------+
 | hubUrl           | longblob         | NO   | PRI | NULL    |       |
 | shortLabel       | varchar(255)     | NO   |     | NULL    |       |
 | longLabel        | varchar(255)     | NO   |     | NULL    |       |
 | registrationTime | varchar(255)     | NO   |     | NULL    |       |
 | dbCount          | int(10) unsigned | NO   |     | NULL    |       |
 | dbList           | blob             | YES  |     | NULL    |       |
 | descriptionUrl   | longblob         | YES  |     | NULL    |       |
 +------------------+------------------+------+-----+---------+-------+
 */
 
 /* Global Variables for all modules */
 
 int maxItemsOutput = 1000;	/* can be set in URL maxItemsOutput=N */
 static int maxItemLimit = 1000000;   /* maximum of 1,000,000 items returned */
+/* for debugging purpose, current bot delay value */
+int botDelay = 0;
+boolean debug = TRUE;	/* can be set in URL debug=1, to turn off: debug=0 */
+#define delayFraction	0.03
 
 /* Global only to this one source file */
-static boolean debug = TRUE;	/* can be set in URL debug=1 */
 static struct cart *cart;             /* CGI and other variables */
 static struct hash *oldVars = NULL;
 static struct hash *trackCounter = NULL;
 static long totalTracks = 0;
 static boolean measureTiming = FALSE;	/* set by CGI parameters */
 static boolean allTrackSettings = FALSE;	/* checkbox setting */
 static char **shortLabels = NULL;	/* public hub short labels in array */
 // struct hubPublic *publicHubList = NULL;
 static int publicHubCount = 0;
 static char *defaultHub = "Plants";
 static char *defaultDb = "ce11";
 static long enteredMainTime = 0;	/* will become = clock1000() on entry */
 		/* to allow calculation of when to bail out, taking too long */
 static long timeOutSeconds = 100;
 static boolean timedOut = FALSE;
@@ -1009,30 +1013,51 @@
 hPrintf("<li><a href='%s/getData/track?hubUrl=http://genome-test.gi.ucsc.edu/~hiram/hubs/Plants/hub.txt&amp;genome=_araTha1&amp;chrom=chrI&amp;track=assembly_&amp;start=0&amp;end=14309681' target=_blank>get track data from specified hub, chromosome, track name, start and end coordinates</a> <em>%s/getData/track?hubUrl=http://genome-test.gi.ucsc.edu/~hiram/hubs/Plants/hub.txt&amp;genome=_araTha1&amp;chrom=chrI&amp;track=assembly_&amp;start=0&amp;end=14309681</em></li>\n", urlPrefix, urlPrefix);
 hPrintf("</ol>\n");
 }	/*	static void showExamples()	*/
 
 #endif
 
 static void showCartDump()
 /* for information purposes only during development, will become obsolete */
 {
 hPrintf("<h4>cart dump</h4>");
 hPrintf("<pre>\n");
 cartDump(cart);
 hPrintf("</pre>\n");
 }
 
+static void sendJsonHogMessage(char *hogHost)
+{
+apiErrAbort("Your host, %s, has been sending too many requests lately and is "
+       "unfairly loading our site, impacting performance for other users. "
+       "Please contact genome@soe.ucsc.edu to ask that your site "
+       "be reenabled.  Also, please consider downloading sequence and/or "
+       "annotations in bulk -- see http://genome.ucsc.edu/downloads.html.",
+       hogHost);
+}
+
+static void sendHogMessage(char *hogHost)
+{
+hPrintf("Your host, %s, has been sending too many requests lately and is "
+       "unfairly loading our site, impacting performance for other users. "
+       "Please contact genome@soe.ucsc.edu to ask that your site "
+       "be reenabled.  Also, please consider downloading sequence and/or "
+       "annotations in bulk -- see http://genome.ucsc.edu/downloads.html.",
+       hogHost);
+exit(0);
+}
+
 static void doMiddle(struct cart *theCart)
 /* Set up globals and make web page */
 {
 cart = theCart;
 measureTiming = hPrintStatus() && isNotEmpty(cartOptionalString(cart, "measureTiming"));
 measureTiming = TRUE;
 char *database = NULL;
 char *genome = NULL;
 
 cgiVarSet("ignoreCookie", "1");
 
 getDbAndGenome(cart, &database, &genome, oldVars);
 initGenbankTableNames(database);
 initSupportedTypes();
 initUrlPrefix();
@@ -1058,63 +1083,88 @@
 boolean commandError = FALSE;
 /*expect no more than MAX_PATH_INFO number of words*/
 char *words[MAX_PATH_INFO];
 
 if (isNotEmpty(pathInfo))
     {
     setupFunctionHash();
     struct hashEl *hel = parsePathInfo(pathInfo, words);
     /* verify valid API command */
 
     if (hel)	/* have valid command */
 	{
         hPrintDisable();
 	puts("Content-Type:application/json");
 	puts("\n");
+	/* similar delay system as in DAS server */
+	botDelay = hgBotDelayTimeFrac(delayFraction);
+	if (botDelay > 0)
+	    {
+	    if (botDelay > 2000)
+		{
+		char *hogHost = getenv("REMOTE_ADDR");
+		sendJsonHogMessage(hogHost);
+		return;
+		}
+	sleep1000(botDelay);
+	}
         void (*apiFunction)(char **) = hel->val;
         (*apiFunction)(words);
 	return;
 	}
      else
 	commandError = TRUE;
     }
 
 puts("Content-Type:text/html");
 puts("\n");
 
+/* similar delay system as in DAS server */
+botDelay = hgBotDelayTimeFrac(delayFraction);
+if (botDelay > 0)
+    {
+    if (botDelay > 2000)
+	{
+	char *hogHost = getenv("REMOTE_ADDR");
+	sendHogMessage(hogHost);
+	}
+    sleep1000(botDelay);
+    }
+
 (void) hubPublicDbLoadAll();
 
 struct dbDb *dbList = ucscDbDb();
 char **ucscDbList = NULL;
 int listSize = slCount(dbList);
 AllocArray(ucscDbList, listSize);
 struct dbDb *el = dbList;
 int ucscDataBaseCount = 0;
 int maxDbNameWidth = 0;
 for ( ; el != NULL; el = el->next )
     {
     ucscDbList[ucscDataBaseCount++] = el->name;
     if (strlen(el->name) > maxDbNameWidth)
 	maxDbNameWidth = strlen(el->name);
     }
 maxDbNameWidth += 1;
 
 cartWebStart(cart, database, "UCSC JSON API interface");
 
 if (debug)
     {
     hPrintf("<ul>\n");
+    hPrintf("<li>hgBotDelay: %d</li>\n", botDelay);
     char *envVar = getenv("BROWSER_HOST");
     hPrintf("<li>BROWSER_HOST:%s</li>\n", envVar);
     envVar = getenv("CONTEXT_DOCUMENT_ROOT");
     hPrintf("<li>CONTEXT_DOCUMENT_ROOT:%s</li>\n", envVar);
     envVar = getenv("CONTEXT_PREFIX");
     hPrintf("<li>CONTEXT_PREFIX:%s</li>\n", envVar);
     envVar = getenv("DOCUMENT_ROOT");
     hPrintf("<li>DOCUMENT_ROOT:%s</li>\n", envVar);
     envVar = getenv("HTTP_HOST");
     hPrintf("<li>HTTP_HOST:%s</li>\n", envVar);
     envVar = getenv("REQUEST_URI");
     hPrintf("<li>REQUEST_URI:%s</li>\n", envVar);
     envVar = getenv("SCRIPT_FILENAME");
     hPrintf("<li>SCRIPT_FILENAME:%s</li>\n", envVar);
     envVar = getenv("SCRIPT_NAME");