function cdn_basic_farfuture_download in CDN 6.2
Same name and namespace in other branches
- 7.2 cdn.basic.farfuture.inc \cdn_basic_farfuture_download()
1 string reference to 'cdn_basic_farfuture_download'
- cdn_menu in ./
cdn.module - Implementation of hook_menu().
File
- ./
cdn.basic.farfuture.inc, line 12 - Far Future expiration setting for basic mode.
Code
function cdn_basic_farfuture_download($token, $ufi, $path) {
// Validate the token to make sure this request originated from CDN.
$path_info = pathinfo($path);
$sec_token = _cdn_hmac_base64($ufi . $path_info['filename'], drupal_get_private_key() . _cdn_get_hash_salt());
if ($token != $sec_token) {
header('HTTP/1.1 403 Forbidden');
exit;
}
// Disallow downloading of files that are also not allowed to be downloaded
// by Drupal's .htaccess file.
if (preg_match("/\\.(engine|inc|info|install|make|module|profile|test|po|sh|php([3-6])?|phtml|.*sql|theme|tpl(\\.php)?|xtmpl)\$|^(\\..*|Entries.*|Repository|Root|Tag|Template)\$/", $path)) {
header('HTTP/1.1 403 Forbidden');
exit;
}
if (!file_exists($path)) {
watchdog('cdn', 'CDN Far Future 404: %file.', array(
'%file' => $path,
), WATCHDOG_ALERT);
header('HTTP/1.1 404 Not Found');
exit;
}
// Remove some useless/unwanted headers.
$remove_headers = explode("\n", CDN_BASIC_FARFUTURE_REMOVE_HEADERS);
$current_headers = array();
foreach (headers_list() as $header) {
$parts = explode(':', $header);
$current_headers[] = $parts[0];
}
foreach ($remove_headers as $header) {
if (in_array($header, $current_headers)) {
// header_remove() only exists in PHP >=5.3
if (function_exists('header_remove')) {
header_remove($header);
}
else {
// In PHP <5.3, we cannot remove headers. At least shorten them to save
// every byte possible and to stop leaking information needlessly.
drupal_set_header($header . ':');
}
}
}
// Remove all previously set Cache-Control headers, because we're going to
// override it. Since multiple Cache-Control headers might have been set,
// simply setting a new, overriding header isn't enough: that would only
// override the *last* Cache-Control header. Yay for PHP!
if (function_exists('header_remove')) {
header_remove('Cache-Control');
}
else {
drupal_set_header("Cache-Control:");
drupal_set_header("Cache-Control:");
}
// Default caching rules: no caching/immediate expiration.
drupal_set_header("Cache-Control: private, must-revalidate, proxy-revalidate");
drupal_set_header("Expires: " . gmdate("D, d M Y H:i:s", time() - 86400) . "GMT");
// Instead of being powered by PHP, tell the world this resource was powered
// by the CDN module!
drupal_set_header("X-Powered-By: Drupal CDN module");
// Instruct intermediate HTTP caches to store both a compressed (gzipped)
// and uncompressed version of the resource.
drupal_set_header("Vary: Accept-Encoding");
// Determine the content type.
drupal_set_header("Content-Type: " . _cdn_basic_farfuture_get_mimetype(basename($path)));
// Support partial content requests.
drupal_set_header("Accept-Ranges: bytes");
// Browsers that implement the W3C Access Control specification might refuse
// to use certain resources such as fonts if those resources violate the
// same-origin policy. Send a header to explicitly allow cross-domain use of
// those resources. (This is called Cross-Origin Resource Sharing, or CORS.)
drupal_set_header("Access-Control-Allow-Origin: *");
// If the extension of the file that's being served is one of the far future
// extensions (by default: images, fonts and flash content), then cache it
// in the far future.
$farfuture_extensions = variable_get(CDN_BASIC_FARFUTURE_EXTENSIONS_VARIABLE, CDN_BASIC_FARFUTURE_EXTENSIONS_DEFAULT);
$extension = drupal_strtolower(pathinfo($path, PATHINFO_EXTENSION));
if (in_array($extension, explode("\n", $farfuture_extensions))) {
// Remove all previously set Cache-Control headers, because we're going to
// override it. Since multiple Cache-Control headers might have been set,
// simply setting a new, overriding header isn't enough: that would only
// override the *last* Cache-Control header. Yay for PHP!
if (function_exists('header_remove')) {
header_remove('Cache-Control');
}
else {
drupal_set_header("Cache-Control:");
drupal_set_header("Cache-Control:");
}
// Set a far future Cache-Control header (480 weeks), which prevents
// intermediate caches from transforming the data and allows any
// intermediate cache to cache it, since it's marked as a public resource.
drupal_set_header("Cache-Control: max-age=290304000, no-transform, public");
// Set a far future Expires header. The maximum UNIX timestamp is somewhere
// in 2038. Set it to a date in 2037, just to be safe.
drupal_set_header("Expires: Tue, 20 Jan 2037 04:20:42 GMT");
// Pretend the file was last modified a long time ago in the past, this will
// prevent browsers that don't support Cache-Control nor Expires headers to
// still request a new version too soon (these browsers calculate a
// heuristic to determine when to request a new version, based on the last
// time the resource has been modified).
// Also see http://code.google.com/speed/page-speed/docs/caching.html.
drupal_set_header("Last-Modified: Wed, 20 Jan 1988 04:20:42 GMT");
}
// GET requests with an "Accept-Encoding" header that lists "gzip".
if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) {
// Only send gzipped files for some file extensions (it doesn't make sense
// to gzip images, for example).
if (in_array($extension, explode("\n", CDN_BASIC_FARFUTURE_GZIP_EXTENSIONS))) {
// Ensure a gzipped version of the file is stored on disk, instead of
// gzipping the file on every request.
$gzip_path = file_directory_path() . '/' . CDN_BASIC_FARFUTURE_GZIP_DIRECTORY . "/{$path}.{$ufi}.gz";
if (!file_exists($gzip_path)) {
_cdn_basic_farfuture_create_directory_structure(dirname($gzip_path));
file_put_contents($gzip_path, gzencode(file_get_contents($path), 9));
}
// Make sure zlib.output_compression does not gzip our gzipped output.
ini_set('zlib.output_compression', '0');
// Prepare for gzipped output.
drupal_set_header("Content-Encoding: gzip");
$path = $gzip_path;
}
}
// Conditional GET requests (i.e. with If-Modified-Since header).
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
// All files served by this function are designed to expire in the far
// future. Hence we can simply always tell the client the requested file
// was not modified.
drupal_set_header("HTTP/1.1 304 Not Modified");
}
else {
_cdn_transfer_file($path);
}
exit;
}