curl-head-vs-get-header-debugging

Par divinevideo · divine-mobile

Corrige les valeurs trompeuses des en-têtes de réponse HTTP lors du débogage avec `curl -I` ou `curl -sI`. À utiliser quand : (1) les en-têtes de réponse diffèrent entre les tests avec `curl` et le comportement réel du navigateur/client, (2) `Cache-Control` ou d'autres en-têtes affichent des valeurs inattendues malgré un code middleware correct, (3) un middleware côté serveur qui ne s'applique qu'aux requêtes GET semble ne pas fonctionner lors des tests avec `curl -I`. Le flag `-I` envoie des requêtes HEAD, et un middleware qui vérifie la méthode GET ignorera le traitement, renvoyant les en-têtes du handler plutôt que ceux surchargés par le middleware.

npx skills add https://github.com/divinevideo/divine-mobile --skill curl-head-vs-get-header-debugging

curl -I envoie HEAD, pas GET — Piège du débogage des en-têtes

Problème

Lors du débogage des en-têtes de réponse HTTP avec curl -I ou curl -sI, la réponse peut afficher des valeurs d'en-têtes différentes de celles que les vraies requêtes GET reçoivent. C'est parce que -I envoie une requête HEAD, et les middlewares serveur qui ne traitent que les requêtes GET seront ignorés.

Contexte / Conditions de déclenchement

  • Test des en-têtes de cache avec curl -sI et observation de valeurs inattendues
  • Middleware qui vérifie method == GET avant de définir des en-têtes (courant dans les middlewares de cache)
  • Les en-têtes semblent corrects dans les tests automatisés mais incorrects dans les tests curl manuels
  • Les valeurs de Cache-Control, Surrogate-Control ou Surrogate-Key ne correspondent pas aux attentes
  • Middleware Axum/Express/tout framework avec des gardes de méthode

Solution

Utilisez curl -s -D - -o /dev/null à la place de curl -I pour obtenir les en-têtes de réponse d'une requête GET :

# INCORRECT — envoie une requête HEAD, le middleware peut ignorer le traitement
curl -sI https://example.com/api/endpoint

# CORRECT — envoie une requête GET, affiche les en-têtes, rejette le corps
curl -s -D - -o /dev/null https://example.com/api/endpoint

Si vous avez besoin seulement d'en-têtes spécifiques :

curl -s -D - -o /dev/null https://example.com/api/endpoint | grep -iE 'cache-control|surrogate'

Vérification

Comparez la sortie des deux méthodes :

echo "=== HEAD (curl -I) ===" 
curl -sI https://example.com/api/endpoint | grep cache-control

echo "=== GET (curl -D) ==="
curl -s -D - -o /dev/null https://example.com/api/endpoint | grep cache-control

Si les valeurs diffèrent, votre middleware a une garde réservée aux requêtes GET (ce qui est un comportement correct).

Exemple

Middleware Axum qui ne définit les en-têtes de cache que pour les requêtes GET :

async fn cache_middleware(request: Request, next: Next) -> Response {
    let method = request.method().clone();
    let mut response = next.run(request).await;

    // Les requêtes HEAD ignorent ceci — curl -I ne verra pas ces en-têtes !
    if method != Method::GET {
        return response;
    }

    response.headers_mut().insert("cache-control", ...);
    response.headers_mut().insert("surrogate-control", ...);
    response
}

Notes

  • Ce n'est PAS un bug — c'est un comportement correct. Les en-têtes de cache ne doivent s'appliquer qu'aux réponses GET cachées.
  • La spécification HTTP dit que les réponses HEAD DEVRAIENT inclure les mêmes en-têtes que GET, mais les implémentations de middleware ne les répliquent souvent pas parce que HEAD est rarement utilisé par les CDN ou les navigateurs pour les décisions de cache.
  • Fastly, Cloudflare et autres CDN envoient des requêtes GET aux origines, donc le comportement de cache est correct même si curl -I affiche des en-têtes différents.
  • Ce piège est particulièrement insidieux parce que curl -I est la façon la plus courante de vérifier les en-têtes.

Skills similaires