Module Name:    src
Committed By:   martin
Date:           Tue Oct 15 06:29:09 UTC 2024

Modified Files:
        src/external/bsd/fetch/dist/libfetch [netbsd-10]: common.c common.h
            fetch.3 ftp.c http.c

Log Message:
Pull up the following revisions, requested by wiz in ticket #980:

        external/bsd/fetch/dist/libfetch/common.c       up to 1.7
        external/bsd/fetch/dist/libfetch/common.h       up to 1.3
        external/bsd/fetch/dist/libfetch/fetch.3        up to 1.5
        external/bsd/fetch/dist/libfetch/ftp.c          up to 1.8
        external/bsd/fetch/dist/libfetch/http.c         up to 1.6

libfetch: fix pkg_install core dumps reported in PR 57179


To generate a diff of this commit:
cvs rdiff -u -r1.2.54.2 -r1.2.54.3 \
    src/external/bsd/fetch/dist/libfetch/common.c
cvs rdiff -u -r1.2 -r1.2.36.1 src/external/bsd/fetch/dist/libfetch/common.h
cvs rdiff -u -r1.4 -r1.4.26.1 src/external/bsd/fetch/dist/libfetch/fetch.3
cvs rdiff -u -r1.7 -r1.7.36.1 src/external/bsd/fetch/dist/libfetch/ftp.c
cvs rdiff -u -r1.4 -r1.4.6.1 src/external/bsd/fetch/dist/libfetch/http.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/bsd/fetch/dist/libfetch/common.c
diff -u src/external/bsd/fetch/dist/libfetch/common.c:1.2.54.2 src/external/bsd/fetch/dist/libfetch/common.c:1.2.54.3
--- src/external/bsd/fetch/dist/libfetch/common.c:1.2.54.2	Sun Jan 14 13:19:39 2024
+++ src/external/bsd/fetch/dist/libfetch/common.c	Tue Oct 15 06:29:09 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: common.c,v 1.2.54.2 2024/01/14 13:19:39 martin Exp $	*/
+/*	$NetBSD: common.c,v 1.2.54.3 2024/10/15 06:29:09 martin Exp $	*/
 /*-
  * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
  * Copyright (c) 2008, 2010 Joerg Sonnenberger <jo...@netbsd.org>
@@ -41,6 +41,13 @@
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <sys/uio.h>
+#if defined(HAVE_POLL_H) || defined(NETBSD)
+#include <poll.h>
+#define HAVE_POLL
+#elif HAVE_SYS_POLL_H
+#define HAVE_POLL
+#include <sys/poll.h>
+#endif
 
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -236,6 +243,9 @@ fetch_reopen(int sd)
 	conn->next_buf = NULL;
 	conn->next_len = 0;
 	conn->sd = sd;
+#ifdef HAVE_POLL
+	conn->buf_events = POLLIN;
+#endif
 	return (conn);
 }
 
@@ -316,6 +326,7 @@ fetch_connect(struct url *url, int af, i
 	if ((conn = fetch_reopen(sd)) == NULL) {
 		fetch_syserr();
 		close(sd);
+		return (NULL);
 	}
 	conn->cache_url = fetchCopyURL(url);
 	conn->cache_af = af;
@@ -368,7 +379,9 @@ fetch_cache_get(const struct url *url, i
 {
 	conn_t *conn, *last_conn = NULL;
 
-	for (conn = connection_cache; conn; conn = conn->next_cached) {
+	for (conn = connection_cache; conn; last_conn = conn,
+	    conn = conn->next_cached)
+	{
 		if (conn->cache_url->port == url->port &&
 		    strcmp(conn->cache_url->scheme, url->scheme) == 0 &&
 		    strcmp(conn->cache_url->host, url->host) == 0 &&
@@ -395,8 +408,8 @@ fetch_cache_get(const struct url *url, i
 void
 fetch_cache_put(conn_t *conn, int (*closecb)(conn_t *))
 {
-	conn_t *iter, *last;
-	int global_count, host_count;
+	conn_t *iter, *last, *oiter;
+	int global_count, host_count, added;
 
 	if (conn->cache_url == NULL || cache_global_limit == 0) {
 		(*closecb)(conn);
@@ -405,20 +418,28 @@ fetch_cache_put(conn_t *conn, int (*clos
 
 	global_count = host_count = 0;
 	last = NULL;
-	for (iter = connection_cache; iter;
-	    last = iter, iter = iter->next_cached) {
+	for (iter = connection_cache; iter; ) {
 		++global_count;
-		if (strcmp(conn->cache_url->host, iter->cache_url->host) == 0)
+		added = !strcmp(conn->cache_url->host, iter->cache_url->host);
+		if (added)
 			++host_count;
 		if (global_count < cache_global_limit &&
-		    host_count < cache_per_host_limit)
-			continue;
-		--global_count;
-		if (last != NULL)
-			last->next_cached = iter->next_cached;
-		else
-			connection_cache = iter->next_cached;
-		(*iter->cache_close)(iter);
+		    host_count < cache_per_host_limit) {
+			oiter = NULL;
+			last = iter;
+		} else {
+			--global_count;
+			if (added)
+				--host_count;
+			if (last != NULL)
+				last->next_cached = iter->next_cached;
+			else
+				connection_cache = iter->next_cached;
+			oiter = iter;
+		}
+		iter = iter->next_cached;
+		if (oiter)
+			(*oiter->cache_close)(oiter);
 	}
 
 	conn->cache_close = closecb;
@@ -430,7 +451,7 @@ fetch_cache_put(conn_t *conn, int (*clos
  * Enable SSL on a connection.
  */
 int
-fetch_ssl(conn_t *conn, int verbose)
+fetch_ssl(conn_t *conn, const struct url *URL, int verbose)
 {
 
 #ifdef WITH_SSL
@@ -455,11 +476,17 @@ fetch_ssl(conn_t *conn, int verbose)
 		fprintf(stderr, "SSL context creation failed\n");
 		return (-1);
 	}
+	conn->buf_events = 0;
 	SSL_set_fd(conn->ssl, conn->sd);
-	if (!SSL_set_tlsext_host_name(conn->ssl, conn->cache_url->host)) {
-		fprintf(stderr, "SSL hostname setting failed\n"); 
+#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
+	if (!SSL_set_tlsext_host_name(conn->ssl, (char *)(uintptr_t)URL->host))
+	{
+		fprintf(stderr,
+		    "TLS server name indication extension failed for host %s\n",
+		    URL->host);
 		return (-1);
 	}
+#endif
 	if (SSL_connect(conn->ssl) == -1){
 		ERR_print_errors_fp(stderr);
 		return (-1);
@@ -491,6 +518,17 @@ fetch_ssl(conn_t *conn, int verbose)
 #endif
 }
 
+#ifdef HAVE_POLL
+static int
+compute_timeout(const struct timeval *tv)
+{
+	struct timeval cur;
+
+	gettimeofday(&cur, NULL);
+	return (tv->tv_sec - cur.tv_sec) * 1000
+	    + (tv->tv_usec - cur.tv_usec) / 1000;
+}
+#endif
 
 /*
  * Read a character from a connection w/ timeout
@@ -498,8 +536,13 @@ fetch_ssl(conn_t *conn, int verbose)
 ssize_t
 fetch_read(conn_t *conn, char *buf, size_t len)
 {
-	struct timeval now, timeout, waittv;
+	struct timeval timeout_end;
+#ifdef HAVE_POLL
+	struct pollfd pfd;
+#else
 	fd_set readfds;
+#endif
+	int timeout_cur;
 	ssize_t rlen;
 	int r;
 
@@ -516,17 +559,41 @@ fetch_read(conn_t *conn, char *buf, size
 	}
 
 	if (fetchTimeout) {
+#ifndef HAVE_POLL
 		FD_ZERO(&readfds);
-		gettimeofday(&timeout, NULL);
-		timeout.tv_sec += fetchTimeout;
+#endif
+		gettimeofday(&timeout_end, NULL);
+		timeout_end.tv_sec += fetchTimeout;
 	}
 
 	for (;;) {
+#ifdef HAVE_POLL
+		pfd.fd = conn->sd;
+		pfd.events = conn->buf_events;
+		if (fetchTimeout && pfd.events) {
+			do {
+				timeout_cur = compute_timeout(&timeout_end);
+				if (timeout_cur < 0) {
+					errno = ETIMEDOUT;
+					fetch_syserr();
+					return (-1);
+				}
+				errno = 0;
+				r = poll(&pfd, 1, timeout_cur);
+				if (r == -1) {
+					if (errno == EINTR && fetchRestartCalls)
+						continue;
+					fetch_syserr();
+					return (-1);
+				}
+			} while (pfd.revents == 0);
+#else
 		while (fetchTimeout && !FD_ISSET(conn->sd, &readfds)) {
+			struct timeval waittv, now;
 			FD_SET(conn->sd, &readfds);
 			gettimeofday(&now, NULL);
-			waittv.tv_sec = timeout.tv_sec - now.tv_sec;
-			waittv.tv_usec = timeout.tv_usec - now.tv_usec;
+			waittv.tv_sec = timeout_end.tv_sec - now.tv_sec;
+			waittv.tv_usec = timeout_end.tv_usec - now.tv_usec;
 			if (waittv.tv_usec < 0) {
 				waittv.tv_usec += 1000000;
 				waittv.tv_sec--;
@@ -544,11 +611,29 @@ fetch_read(conn_t *conn, char *buf, size
 				fetch_syserr();
 				return (-1);
 			}
+#endif
 		}
 #ifdef WITH_SSL
-		if (conn->ssl != NULL)
-			rlen = SSL_read(conn->ssl, buf, (int)len);
-		else
+		if (conn->ssl != NULL) {
+			rlen = SSL_read(conn->ssl, buf, len);
+			if (rlen == -1) {
+				switch (SSL_get_error(conn->ssl, rlen)) {
+				case SSL_ERROR_WANT_READ:
+					conn->buf_events = POLLIN;
+					break;
+				case SSL_ERROR_WANT_WRITE:
+					conn->buf_events = POLLOUT;
+					break;
+				default:
+					errno = EIO;
+					fetch_syserr();
+					return -1;
+				}
+			} else {
+				/* Assume buffering on the SSL layer. */
+				conn->buf_events = 0;
+			}
+		} else
 #endif
 			rlen = read(conn->sd, buf, len);
 		if (rlen >= 0)

Index: src/external/bsd/fetch/dist/libfetch/common.h
diff -u src/external/bsd/fetch/dist/libfetch/common.h:1.2 src/external/bsd/fetch/dist/libfetch/common.h:1.2.36.1
--- src/external/bsd/fetch/dist/libfetch/common.h:1.2	Tue Jan  7 02:13:00 2014
+++ src/external/bsd/fetch/dist/libfetch/common.h	Tue Oct 15 06:29:09 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: common.h,v 1.2 2014/01/07 02:13:00 joerg Exp $	*/
+/*	$NetBSD: common.h,v 1.2.36.1 2024/10/15 06:29:09 martin Exp $	*/
 /*-
  * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
  * All rights reserved.
@@ -45,9 +45,16 @@
 #include <openssl/err.h>
 #endif
 
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define LIBFETCH_PRINTFLIKE(fmtarg, firstvararg)	\
+	    __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
+#else
+#define LIBFETCH_PRINTFLIKE(fmtarg, firstvararg)
+#endif
+
 #if !defined(__sun) && !defined(__hpux) && !defined(__INTERIX) && \
     !defined(__digital__) && !defined(__linux) && !defined(__MINT__) && \
-    !defined(__sgi)
+    !defined(__sgi) && !defined(__minix) && !defined(__CYGWIN__)
 #define HAVE_SA_LEN
 #endif
 
@@ -59,6 +66,7 @@ struct fetchconn {
 	char		*buf;		/* buffer */
 	size_t		 bufsize;	/* buffer size */
 	size_t		 buflen;	/* length of buffer contents */
+	int		 buf_events;	/* poll flags for the next cycle */
 	char		*next_buf;	/* pending buffer, e.g. after getln */
 	size_t		 next_len;	/* size of pending buffer */
 	int		 err;		/* last protocol reply code */
@@ -90,7 +98,7 @@ struct fetcherr {
 
 void		 fetch_seterr(struct fetcherr *, int);
 void		 fetch_syserr(void);
-void		 fetch_info(const char *, ...) __printflike(1, 2);
+void		 fetch_info(const char *, ...) LIBFETCH_PRINTFLIKE(1, 2);
 int		 fetch_default_port(const char *);
 int		 fetch_default_proxy_port(const char *);
 int		 fetch_bind(int, int, const char *);
@@ -98,7 +106,7 @@ conn_t		*fetch_cache_get(const struct ur
 void		 fetch_cache_put(conn_t *, int (*)(conn_t *));
 conn_t		*fetch_connect(struct url *, int, int);
 conn_t		*fetch_reopen(int);
-int		 fetch_ssl(conn_t *, int);
+int		 fetch_ssl(conn_t *, const struct url *, int);
 ssize_t		 fetch_read(conn_t *, char *, size_t);
 int		 fetch_getln(conn_t *);
 ssize_t		 fetch_write(conn_t *, const void *, size_t);

Index: src/external/bsd/fetch/dist/libfetch/fetch.3
diff -u src/external/bsd/fetch/dist/libfetch/fetch.3:1.4 src/external/bsd/fetch/dist/libfetch/fetch.3:1.4.26.1
--- src/external/bsd/fetch/dist/libfetch/fetch.3:1.4	Tue May 31 16:26:47 2016
+++ src/external/bsd/fetch/dist/libfetch/fetch.3	Tue Oct 15 06:29:09 2024
@@ -25,9 +25,9 @@
 .\" SUCH DAMAGE.
 .\"
 .\" $FreeBSD: fetch.3,v 1.64 2007/12/18 11:03:26 des Exp $
-.\" $NetBSD: fetch.3,v 1.4 2016/05/31 16:26:47 abhinav Exp $
+.\" $NetBSD: fetch.3,v 1.4.26.1 2024/10/15 06:29:09 martin Exp $
 .\"
-.Dd January 22, 2010
+.Dd December 22, 2023
 .Dt FETCH 3
 .Os
 .Sh NAME
@@ -638,6 +638,10 @@ which proxies should not be used.
 Same as
 .Ev NO_PROXY ,
 for compatibility.
+.It Ev SSL_NO_VERIFY_PEER
+If defined,
+.Nm
+will skip validating certificates when fetching HTTPS URLs.
 .El
 .Sh EXAMPLES
 To access a proxy server on

Index: src/external/bsd/fetch/dist/libfetch/ftp.c
diff -u src/external/bsd/fetch/dist/libfetch/ftp.c:1.7 src/external/bsd/fetch/dist/libfetch/ftp.c:1.7.36.1
--- src/external/bsd/fetch/dist/libfetch/ftp.c:1.7	Tue Jan  7 02:13:00 2014
+++ src/external/bsd/fetch/dist/libfetch/ftp.c	Tue Oct 15 06:29:09 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: ftp.c,v 1.7 2014/01/07 02:13:00 joerg Exp $	*/
+/*	$NetBSD: ftp.c,v 1.7.36.1 2024/10/15 06:29:09 martin Exp $	*/
 /*-
  * Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
  * Copyright (c) 2008, 2009, 2010 Joerg Sonnenberger <jo...@netbsd.org>
@@ -138,7 +138,6 @@ static void
 unmappedaddr(struct sockaddr_in6 *sin6, socklen_t *len)
 {
 	struct sockaddr_in *sin4;
-	void *addrp;
 	uint32_t addr;
 	int port;
 
@@ -146,8 +145,11 @@ unmappedaddr(struct sockaddr_in6 *sin6, 
 	    !IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
 		return;
 	sin4 = (struct sockaddr_in *)(void *)sin6;
-	addrp = &sin6->sin6_addr.s6_addr[12];
-	addr = *(uint32_t *)addrp;
+#ifdef s6_addr32
+	addr = sin6->sin6_addr.s6_addr32[3];
+#else
+	memcpy(&addr, &sin6->sin6_addr.s6_addr[12], sizeof(addr));
+#endif
 	port = sin6->sin6_port;
 	memset(sin4, 0, sizeof(struct sockaddr_in));
 	sin4->sin_addr.s_addr = addr;
@@ -198,7 +200,7 @@ ftp_chkerr(conn_t *conn)
 /*
  * Send a command and check reply
  */
-__printflike(2, 3)
+LIBFETCH_PRINTFLIKE(2, 3)
 static int
 ftp_cmd(conn_t *conn, const char *fmt, ...)
 {
@@ -331,7 +333,8 @@ ftp_cwd(conn_t *conn, const char *path, 
 	} else if (strcmp(conn->ftp_home, "/") == 0) {
 		dst = strdup(path - 1);
 	} else {
-		asprintf(&dst, "%s/%s", conn->ftp_home, path);
+		if (asprintf(&dst, "%s/%s", conn->ftp_home, path) == -1)
+			dst = NULL;
 	}
 	if (dst == NULL) {
 		fetch_syserr();
@@ -1170,12 +1173,14 @@ ftp_request(struct url *url, const char 
 		return (NULL);
 
 	if ((path = fetchUnquotePath(url)) == NULL) {
+		fetch_close(conn);
 		fetch_syserr();
 		return NULL;
 	}
 
 	/* change directory */
 	if (ftp_cwd(conn, path, op_arg != NULL) == -1) {
+		fetch_close(conn);
 		free(path);
 		return (NULL);
 	}
@@ -1188,12 +1193,14 @@ ftp_request(struct url *url, const char 
 	if (us && ftp_stat(conn, path, us) == -1
 	    && fetchLastErrCode != FETCH_PROTO
 	    && fetchLastErrCode != FETCH_UNAVAIL) {
+		fetch_close(conn);
 		free(path);
 		return (NULL);
 	}
 
 	if (if_modified_since && url->last_modified > 0 &&
 	    url->last_modified >= us->mtime) {
+		fetch_cache_put(conn, ftp_disconnect);
 		free(path);
 		fetchLastErrCode = FETCH_UNCHANGED;
 		snprintf(fetchLastErrString, MAXERRSTRING, "Unchanged");
@@ -1202,6 +1209,7 @@ ftp_request(struct url *url, const char 
 
 	/* just a stat */
 	if (strcmp(op, "STAT") == 0) {
+		fetch_cache_put(conn, ftp_disconnect);
 		free(path);
 		return fetchIO_unopen(NULL, NULL, NULL, NULL);
 	}

Index: src/external/bsd/fetch/dist/libfetch/http.c
diff -u src/external/bsd/fetch/dist/libfetch/http.c:1.4 src/external/bsd/fetch/dist/libfetch/http.c:1.4.6.1
--- src/external/bsd/fetch/dist/libfetch/http.c:1.4	Mon Jun  1 00:55:24 2020
+++ src/external/bsd/fetch/dist/libfetch/http.c	Tue Oct 15 06:29:09 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: http.c,v 1.4 2020/06/01 00:55:24 kamil Exp $	*/
+/*	$NetBSD: http.c,v 1.4.6.1 2024/10/15 06:29:09 martin Exp $	*/
 /*-
  * Copyright (c) 2000-2004 Dag-Erling Coïdan Smørgrav
  * Copyright (c) 2003 Thomas Klausner <w...@netbsd.org>
@@ -63,8 +63,12 @@
  * SUCH DAMAGE.
  */
 
-#if defined(__linux__) || defined(__MINT__)
+#if defined(__linux__) || defined(__MINT__) || defined(__FreeBSD_kernel__)
 /* Keep this down to Linux or MiNT, it can create surprises elsewhere. */
+/*
+   __FreeBSD_kernel__ is defined for GNU/kFreeBSD.
+   See http://glibc-bsd.alioth.debian.org/porting/PORTING .
+*/
 #define _GNU_SOURCE
 #endif
 
@@ -329,7 +333,7 @@ http_closefn(void *v)
 		setsockopt(io->conn->sd, IPPROTO_TCP, TCP_NODELAY, &val,
 			   (socklen_t)sizeof(val));
 			  fetch_cache_put(io->conn, fetch_close);
-#ifdef TCP_NOPUSH
+#if defined(TCP_NOPUSH) && !defined(__APPLE__)
 		val = 1;
 		setsockopt(io->conn->sd, IPPROTO_TCP, TCP_NOPUSH, &val,
 		    sizeof(val));
@@ -406,7 +410,7 @@ static struct {
 /*
  * Send a formatted line; optionally echo to terminal
  */
-__printflike(2, 3)
+LIBFETCH_PRINTFLIKE(2, 3)
 static int
 http_cmd(conn_t *conn, const char *fmt, ...)
 {
@@ -523,16 +527,26 @@ http_next_header(conn_t *conn, const cha
 static int
 http_parse_mtime(const char *p, time_t *mtime)
 {
-	char locale[64], *r;
 	struct tm tm;
+	char *r;
+
+#ifdef LC_C_LOCALE
+	r = strptime_l(p, "%a, %d %b %Y %H:%M:%S GMT", &tm, LC_C_LOCALE);
+#else
+	char *locale;
+
+	locale = strdup(setlocale(LC_TIME, NULL));
+	if (locale == NULL)
+		return (-1);
 
-	strncpy(locale, setlocale(LC_TIME, NULL), sizeof(locale));
 	setlocale(LC_TIME, "C");
 	r = strptime(p, "%a, %d %b %Y %H:%M:%S GMT", &tm);
 	/* XXX should add support for date-2 and date-3 */
 	setlocale(LC_TIME, locale);
-	if (r == NULL)
-		return (-1);
+	free(locale);
+#endif
+ 	if (r == NULL)
+ 		return (-1);
 	*mtime = timegm(&tm);
 	return (0);
 }
@@ -710,13 +724,16 @@ http_authorize(conn_t *conn, const char 
 static conn_t *
 http_connect(struct url *URL, struct url *purl, const char *flags, int *cached)
 {
+	struct url *curl;
 	conn_t *conn;
+	hdr_t h;
+	const char *p;
 	int af, verbose;
-#ifdef TCP_NOPUSH
+#if defined(TCP_NOPUSH) && !defined(__APPLE__)
 	int val;
 #endif
 
-	*cached = 1;
+	*cached = 0;
 
 #ifdef INET6
 	af = AF_UNSPEC;
@@ -732,6 +749,7 @@ http_connect(struct url *URL, struct url
 		af = AF_INET6;
 #endif
 
+	curl = (purl != NULL) ? purl : URL;
 	if (purl && strcasecmp(URL->scheme, SCHEME_HTTPS) != 0) {
 		URL = purl;
 	} else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) {
@@ -740,33 +758,64 @@ http_connect(struct url *URL, struct url
 		return (NULL);
 	}
 
-	if ((conn = fetch_cache_get(URL, af)) != NULL) {
+	if ((conn = fetch_cache_get(curl, af)) != NULL) {
 		*cached = 1;
 		return (conn);
 	}
 
-	if ((conn = fetch_connect(URL, af, verbose)) == NULL)
+	if ((conn = fetch_connect(curl, af, verbose)) == NULL)
 		/* fetch_connect() has already set an error code */
 		return (NULL);
+	if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 && purl) {
+		http_cmd(conn, "CONNECT %s:%d HTTP/1.1\r\n",
+				URL->host, URL->port);
+		http_cmd(conn, "Host: %s:%d\r\n",
+				URL->host, URL->port);
+		/* proxy authorization */
+		if (*purl->user || *purl->pwd)
+			http_basic_auth(conn, "Proxy-Authorization",
+			    purl->user, purl->pwd);
+		else if ((p = getenv("HTTP_PROXY_AUTH")) != NULL && *p != '\0')
+			http_authorize(conn, "Proxy-Authorization", p);
+		http_cmd(conn, "\r\n");
+		if (http_get_reply(conn) != HTTP_OK) {
+			http_seterr(conn->err);
+			goto ouch;
+		}
+		/* Read and discard the rest of the proxy response (if any) */
+		do {
+			switch ((h = http_next_header(conn, &p))) {
+			case hdr_syserror:
+				fetch_syserr();
+				goto ouch;
+			case hdr_error:
+				http_seterr(HTTP_PROTOCOL_ERROR);
+				goto ouch;
+			default:
+				/* ignore */ ;
+			}
+		} while (h > hdr_end);
+	}
 	if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 &&
-	    fetch_ssl(conn, verbose) == -1) {
-		fetch_close(conn);
+	    fetch_ssl(conn, URL, verbose) == -1) {
 		/* grrr */
 #ifdef EAUTH
 		errno = EAUTH;
 #else
 		errno = EPERM;
 #endif
-		fetch_syserr();
-		return (NULL);
+		goto ouch;
 	}
 
-#ifdef TCP_NOPUSH
+#if defined(TCP_NOPUSH) && !defined(__APPLE__)
 	val = 1;
 	setsockopt(conn->sd, IPPROTO_TCP, TCP_NOPUSH, &val, sizeof(val));
 #endif
 
 	return (conn);
+ouch:
+	fetch_close(conn);
+	return (NULL);
 }
 
 static struct url *
@@ -800,9 +849,9 @@ set_if_modified_since(conn_t *conn, time
 	struct tm tm;
 	char buf[80];
 	gmtime_r(&last_modified, &tm);
-	snprintf(buf, sizeof(buf), "%.3s, %02d %.3s %4d %02d:%02d:%02d GMT",
+	snprintf(buf, sizeof(buf), "%.3s, %02d %.3s %4ld %02d:%02d:%02d GMT",
 	    weekdays + tm.tm_wday * 3, tm.tm_mday, months + tm.tm_mon * 3,
-	    tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec);
+	    (long)tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec);
 	http_cmd(conn, "If-Modified-Since: %s\r\n", buf);
 }
 
@@ -898,7 +947,7 @@ http_request(struct url *URL, const char
 		if (verbose)
 			fetch_info("requesting %s://%s%s",
 			    url->scheme, host, url->doc);
-		if (purl) {
+		if (purl && strcasecmp(URL->scheme, SCHEME_HTTPS) != 0) {
 			http_cmd(conn, "%s %s://%s%s HTTP/1.1\r\n",
 			    op, url->scheme, host, url->doc);
 		} else {
@@ -958,7 +1007,7 @@ http_request(struct url *URL, const char
 		 * be compatible with such configurations, fiddle with socket
 		 * options to force the pending data to be written.
 		 */
-#ifdef TCP_NOPUSH
+#if defined(TCP_NOPUSH) && !defined(__APPLE__)
 		val = 0;
 		setsockopt(conn->sd, IPPROTO_TCP, TCP_NOPUSH, &val,
 			   sizeof(val));

Reply via email to