Caching images in browser with URL parameters and XSendFile Caching images in browser with URL parameters and XSendFile php php

Caching images in browser with URL parameters and XSendFile


I think this is a duplicate.

But since there is a bounty lets try to adapt your code together with the suggested solution there.

You need to check that Apache has mod_expires and mod_headers enabled and working properly.

And then before you start real output check if file was modified:

...$last_modified_time = filemtime($file); $etag = md5_file($file);// always send headersheader("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT"); header("Etag: $etag"); // exit if not modifiedif (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time ||     @trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) {     header("HTTP/1.1 304 Not Modified");     exit; } else {    header("X-Sendfile: $file");    header("Content-type: application/octet-stream");    header('Content-Disposition: attachment; filename="' . basename($file) . '"');}


Try to use this kind of header (PHP code) with for example header('Cache-Control: must-revalidate'); for download a private files

$mime_types = array(        'pdf' => 'application/pdf',        'txt' => 'text/plain',        'html' => 'text/html',        'exe' => 'application/octet-stream',        'zip' => 'application/zip',        'doc' => 'application/msword',        'xls' => 'application/vnd.ms-excel',        'ppt' => 'application/vnd.ms-powerpoint',        'gif' => 'image/gif',        'png' => 'image/png',        'jpeg' => 'image/jpg',        'jpg' => 'image/jpg',        'php' => 'text/plain'        );if ($mimeType == '') {    $file_ext = strtolower(substr(strrchr($file_path.$file_name_gen, '.'), 1));    if(array_key_exists($file_ext, $mime_types)) $mime_type = $mime_types[$file_ext];    else $mime_type = 'application/force-download';    }ob_start();header('Content-Disposition: attachment; filename="' . $file_name_gen . '"');header('Content-Type: '.$mime_type);header('Expires: 0');header('Cache-Control: must-revalidate');header('Pragma: public');header('Content-Length: ' . filesize($file_path.$file_name));ob_clean();flush();readfile($file_path.$file_name);

And use Cache control with a best option for your solution like

Cache-Control: max-age=<seconds>Cache-Control: max-stale[=<seconds>]Cache-Control: min-fresh=<seconds>Cache-Control: no-cache Cache-Control: no-storeCache-Control: no-transformCache-Control: only-if-cached

BTW. $file_name_gen is a genuine file name on the server and $file_name is a file name users see for more file privacy.


For the record, this is mostly due to the fact the default value of session.cache_limiter is nocache.

See http://php.net/manual/en/function.session-cache-limiter.php on how to set a different value that fits your needs.