[英]How to manually resolve hosts in HTTP(S) connections in PHP
Curl具有手動指定要將主機解析到的IP的功能。 例如:
curl https://www.google.com --resolve "www.google.com:443:173.194.72.112"
這在使用HTTPS時特別有用。 如果它只是一個HTTP請求,我可以通過直接指定IP地址並添加主機頭來實現相同的目的。 但是在HTTPS中會破壞連接,因為SSL證書主機將與IP地址而不是主機頭進行比較。
我的問題是,我怎樣才能在PHP中做同樣的事情?
雖然@ deceze的答案是正確的,但實際的例子可能會有用。 我需要CURLOPT_RESOLVE
因為我試圖使用額外的Host: www.example.com
標頭直接連接到IP地址,但由於服務器使用的是SNI,因此無效。
我使用CURLOPT_RESOLVE
來解決我的問題。 此代碼允許我使用我選擇的IP地址連接到SNI服務器:
$resolve = array(sprintf(
"%s:%d:%s",
$hostname,
$port,
$host_ip
));
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RESOLVE, $resolve);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
即使這是一個老問題值得注意的是,當使用CURLOPT_RESOLVE
選項將CURL用於多個服務器CURLOPT_RESOLVE
,需要在再次使用CURL之前清除DNS緩存,否則CURL將指向第一個服務器而不管curl_setopt($ch, CURLOPT_RESOLVE, $resolve);
設置。
實現此功能的唯一方法是在$resolve
數組中添加一個解析字符串,其中最后一個服務器使用前綴為“ - ”:
$servers = [ '192.0.2.1', '192.0.2.2', '192.0.2.3' ];
foreach ($servers as $idx => $server) {
$resolve = [];
// Remove the last server used from the DNS cache
if($idx){
$last_server = $server[$idx-1];
$resolve[] = "-example.com:443:{$last_server}";
}
// resolve the new server
$resolve[] = "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, $resolve);
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);
}
正如此處所指出: https : //bugs.php.net/bug.php?id = 74135
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.