FreeToGenerate.com

Lit une valeur de Date, Expires, Last-Modified ou Retry-After comme l’exige la RFC 9110, et montre où votre propre navigateur s’en écarte. Tout se passe dans votre navigateur ; rien n’est envoyé.

Essayez :

Retry-After

La règle des cinquante ans

Le format obsolète écrit l’année sur deux chiffres, et la RFC 9110 impose au destinataire de lire une valeur située à plus de cinquante ans dans le futur comme l’année passée la plus récente se terminant par ces chiffres. La réponse évolue donc : la limite avance d’un an chaque janvier, et une valeur qui signifie 2076 aujourd’hui signifiera 1976 dans cinquante et un ans.

Aussi disponible en : English · Español · Português · العربية

Analyseur de dates HTTP

Les trois formats autorisés par HTTP, ce que chacun signifie, et les six manières dont Date.parse les traite mal.

Qu’est-ce qu’une date HTTP ?

Tout horodatage figurant dans un en-tête HTTP — Date, Expires, Last-Modified, If-Modified-Since, ainsi que la forme datée de Retry-After — s’écrit dans un format que la RFC 9110 nomme HTTP-date. Il en existe trois, parce qu’avant 1995 les serveurs en utilisaient trois, et la spécification les définit tous les trois par compatibilité.

La règle qui les encadre est asymétrique, et c’est cette asymétrie qu’il faut retenir. Un destinataire qui analyse un horodatage « doit accepter les trois formats » ; un émetteur « doit produire ces horodatages au format IMF-fixdate ». Il n’existe donc qu’une seule graphie que vous ayez le droit de produire — Sun, 06 Nov 1994 08:49:37 GMT — et trois que vous devez savoir lire.

Les trois désignent un instant en UTC. Les deux premiers le disent par les lettres GMT ; le troisième, hérité de la fonction asctime du C, ne porte aucun fuseau, et la spécification se contente d’indiquer que ses valeurs sont réputées en UTC. C’est de cette phrase que naissent la plupart des ennuis.

Comment s’en servir

  1. Collez la valeur de l’en-tête. La valeur seule, sans le nom du champ. Les trois boutons d’exemple couvrent un format chacun, et le quatrième écrit l’instant présent comme un émetteur est tenu de le faire.
  2. Lisez la ligne du format et les notes en dessous. Vous obtenez l’instant en UTC et dans votre fuseau, lequel des trois formats c’est, si un émetteur a le droit de l’envoyer, et chaque écart par rapport à la grammaire.
  3. Comparez la dernière ligne à celle du dessus. Cette ligne, c’est ce que le Date.parse de votre navigateur fait de la même chaîne. En cas de divergence, l’écart s’affiche en secondes.

Six choses que Date.parse rate

La plus dommageable est asctime. Ce format ne porte pas de fuseau et la RFC 9110 précise que ses valeurs sont réputées en UTC, mais Date.parse le lit comme une heure locale : la réponse est décalée du décalage horaire de celui qui l’exécute, et n’est juste qu’à Greenwich. C’est le pire type de bogue : silencieux, plausible, et différent sur chaque machine. La ligne de comparaison de cette page s’exécute dans votre navigateur, précisément pour que vous voyiez ce que fait le vôtre.

Viennent ensuite les années sur deux chiffres. Le format obsolète de la RFC 850 écrit l’année sur deux chiffres, et la règle de la spécification est relative au présent : un destinataire doit lire une valeur située à plus de cinquante ans dans le futur comme l’année passée la plus récente se terminant par ces chiffres. Les moteurs JavaScript emploient au contraire un pivot fixe à 50. Aujourd’hui, les deux règles divergent sur 27 des 100 années possibles — toutes les valeurs de 50 à 76 — et comme la limite de la spécification avance chaque janvier, cet ensemble grandit d’une unité par an. Un 68 signifie 2068 selon la règle et 1968 selon le pivot : un siècle d’écart.

Une année à quatre chiffres inférieure à 100 subit le même sort. La grammaire dit que l’année compte quatre chiffres, donc 0094 est une façon légitime d’écrire l’an 94, et Date.parse la transforme quand même en 1994.

Le nom du jour est redondant, ce qui le rend doublement utile. S’il contredit la date, c’est que la valeur a été assemblée de travers : Mon, 06 Nov 1994 était un dimanche, et Date.parse l’accepte sans broncher. Il tranche aussi la question du siècle : l’exemple ci-dessus, Tuesday, 06-Nov-68, n’est cohérent que si l’année est 2068, car le 6 novembre 1968 était un mercredi. Le champ redondant lève l’ambiguïté de l’autre — heureux hasard, dans un format qui n’a jamais été conçu pour cela.

La grammaire autorise la seconde 60 pour une seconde intercalaire. Date.parse transforme 23:59:60 en 23:59:00 : il jette les secondes et perd une minute au lieu d’avancer d’une seconde.

Enfin, les dates impossibles. Le 31 novembre n’existe pas, et Date.parse renvoie le 1er décembre plutôt que NaN — une valeur qui paraîtra tout à fait raisonnable dans un journal.

Limites assumées

Cette page vérifie la valeur, pas le message dont elle provient. Savoir si un en-tête Date devait seulement être envoyé, si un cache peut s’en servir et si l’horloge de l’émetteur était juste sont des choses qu’une chaîne de caractères ne dit pas — la RFC 9110 autorise d’ailleurs explicitement un destinataire doté d’une horloge à remplacer une valeur de Date invalide par l’heure de réception.

Elle applique aussi la règle des cinquante ans telle qu’elle vaut aujourd’hui. C’est le comportement correct, et cela mérite d’être dit : le même horodatage RFC 850 signifie réellement des années différentes selon le moment où on le lit, donc une valeur consignée aujourd’hui et relue dans quelques décennies peut changer de sens. Aucun analyseur ne peut corriger cela : il manque simplement deux chiffres au format.

Le verdict de conformité porte sur la grammaire, pas sur le fait que la valeur fonctionnera. Un gmt en minuscules, un quantième à un chiffre et une espace de trop sont des choses que la spécification interdit de produire et que tous les analyseurs réels acceptent. La page vous dit de quel côté de cette limite vous êtes, au lieu de faire croire à un tout ou rien.

Le champ Retry-After distingue ses deux formes — un nombre entier de secondes ou un horodatage — car c’est le seul endroit où HTTP admet les deux, et c’est une source fréquente de confusion. Un nombre négatif et un nombre décimal ne sont ni l’un ni l’autre.

Pourquoi est-ce gratuit ?

Tout s’exécute dans votre navigateur. La valeur de l’en-tête n’est envoyée nulle part, ce qui compte pour une page comme celle-ci : un Last-Modified ou un If-Modified-Since issu d’un vrai système en dit long sur ce système.

Il n’y a aucun coût serveur à récupérer, donc pas de compte, pas de limite et pas de filigrane.