cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Is it normal to the progress callback be called once again after returning non-zero value?

From: Ray Satiro <raysatiro_at_yahoo.com>
Date: Wed, 11 Jun 2014 15:09:26 -0400

On 6/11/2014 3:14 AM, Ray Satiro wrote:
> On 6/10/2014 5:34 PM, Daniel Stenberg wrote:
>> On Mon, 9 Jun 2014, Ray Satiro wrote:
>>
>>> - res = Curl_done(&data->easy_conn, CURLE_OK, FALSE);
>>> + res = Curl_done(&data->easy_conn, data->result, FALSE);
>>
>> Ah yes, that's indeed a suitable change. Thanks!
>>
>>> After that change the progress callback is not called a final time
>>> after CURLE_ABORTED_BY_CALLBACK.
>>
>> For any error really, not only CURLE_ABORTED_BY_CALLBACK.
>>
>> But it relies on the protocol handler's done function to handle it. I
>> would like to add a little extra precaution:
>>
>> --- a/lib/url.c
>> +++ b/lib/url.c
>> @@ -5806,11 +5806,11 @@ CURLcode Curl_done(struct connectdata **connp,
>>
>> /* this calls the protocol-specific function pointer previously
>> set */
>> if(conn->handler->done)
>> result = conn->handler->done(conn, status, premature);
>> else
>> - result = CURLE_OK;
>> + result = status;
>>
>> if(Curl_pgrsDone(conn) && !result)
>> result = CURLE_ABORTED_BY_CALLBACK;
>>
>> /* if the transfer was completed in a paused state there can be
>> buffered
>>
>> ... for the case where there is no done function for the protocol.
>>
>
> Ok but I notice your other change is missing now. The behavior doesn't
> change unless your first change is applied as well:
>
> url.c Curl_done() line 5808-5816
> ----------
> if(conn->handler->done)
> result = conn->handler->done(conn, status, premature);
> else
> - result = CURLE_OK;
> + result = status;
>
> - if(Curl_pgrsDone(conn) && !result)
> + if((status != CURLE_ABORTED_BY_CALLBACK) && Curl_pgrsDone(conn) &&
> !result)
> result = CURLE_ABORTED_BY_CALLBACK;
>
> /* if the transfer was completed in a paused state there can be
> buffered
> ----------
>

Also I wonder do you need to evaluate the result as well as status now
(or instead of status?) in the case were there is a done function for
the protocol and result receives CURLE_ABORTED_BY_CALLBACK? Either one
works in the repro case since the HTTP done handler returns the status
but do you need both? If a done handler is passed a status of
CURLE_ABORTED_BY_CALLBACK is it acceptable to return something
different? If so it seems to me you'd need to check both result and
status to keep pgrsDone from being called. For example is this needed to
ignore all cases where aborted by callback:

   if((status != CURLE_ABORTED_BY_CALLBACK)
       && (result != CURLE_ABORTED_BY_CALLBACK)
       && Curl_pgrsDone(conn) && !result) {
     result = CURLE_ABORTED_BY_CALLBACK;
   }

I've attached a simple example without the libuv stuff by modifying curl
example simple.c, should be easier to work with.

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html

Received on 2014-06-11