Re: gzcompress -- SOLVED
| From: | Andreas Pour | Date: | Thu, 10 Aug 2000 06:36:39 +0000 |
| Subject: | Re: gzcompress -- SOLVED | ||
| References: | 1 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-11075@lists.php.net to get a copy of this message | ||
Andreas Pour wrote:
>
> Hi,
>
> Has anyone gotten gzcompress to work together with output buffering?
> When you just call it with your data it does not create the appropriate
> file format for gzip (i.e. it does the compression correctly but does
> not insert the appropriate headers, as described in
>
> http://www.info-zip.org/pub/infozip/zlib/rfc-gzip.html#file-format),
> and
> hence the decoding on the client side does not work.
Found a solution that works on the browsers I tested. I had to compile
with --zlib and --mhash (mhash is available from
http://mhash.sourceforge.net/, although it may not be
necessary,
depending on how picky the browser is).
In the 'prepend' file, before sending any headers, I put the code:
$doGzip = isset($GLOBALS["HTTP_ACCEPT_ENCODING"]) &&
eregi("gzip", $GLOBALS["HTTP_ACCEPT_ENCODING"]);
if ($doGzip)
ob_start();
In my scripts, I replace each call to 'flush()' with:
if (!$doGzip)
flush();
Finally, in my "tail" script, I put the meat of the matter:
if ($doGzip)
{
// takes an integer argument
function printBinaryInt($val)
{
return (chr($val & 0xFF) . chr(($val >> 8) & 0xFF) .
chr(($val >> 16) & 0xFF) . chr($val >> 24));
}
$content = ob_get_contents();
ob_end_clean();
// strip off first two and last four chars from compress output
$send = substr(gzcompress($content, 6), 2, -4);
//readfile($file . ".gz");
// print the headers as well
// need to print:
// ID1 ID2 CM FLG MTIME XFL OS
// ID1: one byte, = 31
// ID2: one byte, = 139
// CM: one byte, 8 for deflate
// FLG: one byte, 0 for no extra options
// MTIME: modified time, 0 for no data
// XFL: one byte, 0 for neither max nor min
// OS: one byte, 3 for Unix
// After the send, need to include the "CRC32" and "ISIZE"
// CRC32: 4 bytes: hash of original data
// ISIZE: 4 bytes: size of original data
header("Content-encoding: gzip"); // 'x-gzip' is correct but breaks
MSIE
header("Content-Length: " . (strlen($send) + 18));
print(chr(31) . chr(139) . chr(8) . chr(0) . printBinaryInt(time())
.
chr(0) . chr(3) . $send . mhash(MHASH_CRC32B, $content) .
printBinaryInt(strlen($content))); // stuff after 'send' may
not be needed
}
That's it.
Ciao,
Andreas
> BTW, I can get the compression to work if I output the text to a file,
> run gzip on it and then send the file to the browser.
>
> Ciao,
>
> Andreas