Writing and Reading from a socket a second time - php

I connect to the whois server and am able to retrieve the availability of a domain name.
Somehow I am not able to get a response back using the same connection when I do a request of a different domain name.
<?php
$context = stream_context_create();
if($fp = stream_socket_client("tcp://whois.eu:43", $errno, $errstr, 30, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $context)) {
stream_set_timeout($fp, 30);
$domains = array('test.eu','amaai.eu');
foreach($domains as $domain) {
fwrite($fp, $domain."\r\n");
$contents = '';
while (!feof($fp)) {
$contents .= fread($fp, 8192);
}
echo $domain.": ".$contents;
}
fclose($fp);
}
What am I missing?
I really want to use the same connection.

The WHOIS protocol only supports one query. The server closes the connection after sending a response. You need to reconnect for each query.

Related

Getting certificate from smtp in php

I have a php function that can get the certificate from https-connections, is it possible to extend it to also be able to use on smtp-starttls?
Can I open it as a "tcp://", and after sending the "STARTTLS" command, switch it to a "ssl://"?
function ssl_fetch_cert($domain, $port = 443)
{
$url = "ssl://{$domain}:{$port}";
$connection_context_option['ssl']['capture_peer_cert'] = TRUE;
$connection_context = stream_context_create($connection_context_option);
$connection_client = stream_socket_client($url, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $connection_context);
$connection_info = stream_context_get_params($connection_client);
// $sha256 = openssl_x509_fingerprint($connection_info['options']['ssl']['peer_certificate'], 'sha256');
return $connection_info['options']['ssl']['peer_certificate'];
}
the function stream_socket_enable_crypto() was useful.
$url = "tcp://{$domain}:{$port}";
$connection_client = stream_socket_client($url, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $connection_context);
// timeout fread after 2s
stream_set_timeout($connection_client, 2);
// let the server introduce it self before sending command
fread($connection_client, 10240);
// send STARTTLS command
fwrite($connection_client, "STARTTLS\n");
// wait for server to say its ready, before switching
fread($connection_client, 10240);
// Switching to SSL/TLS
stream_socket_enable_crypto($connection_client, TRUE, STREAM_CRYPTO_METHOD_SSLv23_CLIENT);
https://github.com/puggan/tlsa_validation_php/blob/master/functions.php#L111

reading from external https path by php

I want to read some phrases from an external website which protocol is https.
I've do this for websites with http protocol by this code:
$homepage = file_get_contents('https://www.examlple.com/');
echo $homepage;
but it does not work for https sites. then I used this one:
$fp = fsockopen("https://www.example.com/", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
fwrite($fp, "Data sent by socket");
$content = "";
while (!feof($fp)) { //This looped forever
$content .= fread($fp, 1024);
}
fclose($fp);
echo $content;
}
but I always get an error:
Unable to find the socket transport "http" - did you forget to enable
it when you configured PHP? (2)
actualy the case is to fetch my site's statistics from analytics.
Fsockopen does not know about "http, https". Please remove the http part from your domain and use SSL Port for connection.
See example, this should work:
// open ssl connection - dont add "http or https!"
$host = "ssl://" . "example.com";
$port = 443;
$fp = fsockopen($host,$port);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
fwrite($fp, "Data sent by socket");
$content = "";
while (!feof($fp)) { //This looped forever
$content .= fread($fp, 1024);
}
fclose($fp);
echo $content;
}

Use fsockopen with proxy

I have a simple whois script
if($conn = fsockopen ($whois_server, 43)) {
fputs($conn, $domain."\r\n");
while(!feof($conn)) {
$output .= fgets($conn, 128);
}
fclose($conn);
return $output;
}
$whois_server = whois.afilias.info; //whois server for info domains
but I want to run in through proxy. So I need to connect to proxy -> then connect to whois server -> and then make the request. Something like this?
$fp = fsockopen($ip,$port);
fputs($fp, "CONNECT $whois_server:43\r\n $domain\r\n");
But it doesn't work, I don't know if i'm making the second connection right.
Sending your request to the proxy should do what you like:
<?php
$proxy = "1.2.3.4"; // proxy
$port = 8080; // proxy port
$fp = fsockopen($proxy,$port); // connect to proxy
fputs($fp, "CONNECT $whois_server:43\r\n $domain\r\n");
$data="";
while (!feof($fp)) $data.=fgets($fp,1024);
fclose($fp);
var_dump($data);
?>
Rather than doing that I would recommend you using CURL in combination with:
curl_setopt($ch, CURLOPT_PROXY, 1.2.3.4);

Can I open socket in PHP from a specific IP (if the machine has two IPs)?

I'm using PHPMailer and it uses fsockopen to access the SMTP server.
But the machine has two IPs with different reverse DNS records. So in email headers I got the following:
Received: from one-server.tld (HELO another-server.tld) ...
I need to hide one-server.tld in favor of another-server.tld. But I need both IPs with their current RDNS settings.
I think its not possible using fsockopen. But its possible in curl, fopen and stream functions. What you need is stream_socket_client() function.
Here are some ways to achieve it.
Using context parameters which can be used in fopen function family and stream function family. See the example.
$opts = array(
'socket' => array(
'bindto' => '192.168.0.100:0',
),
);
// create the context...
$context = stream_context_create($opts);
$contents = fopen('http://www.example.com', 'r', false, $context);
Also stream_socket_client
$fp = stream_socket_client("tcp://www.example.com:80", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $opts);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
fwrite($fp, "GET / HTTP/1.0\r\nHost: www.example.com\r\nAccept: */*\r\n\r\n");
while (!feof($fp)) {
echo fgets($fp, 1024);
}
fclose($fp);
}
Using socket_bind. PHP.NET got a simple example here.

Prevent timeout in PHP

I am working on a PHP script that makes an API call to a external site. However, if this site is not available or the request times out, I would like my function to return false.
I have found following, but I am not sure on how to implement it on my script, since i use "file_get_contents" to retrieve the content of the external file call.
Limit execution time of an function or command PHP
$fp = fsockopen("www.example.com", 80);
if (!$fp) {
echo "Unable to open\n";
} else {
fwrite($fp, "GET / HTTP/1.0\r\n\r\n");
stream_set_timeout($fp, 2);
$res = fread($fp, 2000);
$info = stream_get_meta_data($fp);
fclose($fp);
if ($info['timed_out']) {
echo 'Connection timed out!';
} else {
echo $res;
}
}
(From: http://php.net/manual/en/function.stream-set-timeout.php)
How would you adress such an issue? Thanks!
I'd recommend using the cURL family of PHP functions. You can then set the timeout using curl_setopt():
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,2); // two second timeout
This will cause the curl_exec() function to return FALSE after the timeout.
In general, using cURL is better than any of the file reading functions; it's more dependable, has more options and is not regarded as a security threat. Many sysadmins disable remote file reading, so using cURL will make your code more portable and secure.
<?php
$fp = fsockopen("www.example.com", 80);
if (!$fp) {
echo "Unable to open\n";
} else {
stream_set_timeout($fp, 2); // STREAM RESOURCE, NUMBER OF SECONDS TILL TIMEOUT
// GET YOUR FILE CONTENTS
}
?>
From the PHP manual for File_Get_Contents (comments):
<?php
$ctx = stream_context_create(array(
'http' => array(
'timeout' => 1
)
)
);
file_get_contents("http://example.com/", 0, $ctx);
?>
<?php
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 4);
if ($fp) {
stream_set_timeout($fp, 2);
}

Categories