1
0
mirror of https://github.com/moparisthebest/curl synced 2024-08-13 17:03:50 -04:00

Robson Braga Araujo reported bug #1618359

(http://curl.haxx.se/bug/view.cgi?id=1618359) and subsequently provided a
patch for it: when downloading 2 zero byte files in a row, curl 7.16.0
enters an infinite loop, while curl 7.16.1-20061218 does one additional
unnecessary request.

Fix: During the "Major overhaul introducing http pipelining support and
shared connection cache within the multi handle." change, headerbytecount
was moved to live in the Curl_transfer_keeper structure. But that structure
is reset in the Transfer method, losing the information that we had about
the header size. This patch moves it back to the connectdata struct.
This commit is contained in:
Daniel Stenberg 2006-12-21 10:15:38 +00:00
parent 439b84c782
commit 89ab5f4380
7 changed files with 34 additions and 18 deletions

13
CHANGES
View File

@ -6,6 +6,19 @@
Changelog Changelog
Daniel (21 December 2006)
- Robson Braga Araujo reported bug #1618359
(http://curl.haxx.se/bug/view.cgi?id=1618359) and subsequently provided a
patch for it: when downloading 2 zero byte files in a row, curl 7.16.0
enters an infinite loop, while curl 7.16.1-20061218 does one additional
unnecessary request.
Fix: During the "Major overhaul introducing http pipelining support and
shared connection cache within the multi handle." change, headerbytecount
was moved to live in the Curl_transfer_keeper structure. But that structure
is reset in the Transfer method, losing the information that we had about
the header size. This patch moves it back to the connectdata struct.
Daniel (16 December 2006) Daniel (16 December 2006)
- Brendan Jurd provided a fix that now prevents libcurl from getting a SIGPIPE - Brendan Jurd provided a fix that now prevents libcurl from getting a SIGPIPE
during certain conditions when GnuTLS is used. during certain conditions when GnuTLS is used.

View File

@ -36,6 +36,7 @@ This release includes the following bugfixes:
o getting FTP response code errors when using the multi-interface caused o getting FTP response code errors when using the multi-interface caused
libcurl to leak memory libcurl to leak memory
o no more SIGPIPE when GnuTLS is used o no more SIGPIPE when GnuTLS is used
o FTP downloading 2 zero byte files in a row
Other curl-related news: Other curl-related news:
@ -54,6 +55,7 @@ advice from friends like these:
James Housley, Olaf Stueben, Yang Tse, Gisle Vanem, Bradford Bruce, James Housley, Olaf Stueben, Yang Tse, Gisle Vanem, Bradford Bruce,
Ciprian Badescu, Dmitriy Sergeyev, Nir Soffer, Venkat Akella, Toon Verwaest, Ciprian Badescu, Dmitriy Sergeyev, Nir Soffer, Venkat Akella, Toon Verwaest,
Matt Witherspoon, Alexey Simak, Martin Skinner, Sh Diao, Jared Lundell, Matt Witherspoon, Alexey Simak, Martin Skinner, Sh Diao, Jared Lundell,
Stefan Krause, Sebastien Willemijns, Alexey Simak, Brendan Jurd Stefan Krause, Sebastien Willemijns, Alexey Simak, Brendan Jurd,
Robson Braga Araujo
Thanks! (and sorry if I forgot to mention someone) Thanks! (and sorry if I forgot to mention someone)

View File

@ -329,7 +329,7 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
* line */ * line */
int i; int i;
k->headerbytecount += gotbytes; conn->headerbytecount += gotbytes;
ftpc->nread_resp += gotbytes; ftpc->nread_resp += gotbytes;
for(i = 0; i < gotbytes; ptr++, i++) { for(i = 0; i < gotbytes; ptr++, i++) {
@ -562,7 +562,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
* line */ * line */
int i; int i;
k->headerbytecount += gotbytes; conn->headerbytecount += gotbytes;
*nreadp += gotbytes; *nreadp += gotbytes;
for(i = 0; i < gotbytes; ptr++, i++) { for(i = 0; i < gotbytes; ptr++, i++) {

View File

@ -1527,8 +1527,8 @@ CURLcode Curl_http_done(struct connectdata *conn,
if(!conn->bits.retry && if(!conn->bits.retry &&
((http->readbytecount + ((http->readbytecount +
k->headerbytecount - conn->headerbytecount -
k->deductheadercount)) <= 0) { conn->deductheadercount)) <= 0) {
/* If this connection isn't simply closed to be retried, AND nothing was /* If this connection isn't simply closed to be retried, AND nothing was
read from the HTTP server (that counts), this can't be right so we read from the HTTP server (that counts), this can't be right so we
return an error here */ return an error here */

View File

@ -581,10 +581,10 @@ CURLcode Curl_readwrite(struct connectdata *conn,
return result; return result;
data->info.header_size += (long)headerlen; data->info.header_size += (long)headerlen;
k->headerbytecount += (long)headerlen; conn->headerbytecount += (long)headerlen;
k->deductheadercount = conn->deductheadercount =
(100 == k->httpcode)?k->headerbytecount:0; (100 == k->httpcode)?conn->headerbytecount:0;
if (data->reqdata.resume_from && if (data->reqdata.resume_from &&
(data->set.httpreq==HTTPREQ_GET) && (data->set.httpreq==HTTPREQ_GET) &&
@ -1040,7 +1040,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
return result; return result;
data->info.header_size += (long)k->hbuflen; data->info.header_size += (long)k->hbuflen;
k->headerbytecount += (long)k->hbuflen; conn->headerbytecount += (long)k->hbuflen;
/* reset hbufp pointer && hbuflen */ /* reset hbufp pointer && hbuflen */
k->hbufp = data->state.headerbuff; k->hbufp = data->state.headerbuff;
@ -1564,7 +1564,6 @@ CURLcode Curl_readwrite_init(struct connectdata *conn)
k->writebytecountp = data->reqdata.writebytecountp; k->writebytecountp = data->reqdata.writebytecountp;
k->bytecount = 0; k->bytecount = 0;
k->headerbytecount = 0;
k->buf = data->state.buffer; k->buf = data->state.buffer;
k->uploadbuf = data->state.uploadbuffer; k->uploadbuf = data->state.uploadbuffer;
@ -2247,7 +2246,7 @@ bool Curl_retry_request(struct connectdata *conn,
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
struct Curl_transfer_keeper *k = &data->reqdata.keep; struct Curl_transfer_keeper *k = &data->reqdata.keep;
if((data->reqdata.keep.bytecount+k->headerbytecount == 0) && if((data->reqdata.keep.bytecount+conn->headerbytecount == 0) &&
conn->bits.reuse && conn->bits.reuse &&
!conn->bits.no_body) { !conn->bits.no_body) {
/* We got no data, we attempted to re-use a connection and yet we want a /* We got no data, we attempted to re-use a connection and yet we want a

View File

@ -3964,6 +3964,8 @@ static CURLcode SetupConnection(struct connectdata *conn,
} }
} }
conn->headerbytecount = 0;
#ifdef CURL_DO_LINEEND_CONV #ifdef CURL_DO_LINEEND_CONV
data->state.crlf_conversions = 0; /* reset CRLF conversion counter */ data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
#endif /* CURL_DO_LINEEND_CONV */ #endif /* CURL_DO_LINEEND_CONV */

View File

@ -534,13 +534,6 @@ struct Curl_transfer_keeper {
curl_off_t bytecount; /* total number of bytes read */ curl_off_t bytecount; /* total number of bytes read */
curl_off_t writebytecount; /* number of bytes written */ curl_off_t writebytecount; /* number of bytes written */
long headerbytecount; /* only count received headers */
long deductheadercount; /* this amount of bytes doesn't count when we check
if anything has been transfered at the end of
a connection. We use this counter to make only
a 100 reply (without a following second response
code) result in a CURLE_GOT_NOTHING error code */
struct timeval start; /* transfer started at this time */ struct timeval start; /* transfer started at this time */
struct timeval now; /* current time */ struct timeval now; /* current time */
bool header; /* incoming data has HTTP header */ bool header; /* incoming data has HTTP header */
@ -742,6 +735,13 @@ struct connectdata {
unsigned short remote_port; /* what remote port to connect to, unsigned short remote_port; /* what remote port to connect to,
not the proxy port! */ not the proxy port! */
long headerbytecount; /* only count received headers */
long deductheadercount; /* this amount of bytes doesn't count when we check
if anything has been transfered at the end of
a connection. We use this counter to make only
a 100 reply (without a following second response
code) result in a CURLE_GOT_NOTHING error code */
char *user; /* user name string, allocated */ char *user; /* user name string, allocated */
char *passwd; /* password string, allocated */ char *passwd; /* password string, allocated */