Skip to content

Instantly share code, notes, and snippets.

@PerpetualBeta
Created October 25, 2012 16:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PerpetualBeta/3953704 to your computer and use it in GitHub Desktop.
Save PerpetualBeta/3953704 to your computer and use it in GitHub Desktop.
PHP wrapper for servers where mod_expires and/or mod_deflate are not available. Files routed through this wrapper will be served gzip-compressed, with an ETag and with a "far future expires" header.
<?php
/**
* Page delivery wrapper for servers where mod_expires and/or mod_deflate are
* not available.
*
* Route page requests through this wrapper (via mod_rewrite for example) and
* they will be served with far future expires, etags and will be gzip
* compressed.
*
* Works with both programmatically generated and static files.
*
* @param URI $_REQUEST['URI'] URI/URL of the text file to process
*
* @copyright Copyleft: http://www.gnu.org/copyleft/copyleft.html
* @author Jonathan M. Hollin <darkblue@sdf.lonestar.org>
*/
// CONFIGURE
// ---------
// URI to custom 404 page. Edit as necessary (static file, NOT a script).
define('CUSTOM_404', __DIR__ . '/errors/404.html');
// Expiry time of file (from now)
define('EXPIRY_TIME', (365.25 * 24 * 60 * 60)); // seconds
// END CONFIGURATION
// Sanity Check
if ($_REQUEST['uri']) $URI = filter_var($_REQUEST['uri'], FILTER_SANITIZE_URL);
// Generate a 404 error if the URI is bad
if (!$URI) notFound();
// Target file ($target) - absolute path
$target = __DIR__ . '/' . $URI;
// Can the URI be resolved?
if ( file_exists($target) ) {
// Trying read as a file
$buffer = file_get_contents($target);
} else {
// Trying read as URL
$buffer = file_get_contents($URI);
}
// Get the MIME type of the resource
$MIMEType = ($buffer) ? getMIMEType($buffer) : false;
// The Process
if ($buffer === false) {
// The $buffer has no content. 404 Error!
notFound();
} else {
// The $buffer has content.
// Turn on the gzip handler, do so gracefully
if ( ini_get('zlib.output_compression') ) {
// Don't do anything if compression is already enabled.
ob_start();
} else {
if (!ob_start('ob_gzhandler')) ob_start();
}
// Header pre-flight
$cacheTime = filemtime($target);
$gmt_mtime = gmdate('D, d M Y H:i:s', $cacheTime ) . ' GMT';
// Send the headers
if ($MIMEType) header('Content-type: ' . $MIMEType);
header('Last-Modified: ' . $gmt_mtime, true);
header('Expires: ' . gmdate("D, d M Y H:i:s", $cacheTime + EXPIRY_TIME) . ' GMT', true);
header('Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate', true);
header('Cache-Control: post-check=0, pre-check=0', FALSE);
header('Etag: ' . md5($target));
// Send the page
echo $buffer;
// Send the contents of the output buffer and turn buffering off
// (we're done!)
ob_end_flush();
}
function notFound() {
// Send 404 headers
header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
header('Status: 404 Not Found');
if ( file_exists(CUSTOM_404) ) {
// Load and display the custom 404 page
@readfile(CUSTOM_404);
} else {
// Display basic 404 error message
echo '<h1>404 Not Found</h1>';
echo 'The page that you have requested could not be found.';
}
die();
}
function getMIMEType($resource) {
$finfo = new finfo(FILEINFO_MIME);
if ($resource) return $finfo->buffer($resource);
}
@PerpetualBeta
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment