How to debug curl with CURLOPT_STDERR and CURLOPT_VERBOSE
Step 1, enable verbose mode in curl
curl_setopt($ch, CURLOPT_VERBOSE, true);
If the problem is connection timeout, you may also need to set the timeout, because a connection timeout can be up to 60 seconds, you don't want to wait so long to see the verbose information. Usually 5 or 10 seconds will be enough,
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
Then we need to open a file and set the file handle as the error ouput stream of curl
Step 2, read from verbose file
Here is the tricky part which cost me a lot time to figure it out. If you read file directly with file_get_contents, you will get an empty string, even the file do recoreded the verbose information.
Even you close the file handle or close curl handle and then read it
But you can read the file after the function that create and use the curl instance returns. This is baffling me.
Turns out the problem is rewind
Sets the file position indicator for handle to the beginning of the file stream.
But its so easy to forget it, seems curl won't do any clean up after using the file handle, the result is the file position of the handle is at the end of the file. This explains why I always get an empty string.
Add this line before you try to read the contents of the file
Why close the file handle don't work? I guess before the file handle is garbage collected by PHP, you always using the same file handle, maybe a cached one. And the function returning can completely destroy file handle resources. When you call file_get_contents, it reopen the file and the file position is correct.
* Trying 200:2:f3b9:bb27::... * Failed to connect to 200:2:f3b9:bb27::: Network is unreachable
The reason of network is unreachable can be the curl tries to use IPv6 even though it is not configured properly (the IPv6 network is unreachable) and does not retry with IPv4 after a failure. Or the IPv6 stack is configured but is not working (cannot be used to transmit/receive data). As a result, cURL fails when trying to connect via IPv6.
The firewall configuration on the server that running curl may have been configured in a way that your host unable to reach the some servers. Mostly about IPV6 misconfiguration.
Solution 1. Set CURLOPT_IPRESOLVE to CURL_IPRESOLVE_V4.
curl_setopt( $ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
The CURLOPT_IPRESOLVE and associated constants are only defined in PHP 5.3 and newer.
Define the constants manually won't work, PHP will ignore it
The CURLOPT_IPRESOLVE option allows an application to select what kind of IP addresses to use when resolving host names. This is only interesting when using host names that resolve addresses using more than one version of IP. The allowed values are:
Default, resolves addresses to all IP versions that your system allows.
Resolve to IPv4 addresses.
Resolve to IPv6 addresses.
You can not use this option if the PHP version less than 5.3. Otherwise you get an error
Warning: curl_setopt() [function.curl-setopt]: Invalid curl configuration option
NSS error - 8092
This error code SEC_ERROR_KEYGEN_FAIL: -8092 means unable to generate public-private key pair.