views:

819

answers:

4

I'm using PHP CURL to send a request to a server. What do I need to do so the response from server will include that server's IP address?

A: 

AFAIK you can not 'force' the server to send you his IP address in the response. Why not look it up directly? (Check this question/answers for how to do that from php)

Henrik Opel
the server consists of multiple running instances, so I need to find out exactly which server I connected to and responded for a particular CURL request.
+1  A: 

Hi,

I don't think there is a way to get that IP address directly from curl.
But something like this could do the trick :

First, do the curl request, and use curl_getinfo to get the "real" URL that has been fetched -- this is because the first URL can redirect to another one, and you want the final one :

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.google.com/");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($ch);
$real_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
curl_close($ch);
var_dump($real_url);    // http://www.google.fr/

Then, use parse_url to extract the "host" part from that final URL :

$host = parse_url($real_url, PHP_URL_HOST);
var_dump($host);        // www.google.fr

And, finally, use gethostbyname to get the IP address that correspond to that host :

$ip = gethostbyname($host);
var_dump($ip);          // 209.85.227.99

Well...
That's a solution ^^ It should work in most cases, I suppose -- though I'm not sure you would always get the "correct" result if there is some kind of load-balancing mecanism...

Pascal MARTIN
A: 
echo '<pre>';
print_r(gethostbynamel($host));
echo '</pre>';

That will give you all the IP addresses associated with the given host name.

Alix Axel
+2  A: 

This can be done with curl, with the advantage of having no other network traffic besides the curl request/response. DNS requests are made by curl to get the ip addresses, which can be found in the verbose report. So:

  • Turn on CURLOPT_VERBOSE.
  • Direct CURLOPT_STDERR to a "php://temp" stream wrapper resource.
  • Using *preg_match_all()*, parse the resource's string content for the ip address(es).
  • The responding server addresses will be in the match array's zero-key subarray.
  • The address of the server delivering the content (assuming a successful request) can be retrieved with end(). Any intervening servers' addresses will also be in the subarray, in order.

Demo:

$url = 'http://google.com';
$wrapper = fopen('php://temp', 'r+');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, $wrapper);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
$ips = get_curl_remote_ips($wrapper);
fclose($wrapper);

echo end($ips);  // 208.69.36.231

function get_curl_remote_ips($fp) 
{
    rewind($fp);
    $str = fread($fp, 8192);
    $regex = '/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/';
    if (preg_match_all($regex, $str, $matches)) {
        return array_unique($matches[0]);  // Array([0] => 74.125.45.100 [2] => 208.69.36.231)
    } else {
        return false;
    }
}
GZipp