2197f6d5208aff4c48ccbe42e61a116d988ac392
max
  Tue May 19 08:23:54 2026 -0700
hubApi: add /blat endpoint with apiKey gating, format=hgblat, and known-agent bypass

New src/hg/hubApi/blat.c implements /blat/<type> (dna, protein, transRna,
transDna, guess) backed by the same gfServer logic as hgBlat.  Key details:

- Requires an apiKey for rate-limiting; botException() and
botExceptionUserAgent() exempt IPs/user-agents in hg.conf (same
policy as captcha bypass elsewhere in the browser stack).
- Invalid apiKey returns a clean JSON 403 rather than an HTML 500
(pre-validated in hubApi.c main() before hgBotDelayTimeFrac runs).
- Extra bot-delay fraction (default 0.3, 10x hubApi default) is
configurable via hubApi.blatDelayFraction in hg.conf.
- format=text/psl  -> PSL text; format=hgblat -> byte-for-byte
hgBlat?output=json shape; jsonOutputArrays=1 -> hubApi envelope
with arrays (parallel to getData behaviour); default -> objects.
- botExceptionUserAgent() carved out of cart.c's static
isUserAgentException() into botDelay.c so non-cart callers can use it.
- Cross-reference comments added in hgBlat.c and blat.c noting the
shared logic so fixes get applied to both.

refs #36315

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

diff --git src/hg/hubApi/dataApi.h src/hg/hubApi/dataApi.h
index 5541417f397..2a5d2b75fa8 100644
--- src/hg/hubApi/dataApi.h
+++ src/hg/hubApi/dataApi.h
@@ -87,49 +87,53 @@
 #define argLevel "level"
 #define argLiftable "liftable"
 #define argFromGenome "fromGenome"
 #define argToGenome "toGenome"
 /* used by liftRequest */
 #define argEmail "email"
 #define argComment "comment"
 /* used by assemblyRequest */
 #define argAsmId "asmId"
 #define argName "name"
 #define argBetterName "betterName"
 /* used in liftOver 'listExisting' function to filter the result */
 #define argFilter "filter"
 /* used in list/files to show only certain file types */
 #define argFileType "fileType"
+/* used by /blat */
+#define argUserSeq "userSeq"
+#define argApiKey "apiKey"
 
 /* valid argument listings to verify extraneous arguments
  *  initialized in hubApi.c
  */
 extern char *argListPublicHubs[];
 extern char *argListUcscGenomes[];
 extern char *argListGenarkGenomes[];
 extern char *argListHubGenomes[];
 extern char *argListTracks[];
 extern char *argListChromosomes[];
 extern char *argListSchema[];
 extern char *argListFiles[];
 extern char *argGetDataTrack[];
 extern char *argGetDataSequence[];
 extern char *argSearch[];
 extern char *argFindGenome[];
 extern char *argLiftOver[];
 extern char *argLiftRequest[];
 extern char *argAssemblyRequest[];
+extern char *argBlat[];
 
 /* maximum number of words expected in PATH_INFO parsing
  *   so far only using 2
  */
 #define MAX_PATH_INFO 32
 
 /* maximum amount of DNA allowed in a get sequence request */
 #define MAX_DNA_LENGTH	499999999
 /* this size is directly related to the max limit in needMem used in
  * jsonWriteString
  */
 
 /* Maximum number of comma sep tracks that can be requested by /getData/track */
 #define MAX_NUM_TRACKS 100
 
@@ -310,16 +314,23 @@
 void apiFindGenome(char *words[MAX_PATH_INFO]);
 /* 'findGenome' function */
 
 void apiAssemblyRequest(char *words[MAX_PATH_INFO]);
 /* interface to the assemblySearch.html request form, replaces /cgi-bin/asr */
 
 /* ######################################################################### */
 /*  functions in liftover.c */
 
 void apiLiftOver(char *words[MAX_PATH_INFO]);
 /* 'liftOver' function */
 
 void apiLiftRequest(char *words[MAX_PATH_INFO]);
 /* interface to the liftOver request page to send email */
 
+/* ######################################################################### */
+/*  functions in blat.c */
+
+void apiBlat(char *words[MAX_PATH_INFO]);
+/* '/blat' endpoint: run a BLAT alignment of userSeq against the requested
+ * assembly's gfServer and return PSL hits as JSON. */
+
 #endif	/*	 DATAAPH_H	*/