php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #26454 feof and fgets hangs out
Submitted: 2003-11-28 15:17 UTC Modified: 2003-11-30 06:29 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: nunoplopes at sapo dot pt Assigned: wez (profile)
Status: Closed Package: Sockets related
PHP Version: 4CVS-2003-11-30 OS: Windows XP - Apache
Private report: No CVE-ID: None
 [2003-11-28 15:17 UTC] nunoplopes at sapo dot pt
Description:
------------
I opened a socket using fsockopen and then I send some data using fputs.
Then I try to read data either using feof of fgets. If the servers returns 2 lines and I call three times the fgets(), the script times out when it reaches the 30 seconds. If I only call fgets 2 times, everything works fine.
feof also stops the script execution.
So, I have no way to know if servers' response has ended or not.

Reproduce code:
---------------
Get the code from CVS at: http://cvs.sourceforge.net/viewcvs.py/phpdocmanager/phpcvsclass/

Or just a small example:
<?
if ($handle = fsockopen ("cvs.php.net", 2401, $errno, $errstr, 30)) {

$text = "BEGIN AUTH REQUEST\n";
$text .= "/repository\n";
$text .= "cvsread\n";
$text .= "A\n";
$text .= "END AUTH REQUEST\n";

fputs ($handle, $text);
fgets($handle); // "I LOVE YOU\n"

fputs ($handle, "version\n");
echo fgets($handle);
echo fgets($handle);
echo fgets($handle);
fclose($handle);
}
?>

Expected result:
----------------
M Concurrent Versions System (CVS) 1.12.2 (client/server)\n
ok

Actual result:
--------------
timeout

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-11-28 17:26 UTC] iliaa@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php4-STABLE-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php4-win32-STABLE-latest.zip

Please try the snapshot that will be generated in about 4 hours (from the time of this post).
 [2003-11-29 14:59 UTC] nunoplopes at sapo dot pt
I've installed the new snapshot (Nov 29, 2003 17:30 GMT).

The script still times out. The example I wrote before still doesn't work, but there is other with feof that works. Really strange....


Working script:
<?
$fp = fsockopen ("pt.php.net", 80, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br>\n";
} else {
    fputs ($fp, "GET / HTTP/1.1\r\n");
    fputs ($fp, "Host: pt.php.net\r\n");
    fputs ($fp, "Connection: Close\r\n\r\n");
    while (!feof($fp)) {
        echo fgets ($fp,128);
    }
    fclose ($fp);
}
?>
 [2003-11-30 04:33 UTC] wez@php.net
Can you clarify what is happening now (with the updated snapshot)? Provide a short script and explain what happens and why you think it is wrong.
Thanks!
 [2003-11-30 05:14 UTC] nunoplopes at sapo dot pt
I've compiled a couple of tests and its results on my pc, using the snapshot of Nov 30, 2003 09:30 GMT.

The tests andits results are at: http://testes.aborla.net/php-bugreport.tar.bz2
 [2003-11-30 05:22 UTC] wez@php.net
Please, just a single script, and please explain what happens and why it is wrong.
 [2003-11-30 05:26 UTC] nunoplopes at sapo dot pt
The first example I wrote (in reproduce code) is a good example.
I echo fgets 3 times and it times out in the third fgets. Instead of timing ou, it should return FALSE.
 [2003-11-30 05:35 UTC] wez@php.net
I don't have intimate knowledge of the cvs pserver protocol... why should it return false instead of timeout?
 [2003-11-30 05:47 UTC] nunoplopes at sapo dot pt
In the manual it says:
"If an error occurs, returns FALSE." (http://php.net/fgets)

The cvs server should only returns two lines. So, if I call fgets a third time, it times out and I think it should return FALSE.
And feof doesn't work either, so I never know if the server's reponse has ended or not...
 [2003-11-30 06:10 UTC] wez@php.net
does it return two lines and close the connection, or return two lines and wait for you to send more data?
 [2003-11-30 06:15 UTC] nunoplopes at sapo dot pt
The connection stays open and waiting.
 [2003-11-30 06:29 UTC] wez@php.net
In that case, this is the expected behaviour; the connection has not closed, so feof() returns false.
fgets will time out because it will wait a maximum of 60 seconds (by default; the default_socket_timeout ini setting configures this).  It does not return false because it has not hit an error; it merely does not have any data before your timeout period expires (this is a feature).

It is your responsibility to implement the network protocol correctly (PHP cannot read your mind, not that of the CVS server); if you expect only two lines, then you should read only two lines.

 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Thu Jul 07 01:04:05 2022 UTC