diff -ur old/lib/http.c new/lib/http.c --- old/lib/http.c 2006-10-18 00:32:56.000000000 +0200 +++ new/lib/http.c 2006-11-03 07:08:11.071955200 +0100 @@ -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; } diff -ur old/lib/url.c new/lib/url.c --- old/lib/url.c 2006-10-29 23:46:28.000000000 +0100 +++ new/lib/url.c 2006-11-07 07:30:43.609323200 +0100 @@ -2372,7 +2372,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 */ @@ -3920,30 +3921,47 @@ 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) + { + /* Reset Error-Buffer */ + if (data->set.errorbuffer) + data->set.errorbuffer[0] = '\0'; + data->state.errorbuf = FALSE; + 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 diff -ur old/lib/urldata.h new/lib/urldata.h --- old/lib/urldata.h 2006-10-23 23:34:56.000000000 +0200 +++ new/lib/urldata.h 2006-11-03 07:08:57.388555200 +0100 @@ -463,8 +463,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 {