diff -bur curl-7.16.1/lib/http.c mycurl-7.16.1/lib/http.c
--- curl-7.16.1/lib/http.c	2007-01-29 09:26:37.000000000 +0000
+++ mycurl-7.16.1/lib/http.c	2007-02-13 15:44:21.000000000 +0000
@@ -1115,17 +1115,9 @@
   struct Curl_transfer_keeper *k = &data->reqdata.keep;
   CURLcode result;
   int res;
-  size_t nread;   /* total size read */
-  int perline; /* count bytes per line */
-  int keepon=TRUE;
-  ssize_t gotbytes;
-  char *ptr;
   long timeout =
     data->set.timeout?data->set.timeout:3600; /* in seconds */
-  char *line_start;
-  char *host_port;
   curl_socket_t tunnelsocket = conn->sock[sockindex];
-  send_buffer *req_buffer;
   curl_off_t cl=0;
   bool closeConnection = FALSE;
 
@@ -1134,10 +1126,15 @@
 #define SELECT_TIMEOUT 2
   int error = SELECT_OK;
 
-  infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
   conn->bits.proxy_connect_closed = FALSE;
 
   do {
+    if (!conn->bits.tunnel_connecting) { /* BEGIN CONNECT PHASE */
+      char *host_port;
+      send_buffer *req_buffer;
+ 
+      infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
+
     if(data->reqdata.newurl) {
       /* This only happens if we've looped here due to authentication reasons,
          and we don't really use the newly cloned URL here then. Just free()
@@ -1214,6 +1211,51 @@
     if(result)
       return result;
 
+      conn->bits.tunnel_connecting = TRUE;
+    } /* END CONNECT PHASE */
+
+    /* now we've issued the CONNECT and we're waiting to hear back -
+       we try not to block here in multi-mode because that might be a LONG
+       wait if the proxy cannot connect-through to the remote host. */
+
+    /* if timeout is requested, find out how much remaining time we have */
+    long check = timeout - /* timeout time */
+      Curl_tvdiff(Curl_tvnow(), conn->now)/1000; /* spent time */
+    if(check <=0 ) {
+      failf(data, "Proxy CONNECT aborted due to timeout");
+      error = SELECT_TIMEOUT; /* already too little time */
+      break;
+    }
+
+    /* if we're in multi-mode and we would block, return instead for a retry */
+    if (Curl_if_multi == data->state.used_interface) {
+      if (0 == Curl_select(tunnelsocket, CURL_SOCKET_BAD, 0)) {
+        /* return so we'll be called again polling-style */
+	return CURLE_OK;
+      } else {
+        infof(data,
+	      "Multi mode finished polling for response from proxy CONNECT.");
+      }
+    } else {
+        infof(data, "Easy mode waiting for response from proxy CONNECT.");
+    }
+
+    /* at this point, either:
+       1) we're in easy-mode and so it's okay to block waiting for a CONNECT
+          response
+       2) we're in multi-mode and we didn't block - it's either an error or we
+          now have some data waiting.
+       In any case, the tunnel_connecting phase is over. */
+    conn->bits.tunnel_connecting = FALSE;
+
+    { /* BEGIN NEGOTIATION PHASE */
+      size_t nread;   /* total size read */
+      int perline; /* count bytes per line */
+      int keepon=TRUE;
+      ssize_t gotbytes;
+      char *ptr;
+      char *line_start;
+
     ptr=data->state.buffer;
     line_start = ptr;
 
@@ -1367,6 +1409,7 @@
       conn->sock[sockindex] = CURL_SOCKET_BAD;
       break;
     }
+    } /* END NEGOTIATION PHASE */
   } while(data->reqdata.newurl);
 
   if(200 != k->httpcode) {
@@ -1418,6 +1461,11 @@
       return result;
   }
 
+  if (conn->bits.tunnel_connecting) {
+    /* nothing else to do except wait right now - we're not done here. */
+    return CURLE_OK;
+  }
+
   if(!data->state.this_is_a_follow) {
     /* this is not a followed location, get the original host name */
     if (data->state.first_host)
Only in mycurl-7.16.1/lib: http.c.orig
Only in mycurl-7.16.1/lib: http.c.rej
diff -bur curl-7.16.1/lib/multi.c mycurl-7.16.1/lib/multi.c
--- curl-7.16.1/lib/multi.c	2007-01-27 21:22:02.000000000 +0000
+++ mycurl-7.16.1/lib/multi.c	2007-02-13 15:47:03.000000000 +0000
@@ -62,6 +62,7 @@
   CURLM_STATE_CONNECT,     /* resolve/connect has been sent off */
   CURLM_STATE_WAITRESOLVE, /* awaiting the resolve to finalize */
   CURLM_STATE_WAITCONNECT, /* awaiting the connect to finalize */
+  CURLM_STATE_WAITPROXYCONNECT, /* awaiting the proxy connect to finalize */
   CURLM_STATE_PROTOCONNECT, /* completing the protocol-specific connect
                                phase */
   CURLM_STATE_WAITDO,      /* wait for our turn to send the request */
@@ -865,10 +866,14 @@
           if(protocol_connect) {
             multistate(easy, CURLM_STATE_WAITDO);
           } else {
+            if (easy->easy_conn->bits.tunnel_connecting) {
+              multistate(easy, CURLM_STATE_WAITPROXYCONNECT);
+	    } else {
             multistate(easy, CURLM_STATE_WAITCONNECT);
           }
         }
       }
+      }
       break;
 
     case CURLM_STATE_WAITRESOLVE:
@@ -894,10 +899,15 @@
           result = CURLM_CALL_MULTI_PERFORM;
           if(protocol_connect)
             multistate(easy, CURLM_STATE_DO);
-          else
+          else {
+            if (easy->easy_conn->bits.tunnel_connecting) {
+              multistate(easy, CURLM_STATE_WAITPROXYCONNECT);
+	    } else {
             multistate(easy, CURLM_STATE_WAITCONNECT);
         }
       }
+        }
+      }
 
       if(CURLE_OK != easy->result) {
         /* failure detected */
@@ -908,6 +918,14 @@
     }
     break;
 
+    case CURLM_STATE_WAITPROXYCONNECT:      
+      easy->result = Curl_http_connect(easy->easy_conn, &protocol_connect);
+
+      if(CURLE_OK == easy->result)
+        if (!easy->easy_conn->bits.tunnel_connecting)
+	  multistate(easy, CURLM_STATE_WAITCONNECT);
+    break;
+
     case CURLM_STATE_WAITCONNECT:
       /* awaiting a completion of an asynch connect */
       easy->result = Curl_is_connected(easy->easy_conn,
Only in mycurl-7.16.1/lib: multi.c.orig
diff -bur curl-7.16.1/lib/urldata.h mycurl-7.16.1/lib/urldata.h
--- curl-7.16.1/lib/urldata.h	2007-01-23 22:46:31.000000000 +0000
+++ mycurl-7.16.1/lib/urldata.h	2007-02-09 14:56:08.000000000 +0000
@@ -462,6 +462,8 @@
                          This is implicit when SSL-protocols are used through
                          proxies, but can also be enabled explicitly by
                          apps */
+  bool tunnel_connecting; /* TRUE while we're still waiting for a proxy CONNECT
+			   */
   bool authneg;       /* TRUE when the auth phase has started, which means
                          that we are creating a request with an auth header,
                          but it is not the final request in the auth
Only in mycurl-7.16.1/lib: urldata.h.orig

