Nginx: Acesse o mesmo conteúdo de vários URLs

1

Estou tentando configurar o nginx para que o mesmo conteúdo estático possa ser acessado por meio de dois URLs diferentes sem nenhum redirecionamento.

Por exemplo, se o cliente inserir /path/to/A em seu navegador, quero que recupere o mesmo conteúdo que /path/to/B .

Eu tentei usar rewrite , mas o Nginx parece me dar um redirecionamento 301 nesse caso.

Por exemplo:

server {
    root /my/www/data;

    rewrite ^/path/to/A(.*)$ /path/to/B$1;
    # Note: /my/www/data/path/to/B *does* actually exist on disk.
    # However, the .../A version does not.
}

Acho que uma maneira de fazer isso seria fazer um link simbólico de /my/www/data/A para apontar para /my/www/data/B , mas estou tentando fazer isso usando a configuração do servidor, não truques do sistema de arquivos.

Minhas perguntas são:

  1. Como isso pode ser feito?
  2. Em que circunstâncias o módulo rewrite faz um redirecionamento interno em vez de enviar um código 30x para o cliente? Eu não posso dizer claramente a partir dos documentos.

Observação: isso é muito semelhante a outra pergunta: Nxginx reescreve o URL sem redirecionamento No entanto, esse não é muito detalhado.

EDIT: Aqui está uma configuração real, com comandos curl , etc:

Primeiro, a configuração:

server {

    root /usr/share/nginx/www/mydata;
    index index.html index.htm;

    # Make site accessible from http://localhost/
    server_name localhost;

    location / {
        try_files $uri $uri/ =404;
    }

    rewrite_log on;    
    rewrite ^/A(.*)$ /B$1 last;
}

Agora, meu conteúdo da web root:

$ find /usr/share/nginx/www/mydata/
/usr/share/nginx/www/mydata/
/usr/share/nginx/www/mydata/B
/usr/share/nginx/www/mydata/B/index.html
/usr/share/nginx/www/mydata/index.html

E com isso em execução, aqui está o que eu recebo com curl :

$ curl -i 'http://localhost/A'
HTTP/1.1 301 Moved Permanently
Server: nginx/1.2.1
...
Location: http://localhost/B/
...
<snipped>

No entanto, percebo que /A/ (com barra final) e /A/index.html funcionam bem:

$ curl -i 'http://localhost/A/'
HTTP/1.1 200 OK
Server: nginx/1.2.1
<snip - I see data for B/index.html, as I expect>

(Mesmos resultados para /A/index.html ).

Portanto, somente no primeiro caso recebo um redirecionamento 301, embora minha configuração nunca mencione tal coisa explicitamente.

Qual é o problema?

    
por jwd 10.02.2016 / 07:03

3 respostas

1

Ok, depois de algumas experiências, encontrei algumas soluções diferentes.

Para recapitular, quero que /A permaneça como /A no navegador do usuário (não há redirecionamento para /B ), mas ainda quero que ele exiba o conteúdo de /B .

Opção 1: Use um symlink (: Isso funciona, mas você precisa acessar o sistema de arquivos. Evita o problema.

Opção 2: Impedir o redirecionamento automático de barra invertida 301 usando um bloco de localização de correspondência exata ( = ):

location = /A {
    rewrite "" /B/;
}
# Note: the below should probably be inside a location block.
rewrite ^/A(.+)$ /B$1 last;

Descobri isso dos documentos do Nginx :

without the trailing slash, a permanent redirect with the code 301 will be returned to the requested URI with the slash appended. If this is not desired, an exact match of the URI and location could be defined

Opção 3: Use um redirecionamento de /A para /A/ , mas faça isso manualmente, para que ele não seja retornado ao cliente como um redirecionamento (reescrito) para /B/ :

location = /A {
    return 301 /A/;
}
location /A/ {
    rewrite ^/A/(.*)$ /B/$1 last;
}

Acabei indo com a opção 3, pois faz com que /A se comporte como /B , incluindo o redirecionamento à direita da barra (mas no lugar certo, agora).

    
por 11.02.2016 / 17:00
1

rewrite in nginx não leva ao status 301 em geral (a menos que seja explicitamente configurado), então 301 provavelmente é causado por outras partes do seu nginx config.

rewrite é a maneira correta de alcançar o que você quer, sua abordagem está correta.

    
por 10.02.2016 / 07:50
1

Esse é o comportamento padrão de servidores da web mostrando índices de diretório, por exemplo, o Apache faz o mesmo. Sempre que você solicitar apenas "diretório", ele será redirecionado para "diretório /" assim.

A documentação do Apache é explícita, por exemplo O link diz

A "trailing slash" redirect is issued when the server receives a request for a URL http://servername/foo/dirname where dirname is a directory. Directories require a trailing slash, so mod_dir issues a redirect to http://servername/foo/dirname/.

Parece que a documentação do nginx é um pouco mais discreta, por exemplo O link diz apenas:

The ngx_http_autoindex_module module processes requests ending with the slash character (‘/’) and produces a directory listing. Usually a request is passed to the ngx_http_autoindex_module module when the ngx_http_index_module module cannot find an index file.

Não explica o passo anterior, como o pedido chega ao final com a barra, que parece estar implícito.

Há outra pergunta antiga na rede sobre o mesmo problema: link

    
por 10.02.2016 / 20:03