PHP ob_gzhandler, setting Content-Length disables gzipped output

2k views Asked by At

I read some articles about setting the content-length of a file that will be served. It has some benefits comparing to chunked downloads. The server serve chunks (don't know what the size of a chunk is anyway) when the content-length is unknown.

In PHP I use the ob_gzhandler to gzip html,js and css files and other text-based content. Setting the raw content-length before gzip output, results in strange side-effects because the length does not match the length of the gzipped output. I notice a delay or the browser reports an encoding error.

I saw a trick (also on stackoverflow) to set the content-length after gzip compression to be sure it reports the correct size. But when I do this, the content is no longer compressed.

The question is, is this behaviour correct? Is gzipped content always send chuncked? Is content-length only needed for files that are not gzipped?

Here some snippets of code:

1 Results in gzipped and chunked file transfer:

ob_start('ob_gzhandler');
echo $sResult;

2 Results in normal file transfer with content-length specified (but expect gzipped and content-length):

ob_start('ob_gzhandler');
echo $sResult;
header('Content-Length: '.ob_get_length()); 

Here some pictures of http header results: 1 Gzipped and Chuncked

2 Expect Gzipped but normal transfer when set content-length

1

There are 1 answers

0
Codebeat On BEST ANSWER

Found the solution/trick here: How to determine the Content-Length of a gzipped file?

Made into this:

// clear output buffers
while( ob_get_level() )
 { ob_end_clean(); }

< send http headers here >

ob_start();
ob_start('ob_gzhandler');
echo $sResult;
if( !headers_sent() )
{
   ob_end_flush(); // Flush the output from ob_gzhandler
   header('Content-Length: '.ob_get_length());
   ob_end_flush(); // Flush the outer ob_start()
}

To me is not clear why this works but seems to work perfectly. The content is now gzipped and has a content-length (not chunked).

To prove it, here is a screenshot:

gzipped and content-length

Cheers! ;-)