Облако RackSpace Удаляет СЕАНС $, если URL-Адрес Имеет Определенные Расширения Файлов


Ситуация

Я создаю обучающий видео-сайт для клиента в облаке RackSpace с использованием традиционного стека ЛАМП (в облаке Rackspace есть как окна, так и стеки ламп). Видео и другие медиафайлы, которые я размещаю на этом сайте, должны быть защищены, так как мой клиент взимает деньги за доступ к ним. Там нет 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 или, если я даже добавлю параметр запроса, лак будет обойден, и PHP-скрипт сможет получить сеанс. Никаких проблем, верно? Я просто добавлю бессмысленный параметр запроса на мои запросы!

Вот в чем загвоздка: Медиафайлы, которые я обслуживаю через эту систему, запрашиваются через скомпилированные SWF-файлы, над которыми у меня нет никакого контроля. Они генерируются сторонним программным обеспечением, и у меня нет надежды добавить или изменить URL-адреса, которые они запрашивают.

Есть ли у меня какие-либо другие варианты по этому поводу?

Обновление: Я должен отметить, что я проверил это поведение с помощью поддержки RackSpace, и они сказали, что они ничего не могут с этим поделать.

Author: macinjosh, 2010-02-12

2 answers

Если запрашивающее приложение flash выполняет перенаправления, я бы попытался ответить перенаправлением на первый запрос и переписать второй, например

GET .../29.jpg

До

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

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

Если нет (кстати. всегда), я бы явно отправлял заголовки вместе с доставкой статических файлов, которые Лак принимает и действует соответственно, что-то вроде

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-файле могут привести к досадным ошибкам при добавлении заголовков.

 2
Author: initall, 2010-02-12 08:29:42

У меня такая же ситуация, и я связался с Rackspace в надежде на лучший ответ.

У меня есть один! Они собрали часто задаваемые вопросы с описанием полудюжины способов обхода/изменения кэширования:

Http://cloudsites.rackspacecloud.com/index.php/How_can_I_bypass_the_cache%3F

 0
Author: Cam, 2010-05-26 17:07:08