Index: lib/http.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/http.c,v
retrieving revision 1.302
diff -u -r1.302 http.c
--- lib/http.c	17 Oct 2006 21:32:56 -0000	1.302
+++ lib/http.c	2 Nov 2006 22:42:56 -0000
@@ -903,8 +903,8 @@
       Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr,
                  (size_t)(amount-included_body_bytes), conn);
       if (included_body_bytes)
-        Curl_debug(conn->data, CURLINFO_DATA_OUT, 
-                   ptr+amount-included_body_bytes, 
+        Curl_debug(conn->data, CURLINFO_DATA_OUT,
+                   ptr+amount-included_body_bytes,
                    (size_t)included_body_bytes, conn);
     }
 
@@ -1110,6 +1110,7 @@
   curl_socket_t tunnelsocket = conn->sock[sockindex];
   send_buffer *req_buffer;
   curl_off_t cl=0;
+  int closeConnection = FALSE;
 
 #define SELECT_OK      0
 #define SELECT_ERROR   1
@@ -1117,6 +1118,7 @@
   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(data->reqdata.newurl) {
@@ -1258,7 +1260,7 @@
 
               /* output debug if that is requested */
               if(data->set.verbose)
-                Curl_debug(data, CURLINFO_HEADER_IN, 
+                Curl_debug(data, CURLINFO_HEADER_IN,
                            line_start, (size_t)perline, conn);
 
               /* send the header to the callback */
@@ -1310,6 +1312,9 @@
                 cl = curlx_strtoofft(line_start + strlen("Content-Length:"),
                                      NULL, 10);
               }
+              else if(Curl_compareheader(line_start,
+                                         "Connection:", "close"))
+                closeConnection = TRUE;
               else if(2 == sscanf(line_start, "HTTP/1.%d %d",
                                   &subversion,
                                   &k->httpcode)) {
@@ -1336,11 +1341,21 @@
          headers. 'newurl' is set to a new URL if we must loop. */
       Curl_http_auth_act(conn);
 
+    if (closeConnection && data->reqdata.newurl) {
+      /* Connection closed by server. Don't use it anymore */
+      sclose(conn->sock[sockindex]);
+      conn->sock[sockindex] = CURL_SOCKET_BAD;
+      break;
+    }
   } while(data->reqdata.newurl);
 
   if(200 != k->httpcode) {
     failf(data, "Received HTTP code %d from proxy after CONNECT",
           k->httpcode);
+
+    if (closeConnection && data->reqdata.newurl)
+      conn->bits.proxy_connect_closed = TRUE;
+
     return CURLE_RECV_ERROR;
   }
 
Index: lib/url.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/url.c,v
retrieving revision 1.561
diff -u -r1.561 url.c
--- lib/url.c	2 Nov 2006 21:56:43 -0000	1.561
+++ lib/url.c	2 Nov 2006 22:42:56 -0000
@@ -2394,7 +2394,8 @@
 
     /* it has started, possibly even completed but that knowledge isn't stored
        in this bit! */
-    conn->bits.protoconnstart = TRUE;
+    if (!result)
+      conn->bits.protoconnstart = TRUE;
   }
 
   return result; /* pass back status */
@@ -3957,30 +3958,41 @@
   data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
 #endif /* CURL_DO_LINEEND_CONV */
 
-  if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
-    bool connected = FALSE;
+  for(;;) {
+    /* loop for CURL_SERVER_CLOSED_CONNECTION */
 
-    /* Connect only if not already connected! */
-    result = ConnectPlease(data, conn, hostaddr, &connected);
+    if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
+      bool connected = FALSE;
 
-    if(connected) {
-      result = Curl_protocol_connect(conn, protocol_done);
-      if(CURLE_OK == result)
-        conn->bits.tcpconnect = TRUE;
-    }
-    else
-      conn->bits.tcpconnect = FALSE;
+      /* Connect only if not already connected! */
+      result = ConnectPlease(data, conn, hostaddr, &connected);
 
+      if(connected) {
+        result = Curl_protocol_connect(conn, protocol_done);
+        if(CURLE_OK == result)
+          conn->bits.tcpconnect = TRUE;
+      }
+      else
+        conn->bits.tcpconnect = FALSE;
 
-    if(CURLE_OK != result)
-      return result;
-  }
-  else {
-    Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
-    conn->bits.tcpconnect = TRUE;
-    *protocol_done = TRUE;
-    if(data->set.verbose)
-      verboseconnect(conn);
+      /* if the connection was closed by the server while exchanging
+         authentication informations, retry with the new set
+         authentication information */
+      if(conn->bits.proxy_connect_closed)
+        continue;
+
+      if(CURLE_OK != result)
+        return result;
+    }
+    else {
+      Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
+      conn->bits.tcpconnect = TRUE;
+      *protocol_done = TRUE;
+      if(data->set.verbose)
+        verboseconnect(conn);
+    }
+    /* Stop the loop now */
+    break;
   }
 
   conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
Index: lib/urldata.h
===================================================================
RCS file: /cvsroot/curl/curl/lib/urldata.h,v
retrieving revision 1.307
diff -u -r1.307 urldata.h
--- lib/urldata.h	2 Nov 2006 21:56:44 -0000	1.307
+++ lib/urldata.h	2 Nov 2006 22:42:57 -0000
@@ -485,8 +485,12 @@
                          when Curl_done() is called, to prevent Curl_done() to
                          get invoked twice when the multi interface is
                          used. */
-  bool stream_was_rewound; /* Indicates that the stream was rewound after a request
-                              read past the end of its response byte boundary */
+  bool stream_was_rewound; /* Indicates that the stream was rewound after a
+                              request read past the end of its response byte
+                              boundary */
+  bool proxy_connect_closed; /* set true if a proxy disconnected the
+                                connection in a CONNECT request with auth, so
+                                that libcurl should reconnect and continue. */
 };
 
 struct hostname {
