Les expressions rationnelles d'emplacement Nginx ne fonctionnent pas avec un laissez-passer proxy

44

J'essaie de faire en sorte que ces 2 directives d'emplacement fonctionnent dans Nginx, mais certaines erreurs me sont renvoyées lors du démarrage de Nginx.

   location ~ ^/smx/(test|production) {
        proxy_pass   http://localhost:8181/cxf;
    }

    location ~ ^/es/(test|production) {
        proxy_pass   http://localhost:9200/;
    }

C'est l'erreur que je reçois:

nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block

Cela vous semble familier? Qu'est-ce qui me manque ici?

Niels
la source

Réponses:

49

Un petit ajout à l'excellente réponse de Xaviar :

Si vous ne connaissez pas très bien nginx, il existe une différence importante entre l’ajout du slash à la fin de la proxy_passdirective.

Ce qui suit ne fonctionne pas :

location ~* ^/dir/ {
  rewrite ^/dir/(.*) /$1 break;
  proxy_pass http://backend/;

mais celui-ci fait:

location ~* ^/dir/ {
  rewrite ^/dir/(.*) /$1 break;
  proxy_pass http://backend;

La différence étant la /fin de la proxy_passdirective.

95%
la source
1
Ce /problème corrigé mon problème de configuration, il était difficile à attraper, merci!
Yorch
Ca me rendait dingue, merci de me l'avoir signalé!
cyrrill
22

Il vous indique que l'URI dans la directive de passe proxy ne peut pas être utilisé dans un emplacement regex. En effet, nginx ne peut pas remplacer la partie de l'URI correspondant à l'expression rationnelle dans le locationbloc par celle transmise de proxy_passmanière générique dans la directive.

Imaginez simplement que votre regex de localisation est /foo/(.*)/bar, et vous précisez proxy_pass http://server/test, que nginx devrait mapper votre regex de localisation sur un autre niveau supérieur, car vous ne voulez pas terminer avec, /foo/test/bar/somethingmais avec /test/something. Donc, ce n'est pas possible nativement.

Donc, pour cette partie en utilisant ce qui suit devrait fonctionner:

server {

   [ ... ]

    location ~ ^/smx/(test|production) {
        rewrite ^/smx/(?:test|production)/(.*)$ /cxf/$1 break;
        proxy_pass http://localhost:8181;
    }

    location ~ ^/es/(test|production) {
        rewrite ^/es/(?:test|production)/(.*)$ /$1 break;
        proxy_pass http://localhost:9200;
    }

}

Cependant, il ne sera pas possible de réécrire les redirections pour qu'elles correspondent au modèle d'URI du bloc d'emplacement car il réécrit l'URI en cours de traitement, rendant impossible la modification de l'en- Locationtête en fonction de la demande initiale avant la réécriture.

Xavier Lucas
la source
2
déplacer le chemin dans une règle de réécriture a fonctionné pour moi. Merci.
Sonjz