nginx: Como posso definir diretivas proxy_ * apenas para URIs correspondentes?

1

Estou nisso há horas e não consigo descobrir uma solução limpa.

Basicamente, eu tenho uma configuração de proxy nginx, que funciona muito bem, mas eu gostaria de manipular alguns URLs mais manualmente. Especificamente, há 2-3 locais para os quais gostaria de definir proxy_ignore_headers como Set-Cookie para forçar nginx a armazená-los em cache (o nginx não armazena em cache as respostas com Set-Cookie conforme link ).

Portanto, para estas localizações, tudo o que gostaria de fazer é definir proxy_ignore_headers Set-Cookie;

Eu tentei tudo o que consegui pensar fora da configuração e da duplicação de todos os valores de configuração, mas nada funciona.

Eu tentei:

  • Aninhando diretivas de local, esperando que o local interno que coincida com meus arquivos apenas definiria esse valor e herdaria o restante, mas esse não era o caso - parecia ignorar qualquer coisa definida no local externo, principalmente proxy_pass e acabo com um 404).
  • Especificando a diretiva proxy_cache_valid em um bloco if que corresponde a $ request_uri, mas o nginx reclama que não é permitido (a diretiva " proxy_cache_valid " não é permitida aqui).
  • Especificando uma variável igual a "Set-Cookie" em um bloco if, e depois tentando definir proxy_cache_valid para essa variável mais tarde, mas nginx não está permitindo variáveis para este caso e vomita.

Deve ser tão simples - modificar / anexar uma única diretiva para algumas solicitações, e ainda assim não consegui fazer o nginx fazer isso.

O que estou perdendo aqui?

Existe pelo menos uma maneira de agrupar diretivas comuns em um bloco reutilizável e ter vários blocos de localização se referirem a ele, depois de adicionar seus próprios bits exclusivos?

Obrigado.

Apenas para referência, o local / bloco principal é incluído abaixo, junto com minha diretiva proxy_ignore_headers com falha para um URI específico.

location / {
  # Setup var defaults
  set $no_cache "";

  # If non GET/HEAD, don't cache & mark user as uncacheable for 1 second via cookie
  if ($request_method !~ ^(GET|HEAD)$) {
    set $no_cache "1";
  }

  if ($http_user_agent ~* '(iphone|ipod|ipad|aspen|incognito|webmate|android|dream|cupcake|froyo|blackberry|webos|s8000|bada)') {
    set $mobile_request '1';
    set $no_cache "1";
  }

  # feed crawlers, don't want these to get stuck with a cached version, especially if it caches a 302 back to themselves (infinite loop)
  if ($http_user_agent ~* '(FeedBurner|FeedValidator|MediafedMetrics)') {
    set $no_cache "1";
  }

  # Drop no cache cookie if need be
  # (for some reason, add_header fails if included in prior if-block)
  if ($no_cache = "1") {
    add_header Set-Cookie "_mcnc=1; Max-Age=17; Path=/";
    add_header X-Microcachable "0";
  }

  # Bypass cache if no-cache cookie is set, these are absolutely critical for Wordpress installations that don't use JS comments
  if ($http_cookie ~* "(_mcnc|comment_author_|wordpress_(?!test_cookie)|wp-postpass_)") {
    set $no_cache "1";
  }

  if ($request_uri ~* wpsf-(img|js)\.php) {
    proxy_ignore_headers Set-Cookie;
  }

  # Bypass cache if flag is set
  proxy_no_cache $no_cache;
  proxy_cache_bypass $no_cache;

  # under no circumstances should there ever be a retry of a POST request, or any other request for that matter
  proxy_next_upstream off;
  proxy_read_timeout 86400s;

  # Point nginx to the real app/web server
  proxy_pass http://localhost;

  # Set cache zone
  proxy_cache microcache;

  # Set cache key to include identifying components
  proxy_cache_key $scheme$host$request_method$request_uri$mobile_request;

  # Only cache valid HTTP 200 responses for this long
  proxy_cache_valid 200 15s;

  #proxy_cache_min_uses 3;

  # Serve from cache if currently refreshing
  proxy_cache_use_stale updating timeout;

  # Send appropriate headers through
  proxy_set_header Host $host;
  # no need for this proxy_set_header X-Real-IP $remote_addr;
  # no need for this proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

  # Set files larger than 1M to stream rather than cache
  proxy_max_temp_file_size 1M;

  access_log /var/log/nginx/androidpolice-microcache.log custom;
}
    
por Artem Russakovskii 26.03.2012 / 02:53

1 resposta

1

Depois de tentar literalmente 10 coisas diferentes e consultar Fenn Bailey do link , tenho que recorrer à solução include, que parece ser a única coisa que evita a duplicação de código e realmente funciona.

Mudei todas as diretivas da localização / {} para o seu próprio arquivo e fiz isso:

location / {
  include /etc/nginx/vhosts/androidpolice-root.conf;
}

location ~* wpsf-(img|js)\.php {
  include /etc/nginx/vhosts/androidpolice-root.conf;
  proxy_ignore_headers "Set-Cookie" "Cache-Control";
}

Neste ponto, estou bastante chocado com a inflexibilidade do nginx quando se trata de ifs e condicionais - essas coisas devem ser tão triviais, mas não são.

A propósito, eu estou no último nginx 1.1.17.

    
por 26.03.2012 / 05:21