web-dev-qa-db-fra.com

Comment réécrire les URL dans une réponse proxy dans NGINX

J'ai l'habitude d'utiliser Apache avec mod_proxy_html et j'essaie de faire quelque chose de similaire avec NGINX. Le cas d'utilisation spécifique est que j'ai une interface utilisateur d'administration exécutée dans Tomcat sur le port 8080 sur un serveur au niveau du contexte racine:

http://localhost:8080/

J'ai besoin de faire apparaître cela sur le port 80, mais j'ai d'autres contextes sur le serveur NGINX en cours d'exécution sur cet hôte. Par conséquent, essayez d'accéder à ceci à l'adresse:

http://localhost:80/admin/

J'espérais que le bloc serveur super simple suivant le ferait, mais ce n'est pas tout à fait:

server {
    listen  80;
    server_name screenly.local.akana.com;

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

Le problème est que le contenu renvoyé (html) contient des URL vers des scripts et des informations de style accessibles depuis le contexte racine. Je dois donc réécrire ces URL pour qu'elles commencent par/admin/au lieu de /.

Comment est-ce que je fais ceci dans NGINX?

53
IanG

Nous devrions d’abord lire la documentation sur proxy_pass soigneusement et intégralement.

L'URI transmis au serveur en amont est déterminé en fonction de l'utilisation ou non de la directive "proxy_pass" avec l'URI. Le slash final dans la directive proxy_pass signifie que l'URI est présent et égal à /. L'absence de fin de barre oblique signifie que l'URI du chapeau est absent.

Proxy_pass avec l'URI:

location /some_dir/ {
    proxy_pass http://some_server/;
}

Avec ce qui précède, il y a le proxy suivant:

http:// your_server/some_dir/ some_subdir/some_file ->
http:// some_server/          some_subdir/some_file

Fondamentalement, /some_dir/ est remplacé par / pour changer le chemin de requête de /some_dir/some_subdir/some_file à /some_subdir/some_file.

Proxy_pass sans URI:

location /some_dir/ {
    proxy_pass http://some_server;
}

Avec le second (pas de barre oblique): le proxy va comme ceci:

http:// your_server /some_dir/some_subdir/some_file ->
http:// some_server /some_dir/some_subdir/some_file

Fondamentalement, le chemin d'accès complet à la requête d'origine est transmis sans modification.


Donc, dans votre cas, il semble que vous devriez simplement laisser tomber la barre oblique pour obtenir ce que vous voulez.


Caveat

Notez que la réécriture automatique ne fonctionne que si vous n'utilisez pas de variables dans proxy_pass. Si vous utilisez des variables, vous devriez vous réécrire vous-même:

location /some_dir/ {
  rewrite    /some_dir/(.*) /$1 break;
  proxy_pass $upstream_server;
}

Il existe d'autres cas où la réécriture ne fonctionne pas, c'est pourquoi la lecture de la documentation est indispensable.


Modifier

En relisant votre question, il semble que j'ai peut-être manqué le fait que vous souhaitiez simplement modifier la sortie HTML.

Pour cela, vous pouvez utiliser la directive sub_filter . Quelque chose comme ...

location /admin/ {
    proxy_pass http://localhost:8080/;
    sub_filter "http://your_server/" "http://your_server/admin/";
    sub_filter_once off;
}

Fondamentalement, la chaîne que vous souhaitez remplacer et la chaîne de remplacement

79
Dayo

Vous devrez peut-être également définir la directive suivante avant le premier "sous-filtre" pour les serveurs principaux avec compression de données:

proxy_set_header Accept-Encoding "";

Sinon, cela ne fonctionnera peut-être pas ... Pour votre exemple, cela ressemblera à:

location /admin/ {
    proxy_pass http://localhost:8080/;
    proxy_set_header Accept-Encoding "";
    sub_filter "http://your_server/" "http://your_server/admin/";
    sub_filter_once off;
}
11
Vladimir Sh.

Vous pouvez utiliser l'exemple de configuration nginx suivant:

upstream adminhost {
  server adminhostname:8080;
}

server {
  listen 80;

  location ~ ^/admin/(.*)$ {
  proxy_pass http://adminhost/$1$is_args$args;
  proxy_redirect off;
  proxy_set_header Host $Host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Host $server_name;
}
0
Alex Elkin