RackSpace Cloud Strips $ _SESSION, если у URL есть определенные расширения файлов

Ситуация

Я создаю сайт для видеообработки для клиента в облаке 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(); ?> в <?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, и они сказали, что они ничего не могут с этим поделать.

Solutions Collecting From Web of "RackSpace Cloud Strips $ _SESSION, если у URL есть определенные расширения файлов"

Если запрашивающее флэш-приложение выполняет следующие переадресации, я бы попытался ответить с переадресацией на первый запрос и переписать второй, например

 GET .../29.jpg 

в

 header("Status: 302 Moved temporarily"); header("Location: .../r.php?i=29.jpg&random=872938729348"); 

Затем ваш r.php доставляет файл по второму запросу.

Если нет (btw. Always), я бы явно отправлял заголовки вместе с доставкой статических файлов, которые 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