34b790e2381539fa6830bd2129c5089f44be4595
max
  Tue Feb 26 02:14:18 2019 -0800
making hgGeneGraph bottleneck penalty stricter, refs #22999

diff --git src/hg/pyLib/hgLib.py src/hg/pyLib/hgLib.py
index ed6d3d0..53a375e 100644
--- src/hg/pyLib/hgLib.py
+++ src/hg/pyLib/hgLib.py
@@ -39,38 +39,38 @@
 # debug level: a number. the higher, the more debug info is printed
 verboseLevel = None
 
 cgiArgs = None
 
 # like in the kent tree, we keep track of whether we have already output the content-type line
 contentLineDone = False
 
 jksqlTrace = False
 
 def warn(format, *args):
     print (format % args)
 
 def errAbort(msg):
     " show msg and abort. Like errAbort.c "
-    if not contentLineDone:
     printContentType()
     print msg
     exit(0)
 
 def debug(level, msg):
     " output debug message with a given verbosity level "
     if level >= verboseLevel:
+        printContentType()
         print(msg+"<br>")
         sys.stdout.flush()
  
 def parseConf(fname):
     " parse a hg.conf style file, return as dict key -> value (all strings) "
     conf = {}
     for line in open(fname):
         line = line.strip()
         if line.startswith("#"):
             continue
         elif line.startswith("include "):
             inclFname = line.split()[1]
             absFname = normpath(join(dirname(fname), inclFname))
             if os.path.isfile(absFname):
                 inclDict = parseConf(absFname)
@@ -320,30 +320,32 @@
 def webStartGbNoBanner(prefix, title):
     " output the <head> part, largely copied from web.c / webStartGbNoBanner "
     print (getGbHeader() % (prefix, title, getNonce(), getNonce()))
 
 def runCmd(cmd, mustRun=True):
     " wrapper around system() that prints error messages. cmd preferably a list, not just a string. "
     import subprocess
     ret = subprocess.call(cmd)
     if ret!=0 and mustRun:
         errAbort("Could not run command %s" % cmd)
     return ret
 
 def printContentType(contType="text/html", fname=None):
     " print the HTTP Content-type header line with an optional file name "
     global contentLineDone
+    if contentLineDone:
+        return
     contentLineDone = True
     print("Content-type: %s; charset=utf-8" % contType)
     if fname is not None:
         print("Content-Disposition: attachment; filename=%s" % fname)
     print
 
 def queryBottleneck(host, port, ip):
     " contact UCSC-style bottleneck server to get current delay time. From hg/lib/botDelay.c "
     # send ip address
     import socket
     s =  socket.socket()
     s.connect((host, int(port)))
     msg = ip
     d = chr(len(msg))+msg
     s.send(d)
@@ -353,44 +355,46 @@
     totalLen = 0
     buf = list()
     while True:
         resp = s.recv(1024)
         buf.append(resp)
         totalLen+= len(resp)
         if totalLen==expLen:
             break
     return int("".join(buf))
 
 def hgBotDelay():
     """
     Implement bottleneck delay, get bottleneck server from hg.conf.
     This behaves similar to the function src/hg/lib/botDelay.c:hgBotDelay
     It does not use the hgsid, currently it always uses the IP address.
-    Using the hgsid makes little sense. It is more lenient than that C version.
+    Using the hgsid makes little sense. It is more lenient than the C version.
     """
     import time
     if "DOCUMENT_ROOT" not in os.environ: # skip if not called from Apache
         return
     global hgConf
     hgConf = parseHgConf()
     if "bottleneck.host" not in hgConf:
         return
     ip = os.environ["REMOTE_ADDR"]
     delay = queryBottleneck(hgConf["bottleneck.host"], hgConf["bottleneck.port"], ip)
-    if delay>10000:
+    printContentType()
+    debug(1, "Bottleneck delay: %d msecs" % delay)
+    if delay>2000:
         time.sleep(delay/1000.0)
-    if delay>20000:
+    if delay>10000:
         errAbort("Too many queries. Your IP has been blocked. Please contact genome-www@soe.ucsc.edu to unblock your IP address.")
         sys.exit(0)
 
 def parseRa(text):
     " Parse ra-style string and return as dict name -> value "
     import string
     lines = text.split("\n")
     data = dict()
     for l in lines:
         if len(l)==0:
             continue
         key, val = string.split(l, " ", maxsplit=1)
         data[key] = val
     return data