cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Multi cURL connect bug

From: Keyur Govande <keyurgovande_at_gmail.com>
Date: Mon, 8 Jul 2013 14:14:05 -0400

On Mon, Jul 8, 2013 at 1:47 PM, Dave Reisner <d_at_falconindy.com> wrote:
> On Mon, Jul 08, 2013 at 12:41:35PM -0400, Keyur Govande wrote:
>> On Mon, Jul 8, 2013 at 2:44 AM, Yehezkel Horowitz
>> <horowity_at_checkpoint.com> wrote:
>> >
>> > > The goal of this email was to know if there's a way to distinguish these 2 cases, so a.php can make the appropriate decision.
>> >
>> > Are you looking for something like curl_multi_info_read ?
>> >
>> > You can combine it with curl_multi_wait in order to easily handle all the async operations.
>> >
>>
>> Sorry, not sure I understand.
>>
>> Neither of those scenarios is an error, so curl_multi_info_read()
>> returns NULL when called right after curl_multi_exec() as show below:
>>
>> $mc_handle = curl_multi_init();
>> $c = curl_init();
>> // Set up the handle and options
>> curl_multi_add_handle($mc_handle, $c);
>> do {
>> $cme = curl_multi_exec($mc_handle, $remain);
>> } while ($cme == CURLM_CALL_MULTI_PERFORM);
>> $rc = curl_multi_info_read($mc_handle); // This returns FALSE i.e.
>> NULL from the C library both when the connection was successful and
>> when it is still waiting.
>>
>>
>> > > We're currently using the 7.19.7 version of libcurl.
>> >
>> > This is quite old, and you’ll not be able to use curl_multi_wait (added in 7.28.0), but I see you are using curl_multi_select which probably do the job for you.
>> >
>> >
>>
>> Neither curl_multi_wait() nor the 'older' function curl_multi_fdset()
>> exposes whether the internal file descriptor is ready for writes
>> (indicating a successful connection).
>>
>
> Seems to me that what you're doing isn't asynchronous at all. You're
> using a single thread and the only behavior that *might* be categorized
> as asynchronous is your attempt at this guessing game to allow some
> local work to be done before attempting to read the response from the
> server. I feel you've created a solution in search of a problem.
>
> Daniel's earlier comment about your need to not know the internal state
> of the transfer is spot on. If you want to do this asynchronously, then
> really do it asynchronously. Spin off a separate thread to do the
> transfer and join it when you're ready for the response.
>
> Cheers,
> Dave
>

I respectfully disagree. Asynchronous RPC without using a separate
thread is not that uncommon and is definitely not wrong. In C land
this would perfectly reasonable to do:
open a non-blocking socket()
connect() with timeout. If successful {
    loop over write() until finished
   // do other stuff
   poll() on fd with timeout
   read() from fd
}
close()
// do more stuff

The application I'm trying to do this in is PHP, so a separate thread
is not an option.

You're right though that without knowing the internal curl state, when
connecting to localhost, we are *assuming* that the request was fully
sent over when curl_multi_perform() returns CURLM_OK. If the curl
library was changed in future, this assumption will break. The only
correct option is to not use curl and do this "manually" with PHP
streams.

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2013-07-08