diff -ur org/include/curl/curl.h neu/include/curl/curl.h --- org/include/curl/curl.h 2006-10-21 14:32:08.000000000 +0200 +++ neu/include/curl/curl.h 2006-11-02 21:56:05.427222400 +0100 @@ -392,6 +392,10 @@ CURLOPT_CONV_FROM_UTF8_FUNCTION */ CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing or wrong format */ + CURLE_SERVER_CLOSED_CONNECTION,/* 78 - On HTTP-Proxy connection, the server + closed the connection while doing the + Authentication dialog. Reconnect with + new Authentication information */ CURL_LAST /* never use! */ } CURLcode; diff -ur org/lib/http.c neu/lib/http.c --- org/lib/http.c 2006-10-18 00:32:56.000000000 +0200 +++ neu/lib/http.c 2006-11-02 22:34:01.279737600 +0100 @@ -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 @@ -1310,6 +1311,10 @@ cl = curlx_strtoofft(line_start + strlen("Content-Length:"), NULL, 10); } + else if(checkprefix("Connection:", line_start)) { + if (strstr(line_start + strlen("Connection:"), "close") != NULL) + closeConnection = TRUE; + } else if(2 == sscanf(line_start, "HTTP/1.%d %d", &subversion, &k->httpcode)) { @@ -1336,12 +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); - return CURLE_RECV_ERROR; + if (closeConnection && data->reqdata.newurl) + return CURLE_SERVER_CLOSED_CONNECTION; + else + return CURLE_RECV_ERROR; } /* If a proxy-authorization header was used for the proxy, then we should diff -ur org/lib/url.c neu/lib/url.c --- org/lib/url.c 2006-10-29 23:46:28.000000000 +0100 +++ neu/lib/url.c 2006-11-02 22:11:31.769236800 +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,32 +3921,43 @@ 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(connected) { - result = Curl_protocol_connect(conn, protocol_done); - if(CURLE_OK == result) - conn->bits.tcpconnect = TRUE; - } - else - conn->bits.tcpconnect = FALSE; + if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) { + bool connected = 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 the connection was closed by the server while exchanging + authentication informations, retry with the new set + authentication information */ + if(CURLE_SERVER_CLOSED_CONNECTION == result) + 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); + 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 set this here perhaps a second time */