bitlvl
IT

Tester di location nginx

nginx sceglie una location con regole facili da ricordare male, e il modo abituale per scoprirlo è fare il deploy e usare curl. Incolla invece la tua configurazione e un URL: la traccia mostra ogni location considerata, perché ha vinto o perso, e cosa succede dopo.

Nulla viene inviato da nessuna parte; la corrispondenza gira nel tuo browser.

I risultati e i messaggi di questo strumento sono mostrati in inglese.

Come nginx sceglie una location

  1. L’URI viene prima normalizzato: decodifica percentuale, barre ripetute unite, . e .. risolti. La query string non fa mai parte della corrispondenza delle location.
  2. Vengono confrontate tutte le location a prefisso (senza modificatore, =, ^~). Una corrispondenza esatta = vince subito. Altrimenti viene ricordato il prefisso corrispondente più lungo.
  3. Se quel prefisso più lungo ha ^~, vince e le regex vengono saltate.
  4. Le location regex (~ sensibile alle maiuscole, ~* insensibile) vengono provate nell’ordine in cui compaiono nel file. La prima che corrisponde vince, anche se prima aveva corrisposto un prefisso più lungo.
  5. Se nessuna regex corrisponde, viene usato il prefisso più lungo ricordato.
  6. Dentro la location vincente la stessa procedura viene eseguita di nuovo per le location annidate.

Due conseguenze sorprendono di più: una semplice location /images/ perde contro location ~ \.png$ per /images/a.png, perché le regex vengono controllate dopo i prefissi; e location /api corrisponde anche a /apiary, perché i prefissi sono prefissi di stringa, non segmenti di percorso. Usa /api/ o ^~ quando è ciò che intendi.

proxy_pass e la barra finale

Se proxy_pass ha una parte URI (qualsiasi cosa dopo l’host, anche solo /), nginx sostituisce con essa la parte dell’URI della richiesta che ha corrisposto al prefisso della location. location /api/ { proxy_pass http://app/; } trasforma /api/users in /users. Senza parte URI, l’URI della richiesta passa invariato. Barre non coerenti (/api contro /api/, o http://app contro http://app/) producono //users o users — il tester stampa l’URI upstream esatto così puoi vederlo. Una parte URI non è ammessa in una location regex a meno che un rewrite non abbia prima cambiato l’URI.

root contro alias

root aggiunge l’intero URI alla directory: root /srv; location /static/ serve /srv/static/x.css. alias sostituisce il prefisso della location: alias /srv/assets/; location /static/ serve /srv/assets/x.css. Con alias le barre finali della location e dell’alias devono concordare, e in una location regex alias deve usare le catture.

Flag di rewrite

FlagEffetto
lastinterrompe l’elaborazione dei rewrite, ricomincia la corrispondenza delle location con il nuovo URI (max 10 volte, poi 500)
breakinterrompe i rewrite, resta nella location corrente con il nuovo URI
redirectinvia un 302 al client
permanentinvia un 301 al client
(nessuno)continua con il rewrite successivo; a livello di server il risultato viene poi confrontato con le location

try_files

Ogni argomento viene controllato come file (o directory, con una barra finale) relativo a root/alias; il primo che esiste viene servito. L’ultimo argomento è il fallback e non viene controllato: è un redirect interno a un URI (che passa di nuovo per la corrispondenza delle location), una location con nome @nome, o un codice di stato in stile =404. Il tester non può vedere il tuo filesystem, quindi elenca i percorsi che verrebbero controllati.

Ereditarietà di add_header

add_header viene ereditato dal livello server solo quando la location non ha alcun add_header proprio. Un solo add_header Cache-Control in una location elimina silenziosamente gli header di sicurezza impostati a livello di server. La traccia lo segnala.

Domande

Supporta l’intera sintassi di configurazione di nginx?

Il parser gestisce la sintassi reale: blocchi annidati, commenti, stringhe tra virgolette, argomenti regex; le direttive include vengono elencate ma non seguite (incolla anche il file incluso). Le variabili diverse da $uri, $request_uri, $args e le catture regex restano come testo, e i blocchi «if» vengono mostrati ma non valutati.

Perché la mia regex si comporta diversamente in nginx?

nginx usa PCRE; questa pagina usa le espressioni regolari JavaScript. Concordano su quasi tutto ciò che si usa nei blocchi location, ma quantificatori possessivi, ricorsione e alcune forme di lookbehind differiscono. La traccia dice quando una regex non ha potuto essere compilata.

Può verificare quale blocco server risponde per un Host?

Sì. Incolla più blocchi server e compila il campo Host. La selezione segue nginx: nome esatto, wildcard più lunga che inizia con *, wildcard più lunga che finisce con *, prima regex corrispondente, poi default_server, poi il primo server per quella porta.

Come faccio la prova sul server reale?

nginx -T stampa l’intera configurazione unita (tutti gli include risolti) che puoi incollare qui. Per una verifica dal vivo, curl -sI -H "Host: example.com" http://127.0.0.1/percorso e leggi la risposta; aggiungi temporaneamente add_header X-Debug-Location "$uri" se devi vedere quale blocco ha risposto.