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(¶ms->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);