curl-library
RE: CURL loops infinitely when cable is pulled out.
Date: Sun, 22 Apr 2007 18:28:42 -0700
As requested the scenario where this failed:
The test scenario is as follows:
Start a download.
Pull the cable.
Start download again from the byte the prev download terminated.
Use CURL_RESUME_FROM option.
What I got back was an HTTP 416.
When I stepped thru the code I found the problem described below, the
range value was set correctly, but when it reached the http.c functions
the contents were invalid. I then tried to figure out where it got
deleted and it was in CURL disconnect. So all I did was reset the range
value after CURL-disconnect to be safe. I am not allowed to post
patches, but I hope this helps.
Thanks,
Sonia.
-----Original Message-----
From: Sonia Subramanian
Sent: Friday, April 20, 2007 5:53 PM
To: 'libcurl development'
Cc: Charlotte Chang; Robert Spath; Shalu Jain
Subject: RE: CURL loops infinitely when cable is pulled out.
Hi,
I tried this out with the new code and there are 2 issues I thought I
would bring up:
One issue with partial download that I fixed:
1)
This was when I tried to resume download of an already partially
downloaded file.
In the function createconnection in url.c
I had to add the following lines:
else {
/*
* This is a brand new connection, so let's store it in the
connection
* cache of ours!
*/
-> //Fix ssubrama - we have probably called Curl Disconnect
-> //Reset the entire resume from structure - to be safe.
-> data->reqdata.resume_from = data->set.set_resume_from;
-> if (data->reqdata.resume_from) {
-> if (data->reqdata.rangestringalloc == TRUE)
-> free(data->reqdata.range);
-> data->reqdata.range = aprintf("%" FORMAT_OFF_T
"-",
-> data->reqdata.resume_from);
-> if(!data->reqdata.range)
-> return CURLE_OUT_OF_MEMORY;
->
-> /* tell ourselves to fetch this range */
-> data->reqdata.use_range = TRUE; /* enable
range download */
-> data->reqdata.rangestringalloc = TRUE; /* mark
range string allocated */
-> }
-> else if (data->set.set_range) {
-> /* There is a range, but is not a resume, useful
for random ftp access */
-> data->reqdata.range = strdup(data->set.set_range);
-> if(!data->reqdata.range)
-> return CURLE_OUT_OF_MEMORY;
-> data->reqdata.rangestringalloc = TRUE; /* mark
range string allocated */
-> data->reqdata.use_range = TRUE; /* enable
range download */
-> }
-> else
-> data->reqdata.use_range = FALSE; /* disable
range download */
-> ConnectionStore(data, conn);
}
/* Continue connectdata initialization here. */
Because in
reuse = ConnectionExists(data, conn, &conn_temp); if we call
Curl_disconnect - the partial - resume from information always gets
freed and is never reinitialized. So here I am checking if allocated I
am freeing it and then copying again. After this fix it worked.
The other issue is that the infinite loop does not go away.
If select returns 0 Curl_readwrite is called again and no condition
there terminates the loop.
(transfer.c
Function
static CURLcode
Transfer(struct connectdata *conn)
{
.
.
.
switch (Curl_socket_ready(fd_read, fd_write, 1000)) {
case -1: /* select() error, stop reading */
#ifdef EINTR
/* The EINTR is not serious, and it seems you might get this more
ofen when using the lib in a multi-threaded environment! */
if(SOCKERRNO == EINTR)
;
else
#endif
done = TRUE; /* no more read or write */
continue;
case 0: /* timeout */
default: /* readable descriptors */
result = Curl_readwrite(conn, &done);
break;
}
if(result)
return result;
/* "done" signals to us if the transfer(s) are ready */
}
return CURLE_OK;
}
I am not sure about other implications and don't want to change anything
without your input.
I would appreciate your comments on the same. Also if you think that the
code is behaving as it should but the problem lies in the return values,
I would appreciate your letting us know,
Thanks,
Sonia.
-----Original Message-----
From: Sonia Subramanian
Sent: Thursday, April 19, 2007 8:47 PM
To: 'libcurl development'
Cc: Charlotte Chang; Robert Spath; Shalu Jain
Subject: RE: CURL loops infinitely when cable is pulled out.
Hi,
Thanks. I will try this out with the new code.
Thanks,
Sonia.
-----Original Message-----
From: curl-library-bounces_at_cool.haxx.se
[mailto:curl-library-bounces_at_cool.haxx.se] On Behalf Of Daniel Stenberg
Sent: Thursday, April 19, 2007 1:08 PM
To: libcurl development
Cc: Charlotte Chang; Robert Spath; Shalu Jain
Subject: RE: CURL loops infinitely when cable is pulled out.
On Thu, 19 Apr 2007, Sonia Subramanian wrote:
> 1. We don't have poll() and we probably will use select.
> 2. On this platform select returns 0 as I verified with 7.15.4
You mean when select() times out? That's pretty normal.
> 3. In the code that calls it Curl_readwrite is a value of select_res
==0
> handled?
Yes of course. timeouts are very frequent on all platforms for slow or
stalled
transfers.
> Is a select_res value of 0 valid?
Yes, it means the socket didn't turn readable within the given time
(assuming
we talk about downloads).
-- Commercial curl and libcurl Technical Support: http://haxx.se/curl.htmlReceived on 2007-04-23