nginx: Redireciona tudo, exceto alguns diretórios para novo nome de host

1

Estou atendendo a um serviço da Web (API + Webiste) por meio do nginx e seu nome de domínio canônico foi alterado recentemente. A API é dividida do site do usuário por subdiretórios (por exemplo, / api / e / download / fazem parte da API, o restante pertence ao site).

Gostaria agora de redirecionar a parte do site para o novo nome de domínio, mas servir as solicitações da API sem redirecionamentos (para manter a carga do servidor inativa).

Como o servidor da Web pode ser acessado por meio de vários domínios, eu preciso redirecionar tudo que não corresponda ao novo canônico; algo como

IF request-domain != new-domain
 AND resource not in (/api/, /download/):
   redirect to new domain

ELSE:
   # serve site
   proxy_pass   http://app_server;

Eu não encontrei uma maneira adequada no nginx para fazer a comparação (dupla) negativa, e não posso invertê-los para uma comparação positiva, porque os nomes de domínio alternativos e os recursos não-API são bastante Eu não quero manter na configuração do nginx.

Qualquer ideia seria muito apreciada!

    
por Stefan Kögl 23.09.2011 / 10:24

2 respostas

6

No nginx, você geralmente não quer usar se para alterar o comportamento com base no cabeçalho do host ou no uri. Você precisa de um segundo servidor:

server {
  # Make sure this listen matches the one in the second server (minus default flag)
  listen 80;

  server_name new-domain;

  # All your normal processing.  Is it just proxy_pass?
  location / {
    proxy_pass http://app_server;
  }
}

server {
  # If you listen on a specific ip, make sure you put it in the listen here
  # default means it'll catch anything that doesn't match a defined server name
  listen 80 default;

  server_name old-domain; # and everything else, but it's good to define something

  # Everything that doesn't match /api/ or /download/
  location / {
    rewrite ^ http://new-domain$request_uri? permanent;
  }

  # You may want some common proxy_set_header lines here in the server
  # if you need them

  location /api/ {
    proxy_pass http://app_server;
  }

  location /download/ {
    proxy_pass http://app_server;
  }
}
    
por 23.09.2011 / 13:55
0

O Nginx não permite várias declarações if aninhadas, mas você pode definir variáveis, algo assim:

    server_name _;

    if ($http_host !~ new-domain) {
        set $var D;
    }
    if ($request_uri !~ (/api|/download)) {
        set $var "${var}U";
    }
    if ($var = DU) {
        rewrite ^(.*)$ http://new-domain$request_uri last;
        break;
    }

Sobre a condição else , você deve fazer isso em um host virtual separado.

    
por 23.09.2011 / 12:06