Edit report at http://bugs.php.net/bug.php?id=44164&edit=1
ID: 44164 Updated by: cataphr...@php.net Reported by: mplomer at gmx dot de Summary: Handle "Content-Length" HTTP header when zlib.output_compression active -Status: Closed +Status: Assigned Type: Feature/Change Request Package: *General Issues Operating System: * PHP Version: 5.2.5 Assigned To: cataphract Block user comment: N New Comment: I'm reopening as the general opinion seems to be that the content-length header should be suppressed instead of disabling compression. Previous Comments: ------------------------------------------------------------------------ [2010-10-26 04:16:23] cataphr...@php.net Automatic comment from SVN on behalf of cataphract Revision: http://svn.php.net/viewvc/?view=revision&revision=304903 Log: - Implemented request #44164, zlib.output_compression is now implicitly disabled when the header "Content-length" is set. #One could argue that any output handler could change the size of the #response, so this exception for zlib.output_compression is an #inconsistency. However, zlib.output_compression is presented as a #performance setting, whose value should have no effect on the #correctness of the scripts. This was not the case. Setting the #header "content-length" and enabling zlib.output_compression was #a recipe for infringing section 4.4 of RFC 2616. ------------------------------------------------------------------------ [2010-10-23 16:49:53] mplomer at gmx dot de In the meantime we do output-compression only via apache. But back to the problem: First I thought it would be better to remove the header if present (buffering output is not an option of course), but it is also an idea to disable output compression completely, when this header is set (which is a rare case in our environment, and INHO most php users, too). Our problem was that Varnish Reverse Proxy was confused by this inconsistent headers. Both solutions would solve this. ------------------------------------------------------------------------ [2010-10-23 15:04:29] cataphr...@php.net I've just been hit by this problem and I'm thinking a better option would be to disable zlib.output_compression if the Content-Length header is set. What do you think? Buffering everything and then calculating the actual length is not really an option, the output could be several hundred megabytes. ------------------------------------------------------------------------ [2008-02-19 11:04:24] mplomer at gmx dot de Another idea is: IF the Content-Length header IS set from the script, THEN buffer the complete output and calculate the correct compressed Content-Length. ELSE do nothing (do not add any Content-Length header) So ob_flush(), flush() will still work if compression is active. (Which will not work, if we use apache's mod_deflate. This is why "zlib.output_compression" is required.) ------------------------------------------------------------------------ [2008-02-19 10:48:09] mplomer at gmx dot de Description: ------------ If you have a big project, where "Content-Length" header is set on many places, and then you turn on "zlib.output_compression", you will have a problem, because the original header is still passed through, but it is invalid now, because it contains the length of the uncompressed data instead of the compressed data. This would confuse some HTTP clients, that rely on the "Content-Length". I think, "zlib.output_compression" should be completely transparent, so this issue should be handled in php core. One solution is, to remove the "Content-Length" header (if set) in ob_gzhandler() in ext/zlib/zlib.c:882 (where "Content-Encoding: gzip" header is set). If you see a good way to set the Content-Length to the compressed length, this would be, of course, the best solution, but this is IMHO only possible, if the entire data is buffered before (or is this done by ob_gzhandler anyway?). This would make the various workarounds irrelevant that have to be done if "zlib.output_compression" is active and is completely backward compatible. Reproduce code: --------------- In php.ini: zlib.output_compression = On <?php $output = str_repeat('A', 8192); header('Content-Length: ' . strlen($output)); ?> Expected result: ---------------- Correct "Content-Length" header or removed "Content-Length" header in response, because the old length is always wrong. Better send no "Content-Length" instead a wrong length. Actual result: -------------- The old "Content-Length" header is sent. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/bug.php?id=44164&edit=1