Search code examples
phpzliboutput-bufferinghttp-compression

HTTP 500 Internal Server Error with zlib.compression


I enabled zlib.compression in my PHP script.

When I serve small amounts of data with output buffering enabled (up to about 200 MB), everything works fine.

However, when I try to serve more data, I get an HTTP 500 error, and PHP does not log any errors for it although logging is enabled and definitely works.

PHP does not have any output handlers set (output_handler has no value).

<?php

ini_set('zlib.output_compression', 4096);

@ob_start();

header('Content-Type: application/octet-stream');
readfile('/tmp/bigfile.bin');

@ob_end_flush();

With output buffering disabled (i.e. without ob_start() / ob_end_flush()), everything works fine.

What is happening here ? How do I fix this ?

(The code above is just an example that shows the error; I need output buffering for various reasons, so disabling it is not so good; also I'd prefer to use compression if possible)


Solution

  • Turns out to be a memory limit problem (removing the @ before the ob_*() functions will produce error messages).

    Using output buffering and HTTP compression apparently uses a lot of memory.

    My memory limit was 1024 MB, and the script fails with a 230 MB file.

    If we assume that readfile() loads an entire file into memory before handing it over to output buffering, this would still just be readfile() + output buffering + compression ~ 230 MB + 230 MB + 230 MB + some slack for compression and buffering ~ still just about 800 MB, way below 1024 MB...

    Bottom line: Do not use compression and output buffering for bigger data.