Simple HTML DOM - Failed to open stream: Connection Timeout - php

Hello I hosted my website into a free hosting site (5gbfree.com) and I created here a function where it retrieves the Peso-dollar rate based from the site http://ppa.com.ph??q=fcer_view where it simply select the a.active element and get the value as plaintext. It was working yesterday but when I checked it our again this morning it failed to fetch. So it will return the default value which is 50.
error_log:
[09-Apr-2017 13:49:32 Asia/Manila] PHP Warning: file_get_contents(http://www.ppa.com.ph/?q=fcer_view): failed to open stream: Connection timed out in /home/rasibaseport/public_html/simple_html_dom2.php on line 75
I am using simple html DOM.
Here's the function.
include "simple_html_dom2.php";
function PPA_peso_dollar_rate(){
// Create DOM from URL or file
error_reporting(E_ALL);
ini_set("display_errors", 0);
ini_set('default_socket_timeout', 15);
$html = file_get_html("http://www.ppa.com.ph/?q=fcer_view");
$ret = 0;
if($html === false){
$ret = 50;
}else {
foreach($html->find('a[class=active]') as $e)
$ret = $e->plaintext;
$explode = explode(" ", $ret);
$ret = 50;
foreach($explode as $ex){
if(is_numeric($ex)){
$ret = $ex;
}
}
if($ret == 0) $ret = 50;
}
echo $ret;
}
Unfortunately 5gbfree disabled curl_init() function.
curl_init() has been disabled for security reasons in /home/rasibaseport/public_html/config.php on line 38
Is there any work a round here? I appreciate any help. Thank you very much.
Edit: I forgot to mention that testing this with localhost(xampp), the expected return value is correct with no errors and warnings. Works perfectly fine.
UPDATE: After trying #Rafiq's updated solution, nothing worked. It gave me similar error.
[09-Apr-2017 20:18:53 Asia/Manila] PHP Warning: file_get_contents(http://www.ppa.com.ph/?q=fcer_view): failed to open stream: Connection timed out in /home/rasibaseport/public_html/simple_html_dom2.php on line 46

Your code is work for me. Its problem in execution time. Add the following code to increase maximum execution time.
ini_set('max_execution_time', 300); //300 seconds = 5 minutes
ini_set('default_socket_timeout', 100); // 100 seconds = 1 Minutes 40 sec
//call the function file_get_html();
Explanation of parameter max_execution_time inside ini_set finction
This sets the maximum time in seconds a script is allowed to run before it is terminated by the parser. This helps prevent poorly written scripts from tying up the server. The default setting is 30. For detail read Runtime Configuration
To get rid of the following two error use fetch_http_file_contents($url) instead of file_get_contents($url) inside simple_html_dom.php on line 75.
file_get_contents(): failed to open stream: No route to host
file_get_contents(): failed to open stream: Connection timed out
function fetch_http_file_contents($url) {
$hostname = parse_url($url, PHP_URL_HOST);
if ($hostname == FALSE) {
return FALSE;
}
$host_has_ipv6 = FALSE;
$host_has_ipv4 = FALSE;
$file_response = FALSE;
$dns_records = dns_get_record($hostname, DNS_AAAA + DNS_A);
foreach ($dns_records as $dns_record) {
if (isset($dns_record['type'])) {
switch ($dns_record['type']) {
case 'AAAA':
$host_has_ipv6 = TRUE;
break;
case 'A':
$host_has_ipv4 = TRUE;
break;
} } }
if ($host_has_ipv6 === TRUE) {
$file_response = file_get_intbound_contents($url, '[0]:0');
}
if ($host_has_ipv4 === TRUE && $file_response == FALSE) {
$file_response = file_get_intbound_contents($url, '0:0');
}
return $file_response;
}
function file_get_intbound_contents($url, $bindto_addr_family) {
$stream_context = stream_context_create(
array(
'socket' => array(
'bindto' => $bindto_addr_family
),
'http' => array(
'timeout'=>20,
'method'=>'GET'
) ) );
return file_get_contents($url, FALSE, $stream_context);
}
Source Making file_get_contents() more routing-robust and dual-stack

Related

Retry if failed to open stream: HTTP request failed! 1 PHP

Im trying to open an api and extract some data and about 1/5 times the script runs it errors with a
PHP Warning: file_get_contents(http://192.168.1.52/home.cgi): failed to open stream: HTTP request failed! 1
I would like to retry opening the api on error and then follow through with the rest of the code
This is running on a Pi using PHP5
$inverterDataURL = "http://".$dataManagerIP."/home.cgi";
$context = stream_context_create(array('http'=>array('protocol_version'=>'1.1')));
$result = file_get_contents('http://192.168.1.11/home.cgi', false, $context);
20% of the time when running the script it errors trying to open the api and without the api being open i can't grab any data out of it.
the rest of the script runs through fine when it opens correctly
You should use a loop for the retry logic that breaks when the result succeeds. A do ... while loop is used here because it guarantees that it'll be run at least once (therefore guaranteeing that $result will be set to something). When the file_get_contents fails, $result will be false:
<?php
$context = stream_context_create(array('http'=>array('protocol_version'=>'1.1')));
do {
$result = file_get_contents('http://127.0.0.1/home.cgi', false, $context);
if (!$result) {
echo "Waiting 3 seconds.\n";
sleep(3);
}
} while( !$result);
If the server goes down, you'll probably want something to break the loop after a few tries. This bit will stop trying after 5 failures.
<?php
$context = stream_context_create(array('http'=>array('protocol_version'=>'1.1')));
$attempts = 0;
do {
$attempts++;
echo "Attempt $attempts\n";
$result = file_get_contents('http://127.0.0.1/home.cgi', false, $context);
if (!$result) {
echo "Attempt $attempts has failed. Waiting 3 seconds.\n";
sleep(3);
}
} while( !$result && $attempts < 5);

php raw ssh2_connection don´t return a value

What I want do
I want to create a ssh connection to a teamspeak server. With that raw connection it should be possible to put and get commands from the console.
What I´ve
$socket = #ssh2_connect($this->runtime['host'], $this->runtime['queryport']);
if($socket === false)
{
$this->addDebugLog('Error: connection failed!');
return $this->generateOutput(false, array('Error: connection failed!'), false);
}
else
{
if(#ssh2_auth_password($socket, $this->escapeText($username), $this->escapeText($password)))
{
if(($shell = #ssh2_shell($socket, "raw")) === false)
{
return $this->generateOutput(false, array('Error: failed to open a secure shell on server!'), false);
}
else
{
$this->runtime['ssh'] = $socket;
$this->runtime['socket'] = $shell;
#stream_set_timeout($this->runtime['socket'], $this->runtime['timeout']);
#stream_set_blocking($this->runtime['socket'], true);
return $this->generateOutput(true, array(), true);
}
}
else
{
return $this->generateOutput(false, array('Error: invalid loginname or password!'), false);
}
}
What´s wrong
Cause of #stream_set_blocking($this->runtime['socket'], true); this line my script is running into a timeout. Also I´ve got some the problem that fgets always return a empty result. Did I did something wrong?
Problem
I got here a timeout cause the stream waiting until it will be closed.
Solution
If I close the stream after my read and write stuff I got my answer.
#stream_set_timeout($this->stream, intval($this->runtime['timeout']));
#stream_set_blocking($this->stream, true);
echo fgets($this->stream);
echo fgets($this->stream);
fwrite($this->stream, 'quit' . "\n");
$this->runtime['socket'] = $socket;
return $this->generateOutput(true, array(), true);

stream_select timeout on newly opened socket

I use thrift php client to connect to java thrift server. But got the error of
TSocket: timed out writing 78 bytes from 10.0.1.151:1234
I dig into the php source of thrift and find it was caused from timeout on function stream_select.
/**
* Write to the socket.
*
* #param string $buf The data to write
*/
public function write($buf)
{
$null = null;
$write = array($this->handle_);
// keep writing until all the data has been written
while (TStringFuncFactory::create()->strlen($buf) > 0) {
// wait for stream to become available for writing
$writable = #stream_select($null, $write, $null, $this->sendTimeoutSec_, $this->sendTimeoutUsec_);
if ($writable > 0) {
// write buffer to stream
$written = #stream_socket_sendto($this->handle_, $buf);
if ($written === -1 || $written === false) {
throw new TTransportException('TSocket: Could not write '.TStringFuncFactory::create()->strlen($buf).' bytes '.
$this->host_.':'.$this->port_);
}
// determine how much of the buffer is left to write
$buf = TStringFuncFactory::create()->substr($buf, $written);
} elseif ($writable === 0) {
throw new TTransportException('TSocket: timed out writing '.TStringFuncFactory::create()->strlen($buf).' bytes from '.
$this->host_.':'.$this->port_);
} else {
throw new TTransportException('TSocket: Could not write '.TStringFuncFactory::create()->strlen($buf).' bytes '.
$this->host_.':'.$this->port_);
}
}
}
That means the socket was blocked and was not able to write. But the socket is just open and should not be blocked. I try select immediately after pfsockopen
if ($this->persist_) {
$this->handle_ = #pfsockopen($this->host_,
$this->port_,
$errno,
$errstr,
$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000));
} else {
$this->handle_ = #fsockopen($this->host_,
$this->port_,
$errno,
$errstr,
$this->sendTimeoutSec_ + ($this->sendTimeoutUsec_ / 1000000));
}
// Connect failed?
if ($this->handle_ === FALSE) {
$error = 'TSocket: Could not connect to '.$this->host_.':'.$this->port_.' ('.$errstr.' ['.$errno.'])';
if ($this->debug_) {
call_user_func($this->debugHandler_, $error);
}
throw new TException($error);
}
$write = array($this->handle_);
$writable = #stream_select($null, $write, $null, $this->sendTimeoutSec_, $this->sendTimeoutUsec_);
if ($writable === 0) {
die('123');
}
The result show that it is block right after it is opened!
When restart php-fpm, the error disappear for a while and come up again.
Here is the client code:
$socket = new TSocket('10.0.1.151', 1234, true);
$framedSocket = new TFramedTransport($socket);
$transport = $framedSocket;
$protocol = new TCompactProtocol($transport);
$transport->open();
$client= new userservice\UserServiceProxyClient($protocol);
$result = $client->findUser($id);
If I adjust the php-fpm configuration pm.max_children from 200 to 2, the error also disappear.
I tried increase timeout to 10 seconds and it timeout after 10 seconds.
Any idea for what's the cause of the problem and how to fix it?
I modify the php thrift lib. Change from
$writable = #stream_select($null, $write, $null, $this->sendTimeoutSec_, $this->sendTimeoutUsec_);
to
$writable = 1;
And the same for read.
The problem get fixed.
That means the connection is established ( I even use tcpdump to confirm the tcp connection is established) and writable, but select timeout. Strange things!

How to detect stream_copy_to_stream errors?

I've got a bit of code which, simplified, looks something like:
$fout = fsockopen($host, 80);
stream_set_timeout($fout, 10*3600); // 10 hours
$fin = fopen($file, 'rb'); // not really a file stream, but good enough proxy here
$readbytes = stream_copy_to_stream($fin, $fout);
if(!$readbytes) die('copy failed');
However, I'm sometimes getting the following type of error:
Notice: stream_copy_to_stream(): send of 952 bytes failed with errno=104 Connection reset by peer in ...
Notice: stream_copy_to_stream(): send of 952 bytes failed with errno=32 Broken pipe in ...
And the check on $readbytes there won't pick up the error.
I'm aware that it may be possible to check the total length of the file with the number of bytes copied, but this only works if the total length of the stream can be determined in advance.
As this happens randomly, I presume that the connection is just being dropped for some weird reason (but if anyone has any suggestions to reduce the likeliness of this happening, I'm all ears). But it'd be nice to be able to know whether the transfer fully succeeded or not.
Is there anyway to detect a problem without:
having to know the length of the stream in advance
hook into the PHP error handler to pick up the error
...or perhaps using a buffered fread/fwrite loop, checking the length of bytes written, the best solution here?
Thanks.
Okay, so here's my stream copy function, which tries to detect errors, but it seems to fail still (and I thought fwrite was meant to return the correct number of bytes)
function stream_copy($in, $out, $limit=null, $offset=null) {
$bufsize = 32*1024;
if(isset($offset)) fseek($in, $offset, SEEK_CUR);
while(!feof($in)) {
if(isset($limit)) {
if(!$limit) break;
$data = fread($in, min($limit,$bufsize));
} else
$data = fread($in, $bufsize);
$datalen = strlen($data);
$written = fwrite($out, $data);
if($written != $datalen) {
return false; // write failed
}
if(isset($limit)) $limit -= $datalen;
}
return true;
}
In above function, I'm still getting a 'true' returned even when an error is displayed.
So I'm just going to try hooking into PHP's error handler. Haven't tested the following, but my guess is that it should work
function stream_copy_to_stream_testerr($source, $dest) {
$args = func_get_args();
global $__stream_copy_to_stream_fine;
$__stream_copy_to_stream_fine = true;
set_error_handler('__stream_copy_to_stream_testerr');
call_user_func_array('stream_copy_to_stream', $args);
restore_error_handler();
return $__stream_copy_to_stream_fine;
}
function __stream_copy_to_stream_testerr() {
$GLOBALS['__stream_copy_to_stream_fine'] = false;
return true;
}
Ugly, but the only solution I can see.

Why sometimes can't get content using file_get_contents()?

The code is simple:
<?php
function getStringFromUrl($url){
$fResource = fopen($url, 'r');
do {
$data = fread($fResource, 8192);
if (strlen($data) == 0) {
break;
}
$contents .= $data;
} while(true);
fclose ($fResource);
$contents = mb_convert_encoding($contents,'utf-8','gbk');
return $contents;
}
echo getStringFromUrl(urlencode('http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=text&ip=119.97.23.59'));
echo file_get_contents('http://blog.sina.com.cn/rss/1400122351.xml');
Sometimes I can get content, sometimes not. I can't figure out why.
(EDIT:the error msg is :[function.fopen]: failed to open stream and [function.file-get-contents]: failed to open stream)
Of course the 2 URL above are available.
I have also set the allow_url_fopen = On in php.ini.
First of all - you don't need to urlencode full url! Only GET parameters:
echo file_get_contents('http://int.dpool.sina.com.cn/iplookup/iplookup.php?'.http_build_query(array(
'format' => 'text',
'ip' => '119.97.23.59'
)));
Second thing you should share with is error message (if any)

Categories