HTTP/1.1 200 OK suivi d’un corps de page qui affiche le prénom d’un visiteur différent de celui qui vient de faire la requête : c’est le symptôme le plus visible d’une réponse mise en cache sans que l’en-tête Vary n’ait signalé au cache de page qu’elle dépendait d’un critère propre au visiteur, comme un cookie de session ou d’authentification.
Ce sujet ne traite pas de la configuration du cache de page lui-même (durée d’expiration, purge, clés de cache) : il se concentre sur la façon dont un test d’intégration HTTP peut détecter ce problème avant qu’il n’atteigne la production.
Symptôme
Une extension d’espace membre personnalise l’affichage d’une page selon que le visiteur est connecté ou non, en insérant un bloc de bienvenue nominatif. Le contenu HTML change selon le cookie d’authentification transmis, mais aucune modification de l’en-tête Cache-Control ni Vary n’accompagnait cette personnalisation. Sur un site placé derrière un cache de page (au niveau du serveur ou d’un CDN), la première réponse générée pour un visiteur connecté a été mise en cache et servie ensuite à des visiteurs anonymes, ou pire, à un autre visiteur connecté sous une autre identité.
Diagnostic
Le diagnostic a consisté à observer les en-têtes de réponse HTTP réellement envoyés, plutôt que le contenu affiché dans un navigateur, où l’effet du cache local du navigateur brouille l’observation. Deux requêtes successives, avec des cookies différents, ont révélé un corps de réponse identique malgré des cookies distincts, un signe net que la réponse avait été servie depuis un cache sans distinction du visiteur.
Le test qui détecte le problème
Le test suivant simule deux profils de visiteur avec des cookies différents et vérifie explicitement la présence de l’en-tête Vary attendu, plutôt que de se contenter de comparer le contenu affiché :
class EnTeteVaryTest extends WP_UnitTestCase
{
public function test_la_reponse_annonce_une_variation_par_cookie(): void
{
$requete = new WP_REST_Request('GET', '/wp-json/mon-espace/v1/accueil');
$requete->set_header('Cookie', 'session_membre=visiteur_a');
$reponse = rest_get_server()->dispatch($requete);
$entetes = $reponse->get_headers();
$this->assertArrayHasKey('Vary', $entetes);
$this->assertStringContainsString('Cookie', $entetes['Vary']);
}
}

Ce test échoue tant que l’en-tête Vary n’est pas explicitement défini par le point de terminaison, ce qui force à corriger le problème avant toute mise en production, plutôt que de découvrir la fuite de contenu par un signalement d’utilisateur.
Un second test, complémentaire
Le premier test vérifie la présence de l’en-tête, mais pas son effet réel sur un cache de page en conditions proches de la production. Un second test, plus proche d’un test end-to-end, complète le diagnostic en simulant deux requêtes HTTP réelles à travers la pile complète (y compris un cache de page local si l’environnement de test en dispose d’un) et en comparant le contenu retourné pour deux cookies différents :
- Première requête avec le cookie du visiteur A, mémorisation du contenu retourné.
- Seconde requête avec le cookie du visiteur B, immédiatement après la première.
- Assertion que les deux contenus diffèrent bien, preuve que le cache n’a pas servi la première réponse à la seconde requête.
Pourquoi ce n’est pas qu’un détail HTTP
L’en-tête Vary n’est pas une simple formalité de spécification : c’est le seul mécanisme standard qui indique à un cache HTTP (serveur, proxy intermédiaire ou navigateur) selon quels en-têtes de requête une réponse doit être considérée comme distincte. Son absence ne provoque pas systématiquement un incident visible : elle crée une fenêtre de risque qui ne se matérialise parfois qu’après la mise en cache d’une charge de trafic suffisante pour que deux visiteurs différents tombent sur la même entrée de cache.
En résumé
Un test HTTP qui compare explicitement les réponses obtenues pour deux profils de visiteur distincts, en vérifiant à la fois la présence de l’en-tête Vary et la différence effective de contenu, permet de repérer avant mise en production une fuite de contenu entre visiteurs derrière un cache de page. Ce type de test mérite sa place dans toute suite couvrant une fonctionnalité qui personnalise une réponse selon l’identité du visiteur.