diff -ur 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-09 15:00:17.000000000 +0000
@@ -1115,17 +1115,10 @@
   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 +1127,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 +1212,41 @@
     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 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 (0 == Curl_select(tunnelsocket, CURL_SOCKET_BAD, 0)) {
+      //infof(data, "Still waiting for response from proxy CONNECT.");
+      return CURLE_OK;
+    } else {
+      /* we didn't block - it's either an error or we have some data
+	 waiting now.  either way, the tunnel_connecting phase is over. */
+      infof(data, "Finished waiting for response from proxy CONNECT.");
+      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;
 
@@ -1239,6 +1272,7 @@
         failf(data, "Proxy CONNECT aborted due to select() error");
         break;
       case 0: /* timeout */
+        infof(data, "Unexpectedly still waiting for response from proxy CONNECT.");
         break;
       default:
         res = Curl_read(conn, tunnelsocket, ptr, BUFSIZE-nread, &gotbytes);
@@ -1367,6 +1401,7 @@
       conn->sock[sockindex] = CURL_SOCKET_BAD;
       break;
     }
+    } /* END NEGOTIATION PHASE */
   } while(data->reqdata.newurl);
 
   if(200 != k->httpcode) {
@@ -1388,6 +1423,7 @@
   data->state.authproxy.done = TRUE;
 
   infof (data, "Proxy replied OK to CONNECT request\n");
+  //*done = TRUE;
   return CURLE_OK;
 }
 
@@ -1418,6 +1454,12 @@
       return result;
   }
 
+  if (conn->bits.tunnel_connecting) {
+    /* nothing else to do except wait right now - we're not done here. */
+    //infof(data, "Returning CURLE_OK from unfinished connect.");
+    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)
diff -ur 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-09 14:56:08.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 */
@@ -863,9 +864,16 @@
           result = CURLM_CALL_MULTI_PERFORM;
 
           if(protocol_connect) {
+	    //infof(easy->easy_handle, "Going to WAITDO state");
             multistate(easy, CURLM_STATE_WAITDO);
           } else {
-            multistate(easy, CURLM_STATE_WAITCONNECT);
+            if (easy->easy_conn->bits.tunnel_connecting) {
+	      //infof(easy->easy_handle, "Going to WAITPROXYCONNECT state");
+              multistate(easy, CURLM_STATE_WAITPROXYCONNECT);
+	    } else {
+	      //infof(easy->easy_handle, "Going to WAITCONNECT state");
+              multistate(easy, CURLM_STATE_WAITCONNECT);
+	    }
           }
         }
       }
@@ -894,8 +902,15 @@
           result = CURLM_CALL_MULTI_PERFORM;
           if(protocol_connect)
             multistate(easy, CURLM_STATE_DO);
-          else
-            multistate(easy, CURLM_STATE_WAITCONNECT);
+          else {
+            if (easy->easy_conn->bits.tunnel_connecting) {
+	      //infof(easy->easy_handle, "AGoing to WAITPROXYCONNECT state");
+              multistate(easy, CURLM_STATE_WAITPROXYCONNECT);
+	    } else {
+	      //infof(easy->easy_handle, "AGoing to WAITCONNECT state");
+              multistate(easy, CURLM_STATE_WAITCONNECT);
+	    }
+	  }
         }
       }
 
@@ -908,6 +923,18 @@
     }
     break;
 
+    case CURLM_STATE_WAITPROXYCONNECT:      
+      easy->result = /*Curl_connect(easy->easy_handle, &easy->easy_conn,
+		       &async, &protocol_connect);*/
+	      Curl_http_connect(easy->easy_conn, &protocol_connect);
+
+      if(CURLE_OK == easy->result)
+	      //if(protocol_connect)
+	      //multistate(easy, CURLM_STATE_DO);
+        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,
diff -ur 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

