web-dev-qa-db-fra.com

Nginx redirige toutes les demandes du sous-répertoire vers une autre racine de sous-répertoire

Je suis assez nouveau pour Nginx, alors s'il vous plaît, supportez-moi. 

J'essaie de rediriger toutes les demandes d'un sous-répertoire (store) vers la racine d'un autre sous-répertoire (trade). Voir mes progrès ci-dessous. Le site dans le sous-répertoire cible (commerce) est un site magento, c’est la raison pour laquelle la plupart des règles actuelles sont en vigueur.

server {
    server_name example.com *.example.com;
    root /usr/share/nginx/html/example.com/public_html;
    index index.php index.html index.htm;

    access_log /var/log/nginx/example.access.log;
    error_log /var/log/nginx/example.error.log;

    location / {
            try_files $uri $uri/ /index.html;
    }

    location /trade/ {
            index index.html index.php;
            try_files $uri $uri/ @handler;
            expires 30d;
    }

    location ~ /store {
            rewrite /trade permanent;
    }

    location ~ ^/trade/(app|includes|lib|media/downloadable|pkginfo|report/config.xml|var)/ { internal; }
    location /trade/var/export/ { internal; }
    location /. { return 404; }
    location @handler { rewrite / /trade/index.php; }

    error_page 404 /404.html;

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
          root /usr/share/nginx/html;
    }

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    location ~ \.php$ {
            try_files $uri =404;
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;

    }


}

La section que j'utilise pour rediriger est la suivante:

location ~ /store {
        rewrite /trade permanent;
}

Cela fonctionne pour exemple.com/store mais pas exemple/store/index.php ou tout autre uri avec arguments. J'ai l'impression que la section du fichier php en bas est prioritaire sur le traitement. C'est pourquoi j'ai placé le ~ devant le magasin en tant que documentation ici indique que cela sera traité en premier. Est-ce que le traitement s'arrête ou continue? 

J'ai lu sur l'imbrication d'une règle php mais j'ai essayé en vain.

J'apprécierais grandement toute aide.

10
user1214769

ok essayez quelque chose comme ça

location ^~ /store(.*) {
  return 301 $scheme://$http_Host/trade$1$is_args$query_string;
}

Essayer autant que possible d'éviter les trucs codés en dur et utiliser return car c'est préférable aux réécritures permanentes

33

D'accord,

Pour en revenir à cela, je peux voir le problème.

Dans Nginx, lorsque vous ajoutez une directive location avec ~, cela signifie que vous souhaitez traiter les expressions régulières dans votre directive (respectez la casse, ~ * pour les non-respect de la casse). Je crois que toutes les directives regex seront traitées avant toutes les autres, mais je risque d’être corrigé.

Alors, quand j'utilise:

location ~/store {
       rewrite /trade permanent;
}

Il n'y a pas de regex ici. Son correspond simplement/magasin et rediriger vers le commerce.

Après une enquête (et un raffinement de ma regex, qui est des ordures), je suis revenu à cela et ai trouvé une solution de travail.

location ~ ^/store/(.*) {
            rewrite ^/store(.*) /trade permanent;
    }

Ici, je demande à la directive de traiter la regex en entrant ~ puis en faisant correspondre l’url avec/store/dans celle-ci.

Ensuite, selon la documentation, la syntaxe de réécriture est la suivante:

rewrite regex replacement [flag]

donc, je fais correspondre les adresses avec les magasins et les redirige en permanence vers le nouveau sous-dossier.

Plutôt facile, vraiment embarrassant, mais bon, chaque jour est un jour d'école. Je suis ouvert à la correction de tout cela et espère que cela aidera quelqu'un.

3
user1214769

Vous devez vous assurer que votre gestionnaire location ~ \.php$ ne prend aucune URL sous l'ancien dossier. En effet, les règles de priorité sont clairement documentées dans http://nginx.org/r/location , et vous pouvez utiliser des expressions régulières ou, mieux encore, utiliser une correspondance basée sur un préfixe avec le modificateur ^~ pour indiquer à la la recherche doit s'arrêter sans essayer de voir si ce \.php$location basé sur regex correspondrait:

    location ^~ /old/long/path/ { # will match /old/long/path/index.php, too
        rewrite  ^/old/long/path/(.*)$  /new/$1  permanent;
    }

L'extrait ci-dessus est probablement le moyen le plus efficace de le faire, mais voici un autre moyen de faire de même:

    location ~ /old/long/path/(.*) {
        return  301  /new/$1$is_args$args;
    }

Pourquoi un exemple a-t-il $is_args$args et l'autre pas? Bonne question! Notez que la directive location ainsi que le premier paramètre de la directive rewrite fonctionnent tous deux en fonction du contenu de la variable $uri, par opposition à $request_uri. Le récit est long, mais $uri ne contient pas $args. Ainsi, dans les deux cas, $1 ne contiendra pas de args; cependant, dans le cas de rewrite, le cas est réputé si courant que $args est automatiquement rajouté par nginx, à moins que la nouvelle chaîne ne se termine par un caractère ?, voir http://nginx.org/r/rewrite .

0
cnst