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.
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!
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.
Tags proxy cache nginx reverse-proxy http