Le WordPress d'aujourd'hui, décodé pour les développeurs

Hébergement & serveurs

Vary et Accept-Encoding : éviter qu’un cache partagé serve une réponse compressée au mauvais client

Un en-tête Vary absent ou mal réglé peut faire servir, par un cache mutualisé, une page compressée en Brotli à un client qui ne sait pas la lire.

Par WordPress Développement • 28 mai 2023 • 4 min de lecture • Aucun commentaire
Vary et Accept-Encoding : éviter qu'un cache partagé serve une réponse compressée au mauvais client

La documentation officielle du protocole HTTP est claire sur ce point : l’en-tête Vary indique à un cache selon quels autres en-têtes de la requête une réponse peut varier, afin qu’il ne serve jamais à un client une réponse générée pour un contexte différent du sien.

Ce tutoriel montre comment configurer correctement Vary: Accept-Encoding sur une infrastructure WordPress qui partage un cache entre plusieurs serveurs applicatifs, un cas fréquent dès qu’un cache mutualisé de type reverse proxy se trouve devant plusieurs backends. Il ne traite pas de la validation par ETag, un mécanisme de cache distinct qui répond à un autre problème.

Le problème concret que cet en-tête résout

Un serveur web moderne peut compresser sa réponse selon l’algorithme que le client indique supporter dans son en-tête de requête Accept-Encoding, typiquement gzip ou br pour Brotli. Sans indication contraire, un cache partagé placé devant plusieurs serveurs applicatifs peut mémoriser une seule version de la réponse pour une URL donnée, indépendamment de l’encodage utilisé pour la générer.

Si cette réponse a été compressée en Brotli pour un premier client, et que le cache la sert telle quelle à un second client dont le navigateur ne supporte que gzip, ce second client reçoit un contenu binaire qu’il ne sait pas décompresser. Le résultat visible côté navigateur va du texte totalement illisible à une page blanche, selon la façon dont le navigateur gère cette incohérence entre en-tête annoncé et contenu réel.

Configurer nginx pour propager correctement l’en-tête

Sur un serveur nginx qui compresse ses réponses avec le module gzip natif, l’en-tête Vary: Accept-Encoding est ajouté automatiquement dès que la directive gzip_vary on; est activée dans la configuration du serveur ou du bloc de site concerné.

server {
    listen 443 ssl;
    server_name exemple-client.fr;

    gzip on;
    gzip_vary on;
    gzip_types text/html text/css application/javascript application/json;

    location / {
        proxy_pass http://backend_wordpress;
        proxy_set_header Accept-Encoding $http_accept_encoding;
    }
}

Le point souvent oublié se situe au niveau du cache lui-même, qu’il s’agisse d’un module proxy_cache nginx ou d’une brique de cache partagée séparée. La clé de cache doit intégrer la valeur d’Accept-Encoding du client, faute de quoi l’en-tête Vary renvoyé au navigateur devient purement déclaratif, sans effet réel sur ce que le cache mémorise en interne.

L'essentiel à retenir : le cache doit distinguer les réponses selon l'encodage demandé par le client ; Vary Accept-Encoding indique cette distinction au cache ; un mauvais réglage produit du contenu illisible pour certains clients

Configurer la clé de cache pour respecter réellement Vary

Sur un proxy_cache nginx, la clé de cache par défaut n’intègre pas systématiquement l’encodage accepté par le client. Il est nécessaire de l’ajouter explicitement à la directive proxy_cache_key pour que le cache stocke des entrées distinctes selon l’encodage.

proxy_cache_path /var/cache/nginx/wordpress levels=1:2 keys_zone=wp_cache:64m;
proxy_cache_key "$scheme$request_method$host$request_uri$http_accept_encoding";

Cette clé de cache enrichie garantit que deux clients demandant la même URL, mais avec des en-têtes Accept-Encoding différents, obtiennent chacun une entrée de cache distincte, correctement compressée pour leur propre capacité de décompression.

Vérifier le comportement une fois la configuration en place

  1. Envoyer une requête sans en-tête Accept-Encoding et vérifier que la réponse n’est pas compressée.
  2. Envoyer une requête avec Accept-Encoding: br et vérifier, via l’en-tête Content-Encoding: br de la réponse, que la compression Brotli a bien été appliquée.
  3. Vérifier, dans les deux cas, la présence de l’en-tête Vary: Accept-Encoding dans la réponse, quel que soit l’encodage utilisé.

Un en-tête Vary correctement réglé ne se contente pas d’informer le navigateur : il doit aussi être respecté par le cache lui-même, sans quoi la déclaration reste sans effet sur ce que sert réellement l’infrastructure.

En résumé

La configuration correcte de Vary: Accept-Encoding sur un cache partagé entre plusieurs serveurs applicatifs demande deux réglages distincts et complémentaires : l’ajout de l’en-tête lui-même côté serveur web, et l’intégration de la valeur d’Accept-Encoding dans la clé de cache utilisée par la brique de mise en cache. Omettre le second réglage laisse le problème intact, malgré une configuration en apparence conforme à la documentation.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi