Le .htaccess de ce site demandait de basculer tout visiteur vers HTTPS. La règle se chargeait sans erreur et ne correspondait à aucune adresse. Elle est restée près de vingt mois dans le dépôt : tout ce qui s’y vérifiait était vert, et une seule requête au serveur suffisait à voir le défaut.
Publiée le
À l’écran, rien d’anormal : le site s’affichait. Mais interrogé en http://, le serveur servait la page en clair, sans rediriger. Chaque page répondait ainsi sous plusieurs adresses — avec ou sans www, avec ou sans HTTPS — et seule la balise canonique indiquait aux moteurs de recherche laquelle retenir.
http://designhorizon.io/
→ 200 OK, aucune redirectionRewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.\*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]Dans une expression régulière, .* signifie « n’importe quelle suite de caractères ». Précédé d’un antislash, l’astérisque perd ce sens : .\* signifie « un caractère quelconque suivi d’un astérisque ». La règle ne s’appliquait donc qu’aux adresses contenant réellement le caractère *. Aucune n’en contient.
La version précédente, du 26 octobre 2023, écrivait (.*), sans antislash. Celui-ci est arrivé le 8 janvier 2025, dans un commit qui ajoutait une référence au site et remaniait la page d’accueil — sans rapport annoncé avec le serveur. Je n’ai pas de trace de la façon dont il est entré. C’est, entre autres, la forme que laisse un outil qui échappe la syntaxe Markdown.
La ligne est syntaxiquement correcte. Apache la charge sans avertissement, la compilation du site ne lit pas le .htaccess, et aucun test ne démarre un serveur Apache. Le défaut ne vivait pas dans le texte du fichier, mais dans le comportement du serveur qui l’exécute.
Une relecture attentive aurait pu voir l’antislash. Elle n’a pas eu lieu, et rien ne l’imposait. Une règle de ce genre ne se vérifie pas en la lisant : elle se vérifie en interrogeant le serveur.
Le 6 septembre 2026, la règle est réécrite en redirection permanente vers HTTPS. Le lendemain, elle absorbe aussi l’adresse sans www : chaque page n’existe plus que sous une seule forme, atteinte en un seul saut.
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.designhorizon.io%{REQUEST_URI} [R=301,L]Le 6 septembre, une règle voisine avait été ajoutée pour retirer la barre finale des adresses. Le 10 septembre, la sonde décrite plus bas l’a prise en défaut : une adresse terminée par une barre redirigeait vers une adresse qui affiche le port.
https://www.designhorizon.io/offres/
→ 301 https://www.designhorizon.io:443/offresLa cible de cette règle était relative : /$1. Apache reconstruit alors l’adresse complète à partir de ce que lui transmet l’hébergement, port compris. Le navigateur suit sans rien signaler ; l’adresse canonique, elle, ne porte pas de port. La cible est désormais écrite en entier.
RewriteCond %{REQUEST_URI} !^/$
RewriteRule ^(.+)/$ https://www.designhorizon.io/$1 [R=301,L]Une sonde, lancée par yarn probe, interroge le site en ligne à partir de la table des routes — celle qui produit déjà le routeur, le prérendu et le plan du site. Chaque page publiée doit répondre 200, sans redirection. Chaque forme non canonique d’une adresse — en http://, sans www, avec une barre finale — doit répondre 301, en un seul saut, vers l’adresse exacte, comparée caractère par caractère. Une adresse inconnue doit répondre 404, en français comme en anglais.
Un port en trop, une barre en trop, un .htaccess que le logiciel de transfert n’a pas envoyé parce qu’il masque les fichiers cachés : dans chacun de ces cas, la sonde échoue et nomme l’adresse fautive.
✗ https://www.designhorizon.io/mentions-legales/
reçu 301 → https://www.designhorizon.io:443/mentions-legales
attendu 301 → https://www.designhorizon.io/mentions-legales
Sonde : 32 écart(s) sur 157 vérification(s).Trente des trente-deux écarts sont ce port, une fois par page et par langue. Les deux autres sont les pages de cette note, pas encore en ligne au moment du relevé. Tout le reste — HTTPS, hôte unique, adresses inconnues, en-tête HSTS — répondait déjà comme prévu.
Une règle de serveur se lit dans le dépôt, mais ne s’exécute que sur le serveur : c’est là qu’elle se vérifie.
La sonde ne tourne que lorsque je la lance. Le site est mis en ligne à la main, par SFTP, sans chaîne de déploiement qui pourrait l’exécuter d’office : rien n’empêche aujourd’hui une mise en ligne de partir sans elle. Elle ne couvre pas non plus les sous-domaines, que ce .htaccess ne sert pas.
Les règles qui ne vivent pas dans le code — configuration du serveur, réglages de l’hébergement, visibilité d’un paquet — sont celles qu’aucune relecture ne voit. Les inventorier, puis les rendre vérifiables, est l’objet des garde-fous.
Ce site mesure sa fréquentation sans cookie et sans identifiant enregistré sur votre appareil ; « Refuser » interrompt cette mesure. Avec votre accord, nous activons aussi le module de prise de rendez-vous Calendly, qui dépose ses propres cookies. Vous pouvez changer d’avis à tout moment depuis le pied de page. En savoir plus