1

I'm not sure if this is a PHP problem, server config problem or hardware problem, but thought I'd start with PHP and see if I get any suggestions. This code worked fine until recently, and I'm not aware of any configuration changes that might have caused this. We did upgrade from Debian Lenny to Squeeze recently (and from PHP 5.2 to 5.3), but the code works fine on another Squeeze server.

I have a bit of PHP code that takes a path to a file passed as a GET variable (rewritten via mod_rewrite from a request to http://site.com/request/for/file.pdf to http://site.com/downloader.php?path=/path/to/file.pdf). The reason for doing this relates to stats tracking.

The file get passed along to this bit code (simplified for readability).

 if(is_readable($theFile)) {

       //$fh= fopen($theFile, "r");
       header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
       header("Pragma: no-cache");
       header("Content-Type: application/pdf");
       header("Content-Disposition: attachment; filename=\"".basename($theFile)."\"");
       header("Content-Length:".(string)(filesize($theFile)));
       sleep(1);
       //fpassthru($fh);
       readfile($theFile);
 }

As you can see, the code only gets executed if the file is readable (ie the path is all correct). For files under about 63MB, everything works fine. For anything over 63MB, the server returns a 500 error. (This gets reported in Firefox/Chrome as 'file not found', when I guess it should be 'internal server error', but that's another story I guess). There is nothing in the Apache error logs.

Can anybody think of any PHP or Apache server configuration that would cause this to happen? PHP memory limits should not be affected by readfile or fpassthru as far as I know. I do note that my PHP memory limit is 64MB, however, turning off the mod_rewrite redirect to the PHP does not fix the problem. The files still won't download.

Many thanks for any suggestions.

UPDATED***********

Ok, so I increased the PHP Memory limit from 64MB to 200MB. That allows files up to 200MB to download. However, the question remains. Given that readfile and fpassthru should not be affected by memory limit, and I have checked that output buffering is off, why are large files causing this (new) problem?

fred2
  • 1,015
  • 2
  • 9
  • 29
  • 1
    Is output buffering turned off? (That's the only possible memory issue the manual page on readfile() mentions) – Pekka Jun 05 '12 at 18:54
  • So which is it? 500 or 505 error? (505 wouldn't make much sense.) – Ry- Jun 05 '12 at 18:54
  • 2
    PHPs `memory_limit` possibly. What's it set to? – mario Jun 05 '12 at 18:54
  • 1
    @mario: That wouldn't make a 500 error. – Madara's Ghost Jun 05 '12 at 18:58
  • @Truth: Won't every error make a 500 error as long as PHP's `display_errors` is 0? – Hubro Jun 05 '12 at 19:02
  • @Codemonkey: No. If display_errors is 0, a blank page would be shown (which is worse than 500 error). – Madara's Ghost Jun 05 '12 at 19:03
  • 1
    @Truth I've always set `log_errors` to 1 and `display_errors` to 0 in production environments, and all errors always cause the 500 Internal Server Error – Hubro Jun 05 '12 at 19:11
  • 1
    @Truth http://stackoverflow.com/questions/3075355/php-emitting-500-on-errors-where-is-this-documented – Pekka Jun 05 '12 at 19:13
  • 2
    sounds like a memory limit error or script timeout error. check your php.ini settings. – Rooster Jun 05 '12 at 19:19
  • 1
    Too much guessing. Too litte feedback. ↷ Too localized. – mario Jun 05 '12 at 19:19
  • Yeah 500 (505 was a typo). PHP Memory limit is 64MB, which seems suggestive, but the error happens even when PHP is not involved. – fred2 Jun 05 '12 at 19:25
  • 1
    Ok - it is a php memory limit problem, but it should not be. PHP error logs show a Fatal error because of memory size being exhausted. However there is no output buffering that I know of, so readfile and passthru should not (and never used to) cause this problem. – fred2 Jun 05 '12 at 19:31
  • Which line does the error occur in? – Pekka Jun 05 '12 at 19:41
  • Is output buffering turned off? – Pekka Jun 05 '12 at 19:41
  • @Pekka. The PHP fatal error is thrown at the `readfile($theFile);` line (and yes, it's off). – fred2 Jun 05 '12 at 19:42
  • 1
    Weird. The manual explicitly states that shouldn't be the case. It says the only possible reason for this to happen is output buffering – Pekka Jun 05 '12 at 19:43
  • 1
    Other PHP ini settings, features or frameworks can sneakily create output buffers even if you're not explicitly creating one. Have you checked the output of `ob_get_level()`? (It would be `0` if there's no buffering in play). – John Flatness Jun 05 '12 at 19:53
  • Hi John. Good point. But I've checked again - ob_get_level returns 0. – fred2 Jun 05 '12 at 20:01

1 Answers1

1

Resolution was simple (after hours of work).

php_value output_buffering 0

added to Apache virtual host config.

Seems that, regardless of what ob_get_level() said, output buffering was taking place. In other words, just the option to use output buffering is enough for it to affect PHP memory use.

fred2
  • 1,015
  • 2
  • 9
  • 29