Eviter les conflits de redirection dans Nginx

closeCet article a été publié il y a 6 ans 9 jours, il est donc possible qu’il ne soit plus à jour. Les informations proposées sont donc peut-être expirées.

J’aime les clients quand ils changent de site, c’est toujours un bonheur de voir les agences SEO rouler des mécaniques avec leurs tableaux Excel pour rediriger les URLs de l’ancien site vers le nouveau. Le problème, c’est qu’ils n’ont absolument aucune considération pour les personnes qui vont être chargées de traduire ces horreurs en règles de redirection pour le serveur web. Voici donc un petit retour d’expérience sur un sujet qui aura été douloureux, encore plus quand on voit la solution.

Contexte : le client a changé de domaine et de moteur de site, et veut qu’on redirige plusieurs milliers d’URLs vers les « bonnes » pages, afin de récupérer rapidement la visibilité de son ancien domaine pour le nouveau, les moteurs de recherche opérant alors des substitutions au niveau de leur base de liens.

Il utilise Nginx en tant que serveur web, la procédure n’est pas compliquée (je vous passe la conversion « Excel->rewrites », c’est infernal, un peu sauvé par Notepad++ quand même), je met ses règles dans un fichier dédié, je colle un include dans son bloc server{} sur l’ancien site, et roulez jeunesse. Enfin presque, il aura fallu quelques corrections, avec une connerie que représente le tableau de plus de 28000 lignes qu’on m’a transmis, avec une quantité d’URLs qui n’existent tout simplement pas, ça aura cramé du temps, beaucoup.

D’ailleurs, et c’est le cœur du problème, je dois faire des redirections particulières au niveau d’URI identiques mais avec des Query strings différentes, autrement appelés « Query parameters » dans Nginx. Pour rappel, voici un petit schéma sur la décomposition d’une URL :

C’est un des rares points sur lesquels je préfère Apache sur le sujet, le module Rewrite permet de les traiter de la même manière les URI, les hosts, les protocoles, les query_strings… Bref, pour ça pas de miracle, il a fallu passer par des blocs location{} :

On voit bien la difficulté, la page de base est la même ou presque dans tous les cas (403.html ou 404.html), mais on lui applique des paramètres, ici appelé page, qui servent notamment à garder la trace de l’erreur, et potentiellement proposer des pages pertinentes à partir des termes de celle qui était recherchée. Dans Nginx, on a une syntaxe $arg_<parametre> qui permet d’analyser son contenu, voir d’autres s’il y en a plus d’un. $args contient l’intégralité des paramètres.

Pourtant ça ne fonctionnait pas, le fichier de réécriture et surtout sa dernière règle qui redirige vers la page d’accueil passait toujours avant, même en étant déclarée après dans le vhost. Il aura fallu pas mal d’essais, de tentatives de syntaxes à base de mappings, j’ai du tenter 4 écritures différentes que je n’ai malheureusement pas conservé pour les partager, sans succès.

L’explication semble être que même déclarées sur le tard, des directives rewrite sont toujours interprétées en premier par Nginx, avant les directives location, qui elles pour le coup sont exécutées dans l’ordre de définition. La solution était finalement affreusement simple, encapsuler l’include dans un location générique en fin de vhost :

Je vous cache pas qu’un peu de frustration et quelques jurons ont fleuri pendant cette mise en place. D’autant plus vu la simplicité de la solution. Une justification suffisante à mes yeux pour vous éviter la même galère en vous partageant cette astuce autrement que dans un petit paragraphe d’un « astuces diverses » 🙂

4 Commentaires
Le plus ancien
Le plus récent
Commentaires en ligne
Afficher tous les commentaires
xhark
13/04/2018 00:15

Question HS : tu as utilisé quoi pour illustrer les différentes parties de l’URL avec le texte coloré ?

Mirabellette
13/04/2018 12:56
Répondre à  xhark

Je trouve cette image super intéressante perso car elle permet de bien distinguer chaque élément d’une URL.