06b0009211c47fc85787ac3d9bb8a55652c13556 galt Thu Jul 20 11:39:39 2023 -0700 HTTP/1.1 without persistent connections. Addresses complaints that byterange headers should not be used with old HTTP/1.0, or that HTTP/1.0 should no longer be used. fixes #31774 diff --git src/lib/net.c src/lib/net.c index 0795279..0f50bae7 100644 --- src/lib/net.c +++ src/lib/net.c @@ -1259,41 +1259,41 @@ /* 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, boolean noProxy) +int connectNpu(struct netParsedUrl npu, char *url, boolean noProxy, char *httpProtocol) /* 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), noProxy); + sd = netConnectHttps(npu.host, atoi(npu.port), noProxy, httpProtocol); } 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]; @@ -1328,49 +1328,51 @@ * 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 * Cert verification control via hg.conf httpsCertCheck or env var https_cert_check * Cert verify domains exception white-list via hg.conf httpsCertCheckDomainExceptions or env var https_cert_check_domain_exceptions * Return data socket, or -1 if error.*/ { struct netParsedUrl npu; struct netParsedUrl pxy; struct dyString *dy = dyStringNew(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); if (!sameString(pxy.protocol, "http")) errAbort("Unknown proxy protocol %s in %s.", pxy.protocol, proxyUrl); - sd = connectNpu(pxy, url, noProxy); + sd = connectNpu(pxy, url, noProxy, protocol); char *logProxy = getenv("log_proxy"); if (sameOk(logProxy,"on")) verbose(1, "%s via proxy %s\n", url, proxyUrl); } else { - sd = connectNpu(npu, url, noProxy); + sd = connectNpu(npu, url, noProxy, protocol); } 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); @@ -1398,47 +1400,50 @@ setAuthorization(pxy, "Proxy-Authorization", dy); dyStringAppend(dy, "Accept: */*\r\n"); if (npu.byteRangeStart != -1) { if (npu.byteRangeEnd != -1) dyStringPrintf(dy, "Range: bytes=%lld-%lld\r\n" , (long long)npu.byteRangeStart , (long long)npu.byteRangeEnd); else dyStringPrintf(dy, "Range: bytes=%lld-\r\n" , (long long)npu.byteRangeStart); } if (optionalHeader) dyStringAppend(dy, optionalHeader); +if (sameString(protocol, "HTTP/1.1")) + dyStringAppend(dy, "Connection: close\r\n"); // NON-persistent HTTP 1.1 connection /* finish off the header with final blank line */ dyStringAppend(dy, "\r\n"); mustWriteFd(sd, dy->string, dy->stringSize); + /* Clean up and return handle. */ dyStringFree(&dy); return sd; } int netOpenHttpExt(char *url, char *method, char *optionalHeader) /* Return a file handle that will read the url. optionalHeader * may by NULL or may contain cookies and other info. */ { -return netHttpConnect(url, method, "HTTP/1.0", "genome.ucsc.edu/net.c", optionalHeader); +return netHttpConnect(url, method, "HTTP/1.1", "genome.ucsc.edu/net.c", optionalHeader); } static int netGetOpenHttp(char *url) /* Return a file handle that will read the url. */ { return netOpenHttpExt(url, "GET", NULL); } int netUrlHeadExt(char *url, char *method, struct hash *hash) /* Go get head and return status. Return negative number if * can't get head. If hash is non-null, fill it with header * lines with upper cased keywords for case-insensitive lookup, * including hopefully CONTENT-TYPE: . */ { int sd = netOpenHttpExt(url, method, NULL);