php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74135 CURLOPT_RESOLVE don't work properly in second time curl call
Submitted: 2017-02-20 16:10 UTC Modified: 2019-03-26 14:49 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:0 (0.0%)
From: icez at icez dot net Assigned:
Status: Not a bug Package: cURL related
PHP Version: 7.0.16 OS: Linux Debian Jessie
Private report: No CVE-ID: None
 [2017-02-20 16:10 UTC] icez at icez dot net
Description:
------------
I have the code that call several servers behind the load balancer to check for the page load result. The server was configured with SSL so I need the way to force curl to connect to specific IP address with the correct hostname without having to set SSL_VERIFYHOST to false and found curl option CURLOPT_RESOLVE. I've tested that curl command line can use this option to force connect to specific server IP address, but when I run the test script in PHP it always connect to first server. which is the first address to have this option set to.

related question: http://stackoverflow.com/questions/36434049/php-curl-curlopt-resolve-not-working

Test script:
---------------
$servers = [ '192.0.2.1', '192.0.2.2', '192.0.2.3' ];

foreach ($servers as $server) {

$ch = curl_init();

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 0);
curl_setopt($ch, CURLOPT_RESOLVE, $resolveparam);
curl_setopt($ch, CURLOPT_URL, "https://example.com/some/path");
curl_setopt($ch, CURLOPT_VERBOSE, 1);

$result = curl_exec($ch);
$info = curl_getinfo($ch);

echo $info['primary_ip']."\n";
curl_close($ch);
}


Expected result:
----------------
192.0.2.1
192.0.2.2
192.0.2.3

Actual result:
--------------
192.0.2.1
192.0.2.1
192.0.2.1

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-02-20 16:13 UTC] icez at icez dot net
sorry, missing one line in the test script:

Here's the correct one:
-------------------

$servers = [ '192.0.2.1', '192.0.2.2', '192.0.2.3' ];

foreach ($servers as $server) {

$resolveparam = [ 'example.com:443:'.$server ];

$ch = curl_init();

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 0);
curl_setopt($ch, CURLOPT_RESOLVE, $resolveparam);
curl_setopt($ch, CURLOPT_URL, "https://example.com/some/path");
curl_setopt($ch, CURLOPT_VERBOSE, 1);

$result = curl_exec($ch);
$info = curl_getinfo($ch);

echo $info['primary_ip']."\n";
curl_close($ch);
}
 [2017-03-01 16:37 UTC] andrew dot nester dot dev at gmail dot com
It's a bit tricky but isn't related to PHP Curl lib.
According to libcurl documentation (https://curl.haxx.se/libcurl/c/CURLOPT_RESOLVE.html) 

"Remove names from the DNS cache again, to stop providing these fake resolves, by including a string in the linked list that uses the format "-HOST:PORT". The host name must be prefixed with a dash, and the host name and port number must exactly match what was already added previously."

so you can use something as following to perform what you want:

$resolveparam = [ $prev_server ? '-example.com:443:'.$prev_server : '', 'example.com:443:'.$server ];
    $prev_server = $server;
 [2019-03-26 14:49 UTC] mike@php.net
-Status: Open +Status: Not a bug
 [2019-03-26 14:49 UTC] mike@php.net
Cannot reproduce either.

* Added example.com:443:192.0.2.1 to DNS cache
* Hostname example.com was found in DNS cache
*   Trying 192.0.2.1...
* TCP_NODELAY set
* Connection timed out after 1001 milliseconds
* Closing connection 0

* Added example.com:443:192.0.2.2 to DNS cache
* Hostname example.com was found in DNS cache
*   Trying 192.0.2.2...
* TCP_NODELAY set
* Connection timed out after 1001 milliseconds
* Closing connection 0

* Added example.com:443:192.0.2.3 to DNS cache
* Hostname example.com was found in DNS cache
*   Trying 192.0.2.3...
* TCP_NODELAY set
* Connection timed out after 1001 milliseconds
* Closing connection 0
 [2021-07-21 16:04 UTC] maxfomichev at manychat dot com
That was fixed in curl 7.61
https://github.com/curl/curl/pull/2622

but don't work in older versions.

Ondrej ppa for ubuntu still has old one.

Workaround is trivial:

CURLOPT_RESOLVE => ['-manychat.com:80', 'manychat.com:80:18.185.191.84']


will clear previous value if any and provide the new one.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 18 17:01:28 2024 UTC