Right now I'm trying to serve CSS and JS files from a server that won't let me enable mod_gzip
or mod_deflate
. So I wrote a small PHP script to compress with GZIP and return to the user.
Example Code:
$filename = "style.css";
if (!file_exists($filename) || !($info = stat($filename))) {
header("HTTP/1.1 404 Not Found");
die();
}
header("Date: ".gmdate("D, j M Y H:i:s e", time()));
header("Cache-Control: max-age=2592000");
header("Last-Modified: ".gmdate("D, j M Y H:i:s e", $info['mtime']));
header("Etag: ".sprintf("\"%x-%x-%x\"", $info['ino'], $info['size'], $info['mtime']));
header("Accept-Ranges: bytes");
header("Cache-Control: Expires ".gmdate("D, j M Y H:i:s e", $info['mtime']+2592000));
header("Content-Type: text/html");
ob_start("ob_gzhandler");
echo file_get_contents($filename);
ob_end_flush();
I'm having two problems right now. The first is, I'm having trouble determining the resulting size of the compressed file to inform the browser of the content-length. Normally, I would include this line:
header("Content-Length: ".$info["size"]);
But, if I do, the browser hangs while trying to wait for more data. Is there a way to calculate the total size? Or should I ignore this header directive.
The other issue is, whenever I view this PHP file in Firefox, it tries to have me download the result. In Chrome, it just displays it like I would expect. Any suggestions?
Edit: Thanks to SoapBox, I replaced the end of the code with this:
header("Content-Encoding: gzip");
$compressed = gzencode(file_get_contents($filename), 5);
header("Content-Length: ".strlen($compressed));
die($compressed);
This works great for the content-length! But I'm still getting Firefox to download the file instead of display it. :(
Edit Again: Here is the modified end-of-code code, courtesy of Cletus.
// Start buffered output
ob_start();
// Check for gzip capability
if (stripos($_SERVER['HTTP_ACCEPT_ENCODING'], "gzip") !== false) {
ob_start("ob_gzhandler");
echo file_get_contents($filename);
ob_end_flush();
} else
echo file_get_contents($filename);
// Write the content length
header('Content-Length: '.ob_get_length());
ob_end_flush();
I'm going to start a new question to figure out why Firefox keeps trying to download the file.