RackSpace Cloud удаляет $_SESSION, если URL-адрес имеет определенные расширения файлов
-
20-09-2019 - |
Вопрос
Ситуация
Я создаю сайт видеообучения для клиента в облаке RackSpace, используя традиционный стек LAMP (в облаке RackSpace есть стеки как Windows, так и LAMP).Видео и другие медиафайлы, которые я размещаю на этом сайте, должны быть защищены, поскольку мой клиент взимает деньги за доступ к ним.Здесь нет DRM или подобных забавных дел, по сути, мы храним файлы за пределами корня веб-страницы и используем PHP для аутентификации пользователей, прежде чем они смогут получить доступ к файлам, используя mod_rewrite для запуска запроса через PHP.
Допустим, пользователь запрашивает файл по этому URL-адресу:
http://www.example.com/uploads/preview_image/29.jpg
Я использую mod_rewrite, чтобы переписать этот URL-адрес:
http://www.example.com/files.php?path=%2Fuploads%2Fpreview_image%2F29.jpg
Вот упрощенная версия скрипта files.php:
<?php
// Setups the environment and sets $logged_in
// This part requires $_SESSION
require_once('../../includes/user_config.php');
if (!$logged_in) {
// Redirect non-authenticated users
header('Location: login.php');
}
// This user is authenticated, continue
$content_type = "image/jpeg";
// getAbsolutePathForRequestedResource() takes
// a Query Parameter called path and uses DB
// lookups and some string manipulation to get
// an absolute path. This part doesn't have
// any bearing on the problem at hand
$file_path = getAbsolutePathForRequestedResource($_GET['path']);
// At this point $file_path looks something like
// this: "/path/to/a/place/outside/the/webroot"
if (file_exists($file_path) && !is_dir($file_path)) {
header("Content-Type: $content_type");
header('Content-Length: ' . filesize($file_path));
echo file_get_contents($file_path);
} else {
header('HTTP/1.0 404 Not Found');
header('Status: 404 Not Found');
echo '404 Not Found';
}
exit();
?>
Проблема
Начну с того, что для меня это прекрасно работает.На местных тестовых машинах это работает как шарм.Однако после развертывания в облаке он перестает работать.После некоторой отладки выяснилось, что если запрос к облаку имеет определенные расширения файлов, например .JPG, .PNG или .SWF (т.е.расширения обычно статических медиафайлов.) запрос направляется в систему кэширования под названием Varnish.Конечным результатом этой маршрутизации является то, что к тому времени, как весь этот процесс доходит до моего PHP-скрипта, сеанса уже нет.
Если я изменю расширение URL-адреса на .PHP или даже добавлю параметр запроса, Varnish будет пропущен, и сценарий PHP сможет получить сеанс.Нет проблем, верно?Я просто добавлю в свои запросы бессмысленный параметр запроса!
Вот в чем загвоздка: Медиа-файлы, которые я обслуживаю через эту систему, запрашиваются через скомпилированные SWF-файлы, над которыми я не имею никакого контроля.Они генерируются сторонним программным обеспечением, и у меня нет надежды добавить или изменить запрашиваемые ими URL-адреса.
Есть ли у меня какие-либо другие варианты по этому поводу?
Обновлять: Должен отметить, что я проверил это поведение при поддержке RackSpace, и они сказали, что ничего не могут с этим поделать.
Решение
Если запрашивающее флэш-приложение следует за перенаправлениями, я бы попытался ответить перенаправлением на первый запрос и переписать второй, например.
GET .../29.jpg
к
header("Status: 302 Moved temporarily");
header("Location: .../r.php?i=29.jpg&random=872938729348");
Затем ваш r.php доставляет файл по второму запросу.
Если нет (кстати.всегда), я бы явно отправлял заголовки вместе с доставкой статических файлов, которые Varnish принимает и действует соответствующим образом, что-то вроде
header("Cache-Control: no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
И:я бы поместил exit();
команда после вашего первого header()
оператор, чтобы убедиться, что остальная часть сценария не будет выполнена. header()
отправляет только заголовки.
Я считаю, что это также более надежно в использовании ob_start()
поскольку пробелы в вашем файле PHP могут привести к досадным ошибкам при добавлении заголовков.
Другие советы
У меня такая же ситуация, и я связался с Rackspace в надежде получить лучший ответ.
Я получил один!Они составили FAQ, в котором описаны полдюжины способов обойти/изменить кеширование:
http://cloudsites.rackspacecloud.com/index.php/How_can_I_bypass_the_cache%3F