9c918a797291419d4c83699c997d72df815941eb
galt
  Tue May 31 21:07:33 2011 -0700
https:adding ability to wait on sockets of both sides of the conversation, in particular this enables using PUT to upload a large file e.g. Amazon Storage
diff --git src/lib/https.c src/lib/https.c
index c641bd2..1eeb45a 100644
--- src/lib/https.c
+++ src/lib/https.c
@@ -111,63 +111,105 @@
 	ERR_print_errors_fp(stderr);
 	errAbort("Error establishing SSL connection\n");
 	return -1;
 	}
 
     /* future extension: checking certificates 
 
     if (certFile || certPath)
 	if (!check_cert(ssl, host))
 	    return -1;
 
     */
 
     /* Could examine ssl here to get connection info */
 
+    /* we need to wait on both the user's socket and the BIO SSL socket 
+     * to see if we need to ferry data from one to the other */
+
+    /* Get underlying file descriptor, needed for select call */
+    fd = BIO_get_fd(sbio, NULL);
+    if (fd == -1) 
+	{
+	errAbort("BIO doesn't seem to be initialized in https, unable to get descriptor.");
+	return(-1);
+        }
+
+    fd_set readfds;
+    fd_set writefds;
+    boolean done;
+    int err;
+
+
     char buf[32768];
+    done = FALSE;
+    while (!done) 
+	{
+
+	FD_ZERO(&readfds);
+	FD_ZERO(&writefds);
+	FD_SET(fd, &readfds);
+	FD_SET(sv[1], &readfds);
+
+	err = select(max(fd,sv[1]) + 1, &readfds, &writefds, NULL, NULL);
+
+	/* Evaluate select() return code */
+	if (err < 0) 
+	    {
+	    errAbort("error during select()");
+	    return(-1);
+	    }
+	if (err == 0) 
+	    {
+	    return(-1);     /* Timeout (not currently in use) */
+	    }
+
+	if (FD_ISSET(sv[1], &readfds))
+	    {
     int rd = 0;
 
-    while((rd = read(sv[1], buf, 32768)) > 0) 
+	    rd = read(sv[1], buf, 32768);
+	    if (rd == -1)
+		errnoAbort("error reading https socket");
+	    if (rd > 0)
 	{
 	if(BIO_write(sbio, buf, rd) <= 0) 
 	    {
 	    ERR_print_errors_fp(stderr);
 	    errAbort("Error writing SSL connection\n");
 	    return -1;
 	    }
-
-        // TODO may someday need to readywait on both connections
-        break;   // for now, just get input once and move on
-        
 	}
-    if (rd == -1)
-	errnoAbort("error reading https socket");
+	    else 
+		break;
+	    }
 
-    for(;;) 
+	if (FD_ISSET(fd, &readfds))
 	{
 	len = BIO_read(sbio, buf, 32768);
 	if(len < 0) 
 	    {
 	    ERR_print_errors_fp(stderr);
 	    errAbort("Error reading SSL connection\n");
 	    return -1;
 	    }
 	if(len == 0) break;
 	int wt = write(sv[1], buf, len);
 	if (wt == -1)
 	    errnoAbort("error writing https socket");
 	}
+	}
 
     BIO_free_all(sbio);
     close(sv[1]);  /* we are done with it */
 
     exit(0);
 
     /* child will never get to here */
     }
 
 /* parent */
 
 close(sv[1]);  /* close unused half of socket */
 
 return sv[0];