Pergunta

A situação

Estou criando um site de treinamento em vídeo para um cliente na nuvem de rackspace usando a pilha de lâmpadas tradicional (a nuvem do Rackspace tem janelas e pilhas de lâmpadas). Os vídeos e outros arquivos de mídia que estou servindo neste site precisam ser protegidos à medida que meu cliente cobra dinheiro pelo acesso a eles. Não há DRM ou negócios engraçados como esse, essencialmente armazenamos os arquivos fora da raiz da web e usamos o PHP para autenticar os usuários antes que eles possam acessar os arquivos usando o MOD_REWRITE para executar a solicitação através do PHP.

Então, digamos que o usuário solicite um arquivo neste URL:

http://www.example.com/uploads/preview_image/29.jpg

Estou usando mod_rewrite para reescrever esse URL para:

http://www.example.com/files.php?path=%2Fuploads%2Fpreview_image%2F29.jpg

Aqui está uma versão simplificada do script 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();

?>

O problema

Deixe -me começar dizendo que isso funciona perfeitamente para mim. Nas máquinas de teste local, funciona como um charme. No entanto, uma vez implantado na nuvem, ela para de funcionar. Após alguma depuração,, se uma solicitação para a nuvem tiver certas extensões de arquivo como .jpg, .png ou .swf (isto é, extensões de arquivos de mídia tipicamente estáticos.) A solicitação é roteada para um sistema de cache chamado Varnish. O resultado final desse roteamento é que, quando todo esse processo chega ao meu script PHP, a sessão não está presente.

Se eu alterar a extensão no URL para .php ou se eu adicionar um verniz de parâmetro de consulta, é ignorado e o script PHP poderá obter a sessão. Sem problemas, certo? Vou apenas adicionar um parâmetro de consulta sem sentido aos meus pedidos!

Aqui está o problema: Os arquivos de mídia que estou servindo através deste sistema estão sendo solicitados por meio de arquivos SWF compilados sobre os quais tenho controle. Eles são gerados por software de terceiros e não tenho esperança de adicionar ou alterar os URLs que solicitam.

Existem outras opções que tenho sobre isso?

Atualizar: Devo observar que verifiquei esse comportamento com o suporte do Rackspace e eles disseram que não há nada que possam fazer sobre isso.

Foi útil?

Solução

Se o aplicativo flash solicitador estiver seguindo os redirecionamentos, eu tentaria responder com um redirecionamento no primeiro pedido e reescrever o segundo, por exemplo,

GET .../29.jpg

para

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

Em seguida, seu R.Php entrega o arquivo na segunda solicitação.

Se não (btw. Sempre), eu enviaria explicitamente cabeçalhos junto com a entrega dos arquivos estáticos que o verniz aceita e age de acordo, algo como

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");

E: eu colocaria o exit(); comando depois do seu primeiro header() Declaração para garantir que o restante do script não seja executado. header() envia apenas cabeçalhos.

Acho também mais confiável de usar ob_start() Como o espaço em branco no seu arquivo PHP pode levar a erros irritantes ao adicionar cabeçalhos.

Outras dicas

Eu tenho a mesma situação e entrei em contato com a Rackspace na esperança de uma resposta melhor.

Eu tenho um! Eles reuniram uma Perguntas frequentes que descrevem meia dúzia de maneiras de ignorar/modificar o cache:

http://cloudsite.rackspacecloud.com/index.php/how_can_i_bypass_the_cache%3f

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top