3b7af84b7d8ebe9d30811103accd61584add9d9a
galt
  Sun Mar 19 22:24:29 2017 -0700
Initial check-in of proxy stuff. Added support for https_proxy for configuring https proxy. Added no_proxy for configuring domain suffixes which should be excluded from proxying. src/product/README.proxy updated. There are probably some documentation pages that will still need updating.

diff --git src/lib/net.c src/lib/net.c
index 1a37d50..0acfb05 100644
--- src/lib/net.c
+++ src/lib/net.c
@@ -1050,91 +1050,114 @@
     /* make a pipe (fds go in pipefd[0] and pipefd[1])  */
     if (pipe(params->pipefd) != 0)
 	errAbort("netGetOpenFtpSockets: failed to create pipe: %s", strerror(errno));
     int rc;
     rc = pthread_create(&params->thread, NULL, sendFtpDataToPipeThread, (void *)params);
     if (rc)
 	{
 	errAbort("Unexpected error %d from pthread_create(): %s",rc,strerror(rc));
 	}
 
     return params->pipefd[0];
     }
 }
 
 
-int connectNpu(struct netParsedUrl npu, char *url)
+int connectNpu(struct netParsedUrl npu, char *url, boolean noProxy)
 /* Connect using NetParsedUrl. */
 {
 int sd = -1;
 if (sameString(npu.protocol, "http"))
     {
     sd = netConnect(npu.host, atoi(npu.port));
     }
 else if (sameString(npu.protocol, "https"))
     {
-    sd = netConnectHttps(npu.host, atoi(npu.port));
+    sd = netConnectHttps(npu.host, atoi(npu.port), noProxy);
     }
 else
     {
     errAbort("netHttpConnect: url (%s) is not for http.", url);
     return -1;  /* never gets here, fixes compiler complaint */
     }
 return sd;
 }
 
 void setAuthorization(struct netParsedUrl npu, char *authHeader, struct dyString *dy)
 /* Set the specified authorization header with BASIC auth base64-encoded user and password */
 {
 if (!sameString(npu.user,""))
     {
     char up[256];
     char *b64up = NULL;
     safef(up, sizeof(up), "%s:%s", npu.user, npu.password);
     b64up = base64Encode(up, strlen(up));
     dyStringPrintf(dy, "%s: Basic %s\r\n", authHeader, b64up);
     freez(&b64up);
     }
 }
 
+boolean checkNoProxy(char *host)
+/* See if host endsWith element on no_proxy list. Elements are comma-separated. */
+{
+char *list = cloneString(getenv("no_proxy"));
+if (!list)
+    return FALSE;
+replaceChar(list, ',', ' ');
+char *word;
+while((word=nextWord(&list)))
+    {
+    if (endsWith(host, word))
+	return TRUE;
+    }
+return FALSE;
+}
+
 int netHttpConnect(char *url, char *method, char *protocol, char *agent, char *optionalHeader)
 /* Parse URL, connect to associated server on port, and send most of
  * the request to the server.  If specified in the url send user name
  * and password too.  Typically the "method" will be "GET" or "POST"
  * and the agent will be the name of your program or
  * library. optionalHeader may be NULL or contain additional header
  * lines such as cookie info. 
  * Proxy support via hg.conf httpProxy or env var http_proxy
  * Return data socket, or -1 if error.*/
 {
 struct netParsedUrl npu;
 struct netParsedUrl pxy;
 struct dyString *dy = newDyString(512);
 int sd = -1;
 /* Parse the URL and connect. */
 netParseUrl(url, &npu);
 
+boolean noProxy = checkNoProxy(npu.host);
 char *proxyUrl = getenv("http_proxy");
-
+if (sameString(npu.protocol, "https"))
+    proxyUrl = NULL;
+if (noProxy)
+    proxyUrl = NULL;
 if (proxyUrl)
     {
     netParseUrl(proxyUrl, &pxy);
-    sd = connectNpu(pxy, url);
+    if (!sameString(pxy.protocol, "http"))
+	errAbort("Unknown proxy protocol %s in %s.", pxy.protocol, proxyUrl);
+    sd = connectNpu(pxy, url, noProxy);
+    verbose(2, "%s via proxy %s\n", url, proxyUrl);
     }
 else
     {
-    sd = connectNpu(npu, url);
+    sd = connectNpu(npu, url, noProxy);
     }
 if (sd < 0)
     return -1;
 
 /* Ask remote server for a file. */
 char *urlForProxy = NULL;
 if (proxyUrl)
     {
     /* trim off the byterange part at the end of url because proxy does not understand it. */
     urlForProxy = cloneString(url);
     char *x = strrchr(urlForProxy, ';');
     if (x && startsWith(";byterange=", x))
 	*x = 0;
     }
 dyStringPrintf(dy, "%s %s %s\r\n", method, proxyUrl ? urlForProxy : npu.file, protocol);