#22154 [Com]: fpassthru() fails with files larger than a few hundered KB

From: Date: Sat, 03 May 2003 16:07:38 +0000
Subject: #22154 [Com]: fpassthru() fails with files larger than a few hundered KB
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-38988@lists.php.net to get a copy of this message
 ID:               22154
 Comment by:       guilc at fr dot st
 Reported By:      malekjo at aphrodite dot com
 Status:           Verified
 Bug Type:         Session related
 Operating System: Linux 2.4.18-10
 PHP Version:      4.3.2-dev
 New Comment:

I had exactly the same problem with apache 2.0.45 and php 4.3.2-RC2 and
4.3.2-RC3-dev. My code is slightly the same and is designated for
sending tarballs :

header("Content-Type: application/x-tar\n");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT\n");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT\n");
header("Content-length: " . filesize($arch) . "\n");
if (PMA_USR_BROWSER_AGENT == 'IE')
{
    header("Content-Disposition: inline; filename=\"$arch\"\n");
    header("Content-Transfer-Encoding: binary\n");
    header("Cache-Control: must-revalidate, post-check=0,
pre-check=0\n");
    header("Pragma: public\n");
}
else
{
    header("Content-Disposition: attachment; filename=\"$arch\"\n");
    header("Content-Transfer-Encoding: binary\n");
    header("Pragma: no-cache\n");
}
header("Connection: close\n");
readfile($arch);
exit ();

The issue is very simple : just downgrade to apache 1.3.27, and there
is no more memory leak ! This seems not to be a php problem, but an
apache problem...


Previous Comments:
------------------------------------------------------------------------

[2003-03-25 14:51:14] rbobrovs at pop dot tuwien dot ac dot at

Some more strange observations:

The following script works fine on an WinXP (SP1) / PHP 4.3.1 / Apache
1.3.27 system (both as a module and CGI):

# ob_start();

$document = "c:\\Program Files\\Apache
Group\\Apache2\\htdocs\\a4.gif";
$len = filesize($document);
	
header("Content-type: image/gif");
header("Content-Length: $len");
header("Content-Disposition: inline; filename=a4.gif");

readfile($document);

# ob_end_flush();
exit();

However, with Apache 2.0.44, larger images (e.g. 400k) load
incompletely (tested with Phoenix 0.5 and IE 6.0) as long as I do not
use ob_start / ob_end_flush (same observation for PHP as a module and
CGI).

If I try the same with a PDF file of similar size (again Apache
2.0.44), the Acrobat Reader Plugin also shows incomplete files and
seems to hang, even when using ob_start / ob_end_flush (this works with
Apache 1.3.27). If I use wget to retrieve the file the download
succeeds without any problem.

Some directives from php.ini:
output_buffering = Off
implicit_flush = Off
max_execution_time = 30
max_input_time = 60
memory_limit = 8M    

There are no related errors in the Apache error log.

------------------------------------------------------------------------

[2003-03-08 10:59:17] sniper@php.net

Just keep the category as session related, as this is caused
by the trans-sid feature..


------------------------------------------------------------------------

[2003-03-07 17:41:15] malekjo at aphrodite dot com

sorry...8192 bytes...

------------------------------------------------------------------------

[2003-03-07 17:36:32] malekjo at aphrodite dot com

Woohoo, I'm not the only one...

Raising the memory limit and setting output buffers to 8192K in php.ini
worked.  Though I am not happy with that solution.  Indicates to me
some mmap error of some sort.  Maybe something in glibc is mmapping the
file and creating artificially large buffer spaces in memory.

Here's what I found to "work"...though it still indicates a
buffer/memory bug to me:

function send_file($dir, $file){
  $fp = fopen("$dir/$file", 'rb');
  header("Cache-control: private, no-cache, no-store,
must-revalidate");
  header("Pragma: no-cache");
  header("Content-Type: application/x-stuffit");
  header("Content-Length: ".filesize("$dir/$file"));
  header("Content-Disposition: attachment; filename=\"$file\"");
  header("Connection: close");

  while(!feof($fp) and (connection_status() == 0)) {
    print(fread($fp, 8192));
    flush();
  }

  $status = (connection_status() == 0);
  fclose($fp);

  return($status);
}

This works with an 8M memory limit (I really don't want to have it any
higer, otherwise concurrent downloads will absolutely hammer on the
server) but needs output buffering turned on at 8192K.

------------------------------------------------------------------------

[2003-03-06 12:50:12] sniper@php.net

I get pretty wierd results with this script:

<?php

session_start();  // Comment this and it works fine..

$fp = fopen("test.zip", 'rb');
rewind($fp);
header("Cache-control: private"); // another fix for IE
header("Content-Type: application/x-stuffit");
header("Content-Length: ".filesize('test.zip'));
header("Content-Disposition: attachment\; filename=\"test.zip\"");
header("Connection: close");
$fr = fpassthru($fp);

?>

php,ini:
session.use_trans_sid = 1
memory_limit = 1M

And sending some file around 1M size will make it fail..









------------------------------------------------------------------------

The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
    http://bugs.php.net/22154

-- 
Edit this bug report at http://bugs.php.net/?id=22154&edit=1



Thread (34 messages)

« previous php.bugs (#38988) next »