web-dev-qa-db-fra.com

L'argument de localisation Nginx ne fonctionne pas avec le proxy pass

J'essaie de faire fonctionner ces 2 directives d'emplacement dans Nginx mais je reçois des erreurs 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/;
    }

Voici 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-t-il familier? Qu'est-ce que je manque ici?

44
Niels

Un petit ajout à la grande réponse de Xaviar :

S'il vous arrive de ne pas bien connaître nginx, il y a une différence importante entre l'ajout de la barre oblique à la fin du proxy_pass directive.

Les éléments suivants ne fonctionnent 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 le / à la fin de proxy_pass directive.

51
mark

Il vous indique que l'URI dans la directive de passage proxy ne peut pas être utilisé dans un emplacement d'expression régulière. Cela est dû au fait que nginx ne peut pas remplacer la partie de l'URI correspondant à l'expression régulière dans le bloc location par celle passée dans la directive proxy_pass De manière générique.

Imaginez simplement que votre regex de localisation est /foo/(.*)/bar, et que vous spécifiez proxy_pass http://server/test, Nginx devrait mapper votre regex de localisation à une autre à un niveau supérieur parce que vous ne voulez pas finir avec /foo/test/bar/something Mais avec /test/something. Ce n'est donc pas possible nativement.

Donc, pour cette partie, l'utilisation de 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 correspondre au modèle d'URI du bloc d'emplacement car il réécrit l'URI en cours de traitement, ce qui rend impossible de modifier l'en-tête Location en fonction de requête initiale avant réécriture.

24
Xavier Lucas