I am trying to set up a site so that users only have access to their own images and audio files. To to this I am using variables in the URL such as:
<img src="/public/get_file.php?type=image&file=pic001.png" />
On the front-end I am using React JS (not sure if that is important to this issue). But on the backend, the PHP script will validate that the user is logged in (just by checking a simple SESSION variable) and look for that file in the user’s data directory (based on the user id in their SESSION variable). If it exists it will return it to the user using XSendFile.
The problem I am having is that every time that the user tries to access the files there is a bit of a delay before they load. This is telling me that they probably are not being cached by the browser.
Why are the files not getting cached? Does it have to do with the URL parameter or the use of PHP/XSendFile?
What can I do to allow my files (images/audio) to be cached?
Update
As requested here is my get_file.php:
<?php
session_start();
if (empty($_SESSION['auth']['id'])){
exit;
}
require_once("../../api_modules/settings.php");
$developer_id = $_SESSION['auth']['id'];
$type = preg_replace('/[^-a-zA-Z0-9_]/', '', $_GET['type']);
$file = preg_replace('/[^-a-zA-Z0-9_.]/', '', $_GET['file']);
$file = preg_replace('/[.]{2,}/', '', $file);
$project_id = preg_replace('/[^0-9]/', '', $_GET['project_id']);
$developer_id = preg_replace('/[^0-9]/', '', $developer_id);
if ($type == "image")
$file = FILEPATH ."files/$developer_id/$project_id/images/thumbs/88x88/$file";
else if ($type == "full_image")
$file = FILEPATH ."files/$developer_id/$project_id/images/originals/$file";
else if ($type == "audio"){
$file = FILEPATH ."files/$developer_id/$project_id/audio/$file";
}
else {
exit;
}
header("X-Sendfile: $file");
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
4
Answers
Try to use this kind of header (PHP code) with for example
header('Cache-Control: must-revalidate');
for download a private filesAnd use Cache control with a best option for your solution like
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
isnocache
.See http://php.net/manual/en/function.session-cache-limiter.php on how to set a different value that fits your needs.
How do you generate the images? Do you have a public local directory or it is loaded by a CDN (remotely)?
Maybe it can help: HOW TO CACHE IMAGES GENERATED BY PHP
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: