Nginx: Alternativa para se dentro de blocos de localização para cabeçalhos de cache baseados em uma variável

2

Estou tentando usar o cache de páginas Nginx em vez do cache do Wordpress. O cache parece funcionar bem, mas estou tendo problemas para definir cabeçalhos de armazenamento em cache condicionais com base em uma variável - se um usuário está conectado ao wordpress. Se um usuário estiver logado, eu quero que nenhum cabeçalho de cache seja aplicado, se não a página pode ser armazenada em cache por um dia tanto pelo Wordpress quanto pelo CDN. Eu estou achando que só posso adicionar um cabeçalho dentro de uma declaração if.

Eu li (mas não entendi completamente, porque é tarde aqui) [se é mal] [1]. Eu também encontrei uma resposta na troca de pilha (no meu laptop, não consigo encontrá-lo agora) que disse dentro de um bloco if apenas um add_header funciona.

Alguém pode me dar ideias para uma alternativa que funcione melhor? Eu sei que posso combinar o expires com o cache-control, mas eu quero mais cabeçalhos lá, mais eu quero entender e aprender.

Aqui está uma configuração significativamente simplificada com as partes relevantes em vigor.

server {
  server_name example.com;

  set $skip_cache 0;
  # POST requests and urls with a query string should always go to PHP
  if ($request_method = POST) {
    set $skip_cache 1;
  }
  if ($query_string != "") {
    set $skip_cache 1;
  }
  # Don't cache uris containing the following segments.
  if ($request_uri ~* "/wp-admin/|/admin-*|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") {
    set $skip_cache 1;
  }
  # Don't use the cache for logged in users or recent commenters
  if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
    set $skip_cache 1;
  }

  location / {
    try_files $uri $uri/ /blog/index.php?args;
  }

  location ~ \.(hh|php)$ {
    fastcgi_keep_conn on;
    fastcgi_intercept_errors on;
    fastcgi_pass  php;
    include  fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

    # Cache Stuff
    fastcgi_cache CACHE_NAME;
    fastcgi_cache_valid 200 1440m;
    add_header X-Cache $upstream_cache_status;

    fastcgi_cache_methods GET HEAD;
    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache $skip_cache;

    add_header Z_ABCD "Test header";

    if ($skip_cache = 1) {
      add_header Cache-Control "private, no-cache, no-store";
      add_header CACHE_STATUS "CACHE NOT USED";
    }
    if ($skip_cache = 0) {
      add_header Cache-Control "public, s-maxage = 240";
      expires 1d;
      add_header CACHE_STATUS "USED CACHE";
    }

    add_header ANOTHER_HEADER "message";
    }
}
    
por Tim 15.01.2016 / 09:39

2 respostas

0

Eu mesmo criei uma solução, baseada na resposta @Richard Smith, desde que não fizesse exatamente o que eu precisava. Eu usei o cabeçalho de controle de cache mais e descartei a diretiva de expiração desnecessária.

Isso fica dentro do bloco do servidor

if ($skip_cache = 1) {
  set $cacheControl "private, max-age=0, s-maxage=0, no-cache, no-store";
}
if ($skip_cache = 0) {
  set $cacheControl "public, max-age=86400, s-maxage=86400";
}

Então isso vai dentro de cada bloco de localização aplicável

add_header Cache-Control $cacheControl;

Isso significa que não é necessário "se" dentro do bloco de localização. Acho que isso resolve o problema, mas ainda estou interessado se alguém tiver idéias alternativas.

    
por 15.01.2016 / 22:23
1

Uma alternativa à diretiva if é a diretiva map . E supondo que o CACHE_STATUS vs CACHE_STATIC seja apenas um erro de digitação na sua pergunta, você poderia tentar isto:

map $http_cookie $expires {
    default 1d;
    ~*wordpress_logged_in off;
}
map $http_cookie $control {
    default "public, s-maxage = 240";
    ~*wordpress_logged_in "private, no-cache, no-store";
}
map $http_cookie $status {
    default "USED CACHE";
    ~*wordpress_logged_in "CACHE NOT USED";
}
server {
    ...
    location ~ \.(hh|php)$ {
        ...
        expires $expires;
        add_header Cache-Control $control;
        add_header CACHE_STATUS $status;
    }
}

As diretivas map devem ser colocadas dentro do contêiner http (no mesmo nível que o bloco server ), conforme mostrado acima.

A diretiva map é documentada aqui .

    
por 15.01.2016 / 11:34

Tags