Nginx não homenageando deve-revalidar

3

Eu quero usar o nginx como um proxy reverso de armazenamento em cache. Eu também tenho um requisito especial, que eu pensei que poderia ser realizado com nginx.

Estou usando o Amazon s3 como servidor de origem e uso URLs assinados para proteger o conteúdo. Assim, cada usuário recebe um URL exclusivo que expira depois de um certo tempo. Mesmo difícil, cada usuário tem uma URL única, para fazer cache nginx o conteúdo independentemente, eu defini a chave de cache como apenas consiting do nome do arquivo de solicitação (veja a configuração abaixo).

Isso funciona muito bem até agora. O problema é que, se o URL da solicitação for inválido, porque a assinatura na cadeia de consulta é muito antiga ou inválida, o servidor entrega o arquivo de qualquer maneira. Porque está em cache.

Confirmei que a solicitação inicial deve conter uma assinatura válida. Se a assinatura do pedido do usuário for inválida, o nginx não poderá buscá-la no servidor (é claro).

Agora, o que eu quero é uma nova consulta do arquivo em todas as solicitações. Essa nova pesquisa deve ocorrer com o URL especificado pelo usuário. Se a solicitação for bem-sucedida, o arquivo em cache deverá ser entregue.

Este é exatamente o comportamento que deve ser realizado usando Cache-control: must-revalidate

Então eu configurei este cabeçalho no meu servidor de origem (amazon s3).

Então percebi que o nginx não se comporta de acordo.

Portanto, o arquivo é entregue diretamente do cache sem validar com o servidor de origem. E assim a assinatura ruim não é reconhecida e o usuário pode fazer o download.

Pergunta 1: Existe uma maneira de tornar os cabeçalhos de revalidação de obrigação de honra do nginx neste contexto?

Aqui está o meu arquivo de configuração

proxy_cache_path /home/sbgag/cache keys_zone=MYZONE:10m inactive=365d max_size=10g;
server {
        listen       80;
        server_name test.mydomain.com;
        location / {
                proxy_pass          http://s3-eu-west-1.amazonaws.com;
                proxy_set_header    Host s3-eu-west-1.amazonaws.com;
                proxy_set_header    X-Real-IP $remote_addr;
                proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_cache_key         "$request_filename";
                more_set_headers "X-My-Proxy-Cache-Key $request_filename";
                more_set_headers "X-My-Proxy-Cache-realpath_root $realpath_root";
                more_set_headers "X-My-Proxy-Cache-uri $uri";
                proxy_cache            MYZONE;
                proxy_cache_valid      200  365d;
                proxy_cache_use_stale  error timeout invalid_header updating http_500 http_502 http_503 http_504;
                more_set_headers "X-AppServer $upstream_addr";           # Backend Server / Port
                more_set_headers "X-AppServer-Status $upstream_status";  # Backend HTTP Status
                more_set_headers "X-Cache $upstream_cache_status";       # HIT / MISS / BYPASS / EXPIRED
        }
}

Também encontrei este changelog

*) Feature: the "proxy_cache_revalidate", "fastcgi_cache_revalidate",
   "scgi_cache_revalidate", and "uwsgi_cache_revalidate" directives.

Então eu pensei em brincar com isso. Depois de trazer meu nginx para a versão mais recente, configurei meu tempo de cache para 0s. Com 0s, o arquivo nunca é armazenado em cache, portanto, configurei para 1s.

Isso produz quase o comportamento que eu quero. Isso faz com que o arquivo seja revalidado no servidor após 1s. Em seguida, é validado com o URL assinado, o usuário fornecido. Se estiver incorreto, ele falhará. Além disso, o arquivo não é excluído, porque nginx aparece para excluir os arquivos não imediatamente, mas apenas quando o espaço está ficando cheio. Portanto, mesmo que o arquivo tenha expirado e até mesmo se outro cliente forneceu um URL inválido, o próximo cliente com um URL válido pode fazer o download do cache.

No intervalo de tempo de 1 segundo, porém, todos podem fazer download, mas isso não é realmente uma preocupação para mim.

Ok, isso é quase o que eu quero, o que eu não gosto é que é um trabalho feio que é baseado em um comportamento mais acidental do que funcional.

Pergunta 2: Não existe uma maneira melhor?

O que eu gostaria mais seria passar solicitações para um script de validação no qual eu possa validar a solicitação com meu próprio script no backgorund. E somente se esse script retornar bem-sucedido, o download será permitido. E, em seguida, fazendo uso de algoritmos de cache nginx existentes e comprovados.

Maby mesmo uma regra de reescrita faria. Reescrevendo para um script com um mapa de reescrita e apenas exibindo o URL quando a validação foi um sucesso.

Qualquer entrada é appriciated!

    
por The Shurrican 09.01.2014 / 18:14

1 resposta

0

Acho que o que você está procurando está realmente adicionando isso:

proxy_cache_bypass $ http_cache_control;

Dessa forma, enviar uma solicitação com o cabeçalho configurado Cache-Control: must-revalidate irá ignorar o cache.

    
por 16.11.2015 / 14:50