cb1fdec8bd07cde7453f8b3bc3299938504945a5
galt
  Thu Dec 5 02:11:37 2024 -0800
Apparently openssl3 is not handling setting the socket to non-blocking, but I can do it easily myself. fixes #rm34900

diff --git src/lib/https.c src/lib/https.c
index 513695e..e1a997c 100644
--- src/lib/https.c
+++ src/lib/https.c
@@ -151,30 +151,35 @@
 int brd = 0;
 int bwt = 0;
 int fd = 0;
 while (1) 
     {
 
     // Do NOT move this outside the while loop. 
     /* Get underlying file descriptor, needed for select call */
     fd = BIO_get_fd(params->sbio, NULL);
     if (fd == -1) 
 	{
 	xerr("BIO doesn't seem to be initialized in https, unable to get descriptor.");
 	goto cleanup;
 	}
 
+    // The earlier call to BIO_set_nbio() should have turned non-blocking io on already.
+    if (fcntl(fd, F_SETFL, SOCK_NONBLOCK) == -1) {
+        xerr("Could not switch to non-blocking.\n");
+	goto cleanup;
+    }
 
     FD_ZERO(&readfds);
     FD_ZERO(&writefds);
 
     if (brd == 0)
 	FD_SET(fd, &readfds);
     if (swt < srd)
 	FD_SET(fd, &writefds);
     if (srd == 0)
 	FD_SET(params->sv[1], &readfds);
 
     tv.tv_sec = 90; // timeout 90 seconds needed for slow CGIs respsonse time.
     tv.tv_usec = 0;
 
     err = select(max(fd,params->sv[1]) + 1, &readfds, &writefds, NULL, &tv);
@@ -198,50 +203,53 @@
 	    {
 	    swt = 0;
 	    srd = read(params->sv[1], sbuf, 32768);
 	    if (srd == -1)
 		{
 		if (errno != 104) // udcCache often closes causing "Connection reset by peer"
 		    xerrno("error reading user pipe for https socket");
 		goto cleanup;
 		}
 	    if (srd == 0) 
 		break;  // user closed socket, we are done
 	    }
 
 	if (FD_ISSET(fd, &writefds))
 	    {
+            if (swt < srd) 
+		{
 		int swtx = BIO_write(params->sbio, sbuf+swt, srd-swt);
 		if (swtx <= 0)
 		    {
 		    if (!BIO_should_write(params->sbio))
 			{
 			ERR_print_errors_fp(stderr);
 			xerr("Error writing SSL connection");
 			goto cleanup;
 			}
 		    }
 		else
 		    {
 		    swt += swtx;
 		    if (swt >= srd)
 			{
 			swt = 0;
 			srd = 0;
 			}
 		    }
 		}
+	    }
 
 	if (FD_ISSET(fd, &readfds))
 	    {
 	    bwt = 0;
 	    brd = BIO_read(params->sbio, bbuf, 32768);
 
 	    if (brd <= 0)
 		{
 		if (BIO_should_read(params->sbio))
 		    {
 		    brd = 0;
 		    continue;
 		    }
 		else
 		    {
@@ -665,32 +673,31 @@
 	// VITAL FOR PROPER VERIFICATION OF CERTS
 	if (!SSL_CTX_set_default_verify_paths(ctx)) 
 	    {
 	    warn("SSL set default verify paths failed");
 	    }
 
 	// add the hostName to the structure and set it here, making it available during callback.
 	myData.hostName = hostName;
 	doSetMyData = TRUE;
 
 	} 
     }
 
 // Don't want any retries since we are non-blocking bio now
 // This is available on newer versions of openssl
-//SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
-
+//SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);  // this has become the default, but only matters for blocking mode which we are not using.
 
 // Support for Http Proxy
 struct netParsedUrl pxy;
 if (proxyUrl)
     {
     netParseUrl(proxyUrl, &pxy);
     if (!sameString(pxy.protocol, "http"))
 	{
 	warn("Unknown proxy protocol %s in %s. Should be http.", pxy.protocol, proxyUrl);
 	goto cleanup2;
 	}
     connectHost = pxy.host;
     connectPort = atoi(pxy.port);
     }
 else