Disabilitazione della decodifica URL nel proxy nginx


21

Quando cerco questo URL: http://localhost:8080/foo/%5B-%5Dserver ( nc -l 8080) lo riceve così com'è:

GET /foo/%5B-%5D HTTP/1.1

Tuttavia, quando eseguo il proxy di questa applicazione tramite nginx (1.1.19):

location /foo {
        proxy_pass    http://localhost:8080/foo;
}

La stessa richiesta instradata attraverso la porta nginx viene inoltrata con il percorso decodificato:

GET /foo/[-] HTTP/1.1

Le parentesi quadre decodificate nel percorso GET stanno causando gli errori nel server di destinazione ( Stato HTTP 400 - Carattere illegale nel percorso ... ) quando arrivano senza escape.

Esiste un modo per disabilitare la decodifica URL o ricodificarlo in modo che il server di destinazione ottenga lo stesso percorso esatto quando viene instradato attraverso nginx? Qualche regola di riscrittura URL intelligente?


Risposte:


19

Citando Valentin V. Bartenev (che dovrebbe ottenere il credito completo per questa risposta):

Una citazione dalla documentazione :

  • Se proxy_pass viene specificato con URI , quando si passa una richiesta al server, parte di un URI di richiesta normalizzato corrispondente alla posizione viene sostituito da un URI specificato nella direttiva

  • Se proxy_passviene specificato senza URI , un URI di richiesta viene passato al server nella stessa forma inviata da un client durante l'elaborazione di una richiesta originale

La configurazione corretta nel tuo caso sarebbe:

location /foo {
   proxy_pass http://localhost:8080;
}

8
Ho dovuto cambiare http://localhost:8080/a http://localhost:8080nel caso in cui qualcuno ha la stessa situazione come ho fatto io.
Herrtim,

4
Perché Nginx decodifica l'URI prima di passarlo al server back-end? Non avrebbe più senso se non toccasse l'URI?
ornitorinco

@platypus, rimane intatto, fino a quando non inizi esplicitamente a eseguire le sostituzioni
cnst

2

Si noti che la decodifica URL, comunemente nota come $uri"normalizzazione" all'interno della documentazione di nginx, avviene prima dell'IFF back-end:

  • o qualsiasi URI è specificato all'interno di proxy_passse stesso, anche se solo la barra finale da sola,

  • oppure, l'URI viene modificato durante l'elaborazione, ad es rewrite. tramite .


Entrambe le condizioni sono esplicitamente documentate su http://nginx.org/r/proxy_pass (sottolineatura mia):

  • Se la proxy_passdirettiva viene specificata con un URI , quando una richiesta viene passata al server, la parte di un URI di richiesta normalizzata corrispondente alla posizione viene sostituita da un URI specificato nella direttiva

  • Se proxy_passviene specificato senza un URI , l' URI della richiesta viene passato al server nella stessa forma inviata da un client quando viene elaborata la richiesta originale o viene passato l'intero URI della richiesta normalizzata durante l' elaborazione dell'URI modificato


La soluzione consiste nell'omettere l'URI come nel caso dei PO o, in effetti, utilizzare una rewriteregola intelligente :

# map `/foo` to `/foo`:
location /foo {
    proxy_pass  http://localhost:8080;  # no URI -- not even just a slash
}

# map `/foo` to `/bar`:
location /foo {
    rewrite  ^  $request_uri;            # get original URI
    rewrite  ^/foo(/.*)  /bar$1  break;  # drop /foo, put /bar
    return 400;   # if the second rewrite won't match
    proxy_pass    http://localhost:8080$uri;
}

Puoi vederlo dal vivo in una risposta Stack Overflow correlata , incluso il gruppo di controllo.


La documentazione qui è confusa. Entrambi i moduli contengono un URI. È il componente del percorso presente in uno e mancante nell'altro.
Michael Hampton

@MichaelHampton, non sono d'accordo - il PERCORSO è generalmente chiamato URI, quindi quello senza il percorso non contiene l'URI.
primo

Un percorso relativo da solo può anche essere un URL valido, ovviamente. Il punto è che il resto è anche un URI valido (ad es http://localhost:8080.). Se non sei d'accordo, puoi accettarlo con gli autori di RFC 3986.
Michael Hampton

@MichaelHampton Sfortunatamente, lo schema e il percorso sono obbligatori per essere un URI, autorità, argomenti, frammento sono opzionali
Norman Xu,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.