b9790c43b9e50be9b2b1d5f97ad760c5442ae8a9
galt
  Sun May 12 02:07:18 2019 -0700
Adding 400, 401, 403, 404 http response errors. Helps browser and htmlCheck know that there is a problem.

diff --git src/hg/cirm/cdw/cdwGetFile/cdwGetFile.c src/hg/cirm/cdw/cdwGetFile/cdwGetFile.c
index 6fa94bd..b360cc1 100644
--- src/hg/cirm/cdw/cdwGetFile/cdwGetFile.c
+++ src/hg/cirm/cdw/cdwGetFile/cdwGetFile.c
@@ -15,55 +15,72 @@
 #include "cdw.h"
 #include "hdb.h"
 #include "hui.h"
 #include "cdw.h"
 #include "cdwValid.h"
 #include "web.h"
 #include "cdwLib.h"
 #include "wikiLink.h"
 #include "filePath.h"
 
 /* Global vars */
 struct cart *cart;	// User variables saved from click to click
 struct hash *oldVars;	// Previous cart, before current round of CGI vars folded in
 struct cdwUser *user;	// Our logged in user if any
 
-void errExit(char *msg, char *field) 
+void errExitExt(char *msg, char *field, char *status) 
 /* print http header + message and exit. msg can contain %s */
 {
+if (status)
+    {
+    printf("Status: %s\n", status);
+    }
+else
+    {
+    // provide a generic error code when status not specified
+    // this will signal an error to the caller.
+    printf("Status: %s\n", "400 BAD REQUEST");  
+    }
+
 printf("Content-Type: text/html\n\n");
 puts("ERROR: ");
 if (!field)
     puts(msg);
 else
     printf(msg, field);
 exit(0);
 }
 
+void errExit(char *msg, char *field) 
+/* print http header + message and exit. msg can contain %s */
+{
+errExitExt(msg, field, NULL);
+}
+
 void mustHaveAccess(struct sqlConnection *conn, struct cdwFile *ef)
 /* exit with error message if user does not have access to file ef */
 {
 boolean isPublic = cfgOptionBooleanDefault("cdw.siteIsPublic", FALSE);
 if (isPublic)
     return;
 if (cdwCheckAccess(conn, ef, user, cdwAccessRead))
     return;
 else
     if (user==NULL)
-        errExit("Sorry, this file has access restrictions. Please <a href='/cgi-bin/hgLogin'>log in</a> first.", NULL);
+        errExitExt("Sorry, this file has access restrictions. Please <a href='/cgi-bin/hgLogin'>log in</a> first.", NULL, "401 Unauthorized");
     else
-        errExit("Sorry, user %s does not have access to this file.", user->email);
+        errExitExt("Sorry, user %s does not have access to this file.", user->email, "403 Forbidden");
 }
 
 struct patcher 
 /* deal with patching replacement bits in html */
     {
     struct patcher *next;
     char *match; // string to match
     int size;   // string size
     int count;   // match count
     char *(*cdwLocalFunction)(struct cart *cart, boolean makeAbsolute);  // function to make
     };
 
 static void printFileReplaceVar(char *filePath) 
 /* dump a text file to stdout with the html header, replace <!--menuBar--> with the menubar */
 {
@@ -214,31 +231,31 @@
 sendFile(vf->format, filePath, suggestName);
 }
 
 void sendFileByPath(struct sqlConnection *conn, char *path) 
 /* send file identified by a submission pathname (cdwFile.submitFileName),
  * suggests the original filename. */
 /* path can be a suffix that matches a filename, so the initial '/hive' or
  * '/data' can be omitted. *
  * Example URL for testing:
  * http://hgwdev.soe.ucsc.edu/cgi-bin/cdwGetFile/hive/groups/cirm/pilot/labs/quake/130625_M00361_0080_000000000-A43D1/Sample_1_L13_C31_IL3541-701-506/1_L13_C31_IL3541-701-506_TAAGGCGA-ACTGCATA_L001_R1_001.fastq.gz */
 {
 int fileId = cdwFileIdFromPathSuffix(conn, path);
 
 
 if (fileId == 0)
-    errExit("A file with suffix %s does not exist in the database", path);
+    errExitExt("A file with suffix %s does not exist in the database", path, "404 Not Found");
     
 char *localPath = cdwPathForFileId(conn, fileId);
 
 if (localPath == NULL)
     errExit("A local file with suffix %s was not found in the database. This is an internal error.", path);
 
 struct cdwFile *ef = cdwFileFromId(conn, fileId);
 
 if (ef == NULL)
     errExit("Could not find cdwFile for path %s", path);
 
 mustHaveAccess(conn, ef);
 sendFile(NULL, localPath, basename(ef->submitFileName));
 }