Réessayez après l’en-tête de réponse HTTP – cela affecte-t-il quelque chose?

Si je veux refuser poliment le service sur un site Web en raison d’une surcharge temporaire, la réponse HTTP 503 Service non disponible semble appropriée. La spécification mentionne l’envoi d’un en – tête Retry-after avec le 503.

Y a-t-il un point? Est-ce que Retry-after affecte quelque chose? Les navigateurs y prêtent-ils attention?

L’état actuel de l’en tête Retry-After

L’implémentation de l’en tête Retry-After dans les clients et les serveurs a légèrement changé ces dernières années depuis la publication initiale de cette question. J’ai donc pensé fournir une réponse actualisée.

Tout d’abord, RFC 2616, section 14.37 Retry-After déclare:

Le champ d’en-tête de réponse Retry-After peut être utilisé avec une réponse 503 (Service non disponible) pour indiquer combien de temps le service est censé être indisponible pour le client demandeur.

Deux exemples de son utilisation sont

  Retry-After: Fri, 31 Dec 1999 23:59:59 GMT Retry-After: 120 

Dans ce dernier exemple, le délai est de 2 minutes.

Prise en charge des logiciels client et serveur

Les éléments suivants sont des messages de validation du référentiel de code, des annonces et de la documentation concernant l’en tête Retry-After dans divers logiciels.

Chrome / Chrome

Un code validé le 22 novembre 2012 avec le message du journal: Ajout des délais de détection et utilisation de l’en-tête HTTP Retry-After .

Mozilla / Firefox

Un code validé le 27 mars 2012 avec le journal de connexion: implémenter le traitement de 5xxs, X-Weave-Backoff, puis réessayer . En outre, il existe trois autres mentions d’en-tête Retry-After dans leur référentiel Mercurial.

Un bug a été initialement soumis le 6 janvier 2004 avec le titre Retry-After envoyé avec la réponse HTTP 503 est ignoré .

Googlebot

Un article du blog Google Webmaster Central traitant de la gestion des temps d’arrêt des sites mentionne que l’en -tête Retry-After peut être utilisé pour déterminer le moment de la récupération de l’URL .

Bingbot / Msnbot

Impossible de trouver un document de support officiel Retry-After. Cependant, il y a eu quelques mentions dans des forums aléatoires sur l’utilisation de cet en-tête dans une réponse 503 pour limiter les bots de Microsoft.

Nginx

La directive add_header indique:

Ajoute le champ spécifié à un en-tête de réponse à condition que le code de réponse soit égal à 200, 201, 204, 206, 301, 302, 303, 304 ou 307.

Par conséquent, pour append l’en-tête Retry-After pour une réponse 503 à l’aide de la version:

  • 1.7.4 et versions antérieures, utilisez un module tiers, tel que les en- têtes plus .

  • 1.7.5 et versions ultérieures, ajoutez le paramètre always à la directive add_header .

Apache

Contrairement à Nginx, la documentation de l’en-tête Apache ne donne aucune indication qu’il ne peut pas envoyer un en-tête Retry-After sur une réponse 503. En ce qui concerne les réponses non-2xx, cependant, les documents indiquent:

append un en-tête à une réponse non réussie (non-2xx) générée localement, telle qu’une redirection, auquel cas seule la table correspondant à toujours est utilisée dans la réponse finale.

Voici une réponse SO qui définit un en-tête Retry-After avec la condition Toujours pour 503 réponses, comme le conseille doc.

Un article AskApache fournit d’autres exemples de configuration sur la manière de demander aux moteurs de recherche de revenir en arrière en utilisant une réponse 503 avec un en-tête Retry-After.

Test client

J’ai écrit un serveur Ruby qui renvoie simplement une réponse 503 avec un en-tête Retry-After défini sur 10 secondes et un corps contenant un nombre aléatoire.

 require 'sinatra' get '/' do headers 'Content-Type' => 'text/plain', 'Retry-After' => '10' status 503 body rand(1000).to_s end 

Je l’ai accédé sur:

  • OpenBSD 5.8 utilisant Chromium 44, Firefox-ESR 38 et Seamonkey 2.33,
  • Mac OSX 10.7.5 avec Chrome 47 et Safari 6.1,
  • Windows 10 utilisant Chrome 48, Firefox 41 et Edge 25.

Je m’attendais à ce que ces navigateurs actualisent automatiquement l’URL après 10 secondes et affichent un nouveau nombre aléatoire. Cependant, tous les navigateurs n’ont pas réessayé, même après plusieurs minutes. J’ai essayé des périodes de réessai plus longues et plus courtes avec les mêmes résultats. Le journal d’access au serveur a confirmé qu’aucune nouvelle tentative n’a été effectuée depuis ces navigateurs.

En outre, une actualisation «souple» avant la période de réessai a immédiatement récupéré l’URL. Ainsi, l’en-tête Retry-After ne peut pas être utilisé pour limiter les utilisateurs «à la mode». Je mentionne cela parce que j’ai vu dans un forum que cet en-tête pouvait être utilisé pour limiter les utilisateurs impatients de bash votre site.

Par ailleurs, il semble logique qu’une actualisation «logicielle» n’ait aucune action avant le délai d’expiration, mais une actualisation «matérielle» ou de contournement du cache ignore tout délai d’expiration et récupère immédiatement l’URL.

Conclusion

La prise en charge de l’en tête Retry-After semble encore un peu sommaire sur les clients et les serveurs. Néanmoins, il est judicieux de définir un délai d’attente pour les réponses 503 si cela n’est pas difficile à configurer.

Même si Googlebot est le seul client à prendre en charge l’en-tête et à réessayer après le délai d’expiration, il peut empêcher la désindexation de vos pages, par opposition à une réponse 404, 500, 502 ou 504.

Je vois cela comme un problème de poulet et d’œuf: Aucun navigateur n’implémente actuellement Retry-after car aucun site Web ne s’y intéresse. À mon avis, allez-y et envoyez-le comme un service aux utilisateurs. Si leur choix de navigateur Web ne l’implémente pas, alors leur navigateur ne leur donne pas d’informations utiles. Tu l’as fait!

Lorsque je cherche à implémenter des standards avec de multiples implémentations concurrentes, j’essaie toujours de respecter les standards et de ne pas faire attention aux différentes implémentations (sauf si j’essaie d’imiter une implémentation telle que cURLing mais déguiser mes en-têtes pour navigateur web). Sinon, nous nous retrouvons avec des normes de facto, qui si vous vous souvenez des jours de domination IE que vous ne voulez pas!

Si vous voulez envoyer un rafraîchissement automatique après X fois, vous pouvez envoyer un

 Refresh: 120; url=http://your_url.com 

en PHP:

 header("Refresh: " .$retry_time."; url=". $url); 

Pour actualiser la page en cours, vous pouvez utiliser $_SERVER["REQUEST_URI"] pour $ url.

J’ai testé cet en-tête avec succès dans différentes versions d’Opera, Firefox et Internet Explorer.

Cet en-tête fonctionne même pour rafraîchir le contenu binary comme des images (mais uniquement lorsque celui-ci est chargé directement ou dans un cadre – une balise IMG ne se recharge pas).