# Comparador de location do NGINX

> Cole seus blocos location e uma URI, e acompanhe a seleção de cinco passos do NGINX: exata, prefixo mais longo, a saída antecipada do circunflexo-til, regexes na ordem do arquivo, e então o retorno.

- Tool: https://ronutz.com/pt-BR/tools/nginx-location-matcher
- Family: Redes

---

## O que esta ferramenta faz

Cole as linhas `location` de um bloco server mais uma linha `request <uri>`, e o comparador roda o algoritmo de seleção documentado do NGINX à sua frente. Ele nomeia o bloco vencedor e mostra o percurso inteiro: o que aconteceu em cada um dos cinco passos e por quê, inclusive nos passos que não decidiram nada.

## A regra que ela existe para ensinar

**O NGINX não escolhe o primeiro location que casa, nem o último.** Ele tenta uma correspondência exata primeiro e para se uma acertar. Depois verifica cada location de prefixo e memoriza o **mais longo**, não o primeiro. Se esse prefixo tiver `^~`, ele vence de imediato. Caso contrário, as expressões regulares são tentadas **na ordem do arquivo** e a primeira que casar vence, batendo o prefixo memorizado. Só se nenhuma regex casar é que o prefixo vence afinal.

A ordem do arquivo decide exatamente um desses cinco passos, e é por isso que ler a configuração de cima para baixo engana sobre o resultado.

## Os dois resultados que as pessoas descobrem na prática

Um bloco de prefixo `/images/` perde para um bloco `~ \.(gif|jpg|png)$` escrito abaixo dele, porque as regexes são tentadas depois da rodada de prefixos e a vencem. O bloco de aparência mais específica, escrito primeiro, é superado por projeto.

E `^~` não significa "prioridade maior" — significa **pare antes das expressões regulares**. É exatamente por isso que ele corrige o caso acima.

## O que mais ela reporta

Além do percurso, a ferramenta inspeciona a própria configuração: blocos de prefixo que uma expressão regular poderia tomar (com a correção `^~` nomeada), locations duplicados, e a ausência de um `location /` de captura geral.

## Limites honestos

Um bloco server: sem seleção por `server_name` e sem correspondência de porta. Os padrões `~` e `~*` compilam para expressões regulares JavaScript — PCRE e JS concordam na sintaxe usada em blocos location comuns, mas são motores diferentes, então confie no próprio NGINX para qualquer coisa exótica. Sem `rewrite`, `try_files` ou redirecionamentos internos: isto responde qual bloco é selecionado, não o que a requisição inteira faz. A URI é comparada como escrita, porque o NGINX decodifica antes de comparar e fazer metade disso aqui seria pior que não fazer nada.

## Standards and references

- [NGINX documentation: ngx_http_core_module, location directive](https://nginx.org/en/docs/http/ngx_http_core_module.html#location) - the selection algorithm: exact match, longest prefix remembered, ^~ suppressing regular expressions, regular expressions in order of appearance, prefix fallback
- [NGINX documentation: how NGINX processes a request](https://nginx.org/en/docs/http/request_processing.html) - server and location selection order for an incoming request

## Related reading

- [A árvore de configuração do NGINX: o que é incluído, em que ordem, e de quem é o worker](https://ronutz.com/pt-BR/learn/nginx-configuration-tree-and-includes.md): Um arquivo, um diretório de fragmentos, e uma ordem de inclusão que decide qual diretiva vence. Mais as duas perguntas de propriedade que explicam a maioria das falhas de permissão: com qual usuário o master roda, com qual os workers rodam, e por que são deliberadamente diferentes.
- [A barra final do proxy_pass no NGINX: um caractere que decide o que seu backend recebe](https://ronutz.com/pt-BR/learn/nginx-proxy-pass-uri-rewriting.md): proxy_pass com uma parte de URI substitui o prefixo do location que casou. Sem ela, a URI original da requisição passa direto. Essa é a regra inteira, é um interruptor binário e não uma questão de grau, e uma única barra basta para virá-lo.
- [Apache httpd: o servidor que rodava a web, e o problema que produziu o NGINX](https://ronutz.com/pt-BR/learn/apache-httpd-and-what-nginx-was-written-against.md): O Apache começou como remendos a um servidor que ninguém mantinha, e em um ano rodava mais da web que qualquer outro. A arquitetura que o tornou flexível é também a que o fez sofrer com o tráfego dos anos 2000, e esse é o problema que o NGINX foi escrito para resolver.
- [Correspondência de location no NGINX: por que o bloco que você esperava não foi o que rodou](https://ronutz.com/pt-BR/learn/nginx-location-matching-order.md): O NGINX não escolhe o primeiro location que casa, nem o último. Ele segue uma ordem fixa de cinco passos em que a ordem do arquivo importa para exatamente um deles, e é por isso que ler a configuração de cima para baixo engana sobre qual bloco vence.
- [Limitar requisições, conexões e banda no NGINX: baldes furados e o burst que surpreende](https://ronutz.com/pt-BR/learn/nginx-limiting-connections-and-rate.md): Três limites diferentes, três diretivas diferentes, e um mecanismo comum que vale entender antes de ajustar. O limitador de requisições é um balde furado, e não uma cota por segundo, e burst com nodelay muda seu comportamento de formas que o nome não sugere.
- [Recarregar o NGINX sem derrubar tráfego, e as primeiras quatro coisas a conferir quando quebra](https://ronutz.com/pt-BR/learn/nginx-reload-signals-and-first-troubleshooting.md): Um reload não é um restart: o master valida a nova configuração, sobe novos workers, e deixa os antigos terminarem o que estavam fazendo. Saber isso, e saber qual log responde qual pergunta, resolve a maioria dos problemas de NGINX antes que fiquem interessantes.
