php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78404 Curl Multi Handle: curl_error($ch) returns no error string
Submitted: 2019-08-12 08:52 UTC Modified: 2019-08-13 13:00 UTC
From: sa dot su dot technic at gmail dot com Assigned: nikic (profile)
Status: Closed Package: cURL related
PHP Version: 7.3.8 OS: Debian 8
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: sa dot su dot technic at gmail dot com
New email:
PHP Version: OS:

 

 [2019-08-12 08:52 UTC] sa dot su dot technic at gmail dot com
Description:
------------
As always in previous php versions there is no returned error string by calling "curl_error($foo)" (e.g. "Port number out of range") when executing curl multi handle.

Test script:
---------------
$ch1 = curl_init();
$ch2 = curl_init();
curl_setopt($ch1, CURLOPT_URL, "Foobar://127.0.0.1:777/foobar");
curl_setopt($ch2, CURLOPT_URL, "http://127.0.0.1:999999999/foobar");

$mh = curl_multi_init();
curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);
do {
    $status = curl_multi_exec($mh, $active);
    if ($active) {
        curl_multi_select($mh);
    }
} while ($active && $status == CURLM_OK);

echo curl_error($ch1) . PHP_EOL;
echo curl_error($ch2);

curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);

Expected result:
----------------
Output of "curl_error($ch1)":
Protocol "Foobar" not supported or disabled in libcurl

Output of "curl_error($ch2)":
Port number out of range



Actual result:
--------------
Output of "curl_error($ch1)":
Empty string

Output of "curl_error($ch2)":
Empty string

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-08-12 09:19 UTC] cmb@php.net
-Package: *Network Functions +Package: cURL related
 [2019-08-12 09:37 UTC] requinix@php.net
-Status: Open +Status: Feedback
 [2019-08-12 09:37 UTC] requinix@php.net
What version of cURL are you using? Because this looks like an upstream matter.

Between 7.58 and 7.64 (the two versions I have on hand) two things changed:
1. Errors during multi operations "bubble up" into the original handles
2. Port number error message was removed
https://github.com/curl/curl/commit/46e1640#diff-8fb104c402dc51bdffef05a372f32aa2L3447

I modified your example to set CURLOPT_VERBOSE and mark the two messages with 1/2. On 7.64 on Windows I get

* Expire in 0 ms for 6 (transfer 0x20d4a2f41c0)
* Expire in 0 ms for 6 (transfer 0x20d4a2f9980)
* Protocol "foobar" not supported or disabled in libcurl
* Closing connection -1
* Closing connection -1
1: Protocol "foobar" not supported or disabled in libcurl
2:

With 7.58 on Ubuntu 18.04 I get

* Protocol "Foobar" not supported or disabled in libcurl
* Closing connection -1
* Port number out of range
* Closing connection -1
1:
2:
 [2019-08-12 10:49 UTC] sa dot su dot technic at gmail dot com
-Status: Feedback +Status: Open
 [2019-08-12 10:49 UTC] sa dot su dot technic at gmail dot com
I use "curl 7.38.0 (x86_64-pc-linux-gnu) libcurl/7.38.0 OpenSSL/1.0.1t zlib/1.2.8 libidn/1.29 libssh2/1.4.3 librtmp/2.3"

There is no change to the version I used with php 7.2 and there everything works as expected.
 [2019-08-12 11:18 UTC] sa dot su dot technic at gmail dot com
Is it possible that it does not work as expected because of curl version 7.38.0 ?
I can see that the package php7.3-curl depends on "libcurl4" and I only have "libcurl3"?

I can not update that because of debian 8.
 [2019-08-12 11:59 UTC] nikic@php.net
This looks related to bug #77946.
 [2019-08-12 12:08 UTC] sa dot su dot technic at gmail dot com
But for php version 7.2.15 and previous it worked fine and outputs an error message.
So I have to accept that to be that way?
 [2019-08-13 04:54 UTC] sa dot su dot technic at gmail dot com
I am a newbie to this php bug reports.
Is it correct that a fix will be released with version 7.2.22? 
Will there be a fix for 7.3, too?

Thank you very much for your effort.
 [2019-08-13 05:09 UTC] requinix@php.net
I believe we have all the information necessary so there's nothing else you need to do. If this is a bug in PHP (seems like it) then it will be fixed when it can be identified and fixed. And yes, it should be possible to do for both PHP 7.2 and 7.3, whose next set of releases will be in about two weeks.
 [2019-08-13 05:42 UTC] sa dot su dot technic at gmail dot com
In the related bug report https://bugs.php.net/bug.php?id=77946 I can see that there is a fix commit for this bug.
But I was not able to see for which php version. Thank you!
 [2019-08-13 05:54 UTC] requinix@php.net
7.2.22 and 7.3.9 - the upcoming releases. But the fix was specific to curl_multi_info_read().
 [2019-08-13 06:17 UTC] sa dot su dot technic at gmail dot com
Thats perfect!
Thank you and your team very much!!

I appreciate your work :-)
 [2019-08-13 08:59 UTC] nikic@php.net
I'm not sure what we should be doing here. As far as I understand, we can only get the errno information for the easy handles after calling curl_multi_info_read() -- unless I'm missing some other way? In that case, I believe that you need a) the fix for bug #77946 and b) change your code to call curl_multi_info_read() to make this work.
 [2019-08-13 09:48 UTC] requinix@php.net
So could this be a problem of mixing the Easy and Multi APIs in a way that cURL doesn't support? Or at least in a way it leaves as undefined behavior? The online docs talk about curl_multi_info_read being The Way to get the error messages:

> To get information about completed transfers, to figure out success or not and similar, curl_multi_info_read
> should be called. It can return a message about a current or previous transfer. Repeated invokes of the function
> get more messages until the message queue is empty. The information you receive there includes an easy handle
> pointer which you may use to identify which easy handle the information regards.
https://curl.haxx.se/libcurl/c/libcurl-multi.html

And accordingly,

  while ($info = curl_multi_info_read($mh)) {
    echo curl_error($info['handle']) . PHP_EOL;
  }

does produce error messages (on master).
 [2019-08-13 11:53 UTC] sa dot su dot technic at gmail dot com
For me it is sufficient to have the fix for bug #77946 and to change my code to call "curl_multi_info_read()." Thats fine.

I do not know why it worked in a previous php version.
For me, you do not need to spent anymore time on this. I am going to wait for the next version release of 7.3.0 and adapt my code.
 [2019-08-13 13:00 UTC] nikic@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: nikic
 [2019-08-13 13:00 UTC] nikic@php.net
> I do not know why it worked in a previous php version.

This used to work, because PHP handled errno + errstr inconsistently: Sometimes, the error string was available, even though the error number wasn't (like here). This was fixed to only provide the error string only if the error number is set, otherwise invalid error strings could persist in some cases. Unfortunately it broke this case :(

> For me, you do not need to spent anymore time on this. I am going to wait for the next version release of 7.3.0 and adapt my code.

In that case I'm going to close this issue, as a fix for the curl_multi_info_read() variant is already in the pipeline...
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 05 17:01:30 2024 UTC