Nginx – encodage (normalisation) d’une partie de l’URI

J’ai la directive de location nginx dont le but est de “supprimer” le préfixe de localisation de l’URI pour la directive proxy_pass .

Par exemple, pour utiliser l’URI http://example.com/en/lalala, utilisez proxy_pass http://example.com/lalala

 location ~ '^/(?[\w]{2})(/(?.*))?$' { ... proxy_pass http://example/$rest; ... } 

De cette manière, la variable rest sera décodée lorsqu’elle sera transmise à proxy_pass directeve. Cela semble être un comportement attendu.

Le problème est lorsque mon URI contient un espace codé %20 transmis par le client

 http://example.com/lala%20lala 

nginx décode l’URI vers

 http://example.com/lala lala 

Je peux le voir dans mon error.log.

La question est: est-il possible d’utiliser une variable de rest codée d’une manière ou d’une autre, telle qu’elle est transmise par le client? Si je fais quelque chose de complètement faux, s’il-vous-plaît, suggérez la bonne manière.

Je vous remercie.

Oui, ce comportement est attendu même si les documents disent également:

Si proxy_pass est spécifié sans URI, l’URI de la demande est transmis au serveur sous la même forme que celle envoyée par un client lorsque la demande d’origine est traitée ou que l’URI de la demande normalisée complète est transmis lors du traitement de l’URI modifié:

 location /some/path/ { proxy_pass http://127.0.0.1; } 

Les ingénieurs de Nginx disent la même chose: https://serverfault.com/questions/459369/disabling-url-decoding-in-nginx-proxy

Cependant, si vous ajoutez $ request_uri à proxy_pass (et supprimez les parameters régionaux au préalable, cela peut fonctionner comme indiqué par l’ingénieur Nginx):

 set $modified_uri $request_uri; if ($modified_uri ~ "^/([\w]{2})(/.*)") { set $modified_uri $1; } proxy_pass http://example$modified_uri; 

J’ai eu un certain succès en utilisant ce qui suit avec Confluence et d’autres applications Atlassian derrière nginx où des caractères spéciaux tels que () <> [] causaient des problèmes.

 location /path { # [... other proxy options ...] # set proxy path with regex if ($request_uri ~* "/path(/.*)") { proxy_pass http://server:port/path$1; break; } # fallback (probably not needed) proxy_pass http://server:port/path; } 

La directive set peut faire l’affaire. Il conserve l’encodage intact ou plutôt encode la chaîne décodée.

 location ~ '^/(?[\w]{2})(/(?.*))?$' { ... set $encoded_rest $rest proxy_pass http://example/$encoded_rest; ... }