Résumé

  • Le RFC 2068 donnait au numéro de version deux objets précis : le format employé par l’émetteur et sa capacité maximale à comprendre les échanges HTTP suivants.
  • Un proxy ne transmettait pas le numéro comme une provenance scellée ; il devenait lui-même émetteur et devait annoncer une version qu’il pouvait réellement assumer.
  • La compatibilité entre versions mineures reposait sur une contrainte de construction : une fois retirés les champs nouveaux inconnus d’un destinataire ancien, le message devait rester valable pour lui.

Une chaîne HTTP n’était pas un tuyau unique. Le client parlait au premier intermédiaire, cet intermédiaire parlait au suivant, puis un dernier programme parlait au serveur d’origine. Le contenu pouvait paraître continu à l’utilisateur, mais chaque liaison constituait une relation protocolaire distincte. Le RFC 2068 a placé le numéro de version exactement à cette jointure.

L’idée est facile à perdre aujourd’hui parce qu’un numéro ressemble à une étiquette de produit. Dans le texte de 1997, HTTP/1.1 n’énumérait pourtant pas les fonctions observées dans le message courant. Il indiquait le format choisi par celui qui envoyait ce message et le niveau d’HTTP qu’il était capable de comprendre pour la suite. La différence séparait une déclaration de capacité d’une preuve d’exécution.

Une version ne racontait pas la totalité d’un logiciel

Le RFC 1945, publié en mai 1996, documentait l’usage commun d’HTTP/1.0 sans prétendre établir une norme Internet. Il distinguait déjà les fonctions généralement cohérentes des fonctions peu ou diversement implémentées. Son paragraphe sur les versions formulait néanmoins la règle reprise ensuite : le nombre décrivait la forme du message et la capacité de l’émetteur pour une communication ultérieure, non ce que cet échange avait effectivement obtenu.

Le contexte rendait cette discipline nécessaire. L’introduction du RFC 2068 signalait la multiplication de programmes incomplètement implémentés qui se présentaient malgré tout comme HTTP/1.0. Un nom commercial ou une chaîne de caractères dans une bannière ne suffisait donc pas à déterminer les possibilités du prochain échange.

Le couple majeur-mineur répartissait les changements. La partie majeure devait changer lorsque le format du message devenait incompatible. La partie mineure pouvait évoluer lorsque de nouvelles fonctions ajoutaient de la sémantique ou des capacités sans bouleverser l’algorithme général d’analyse. Un simple ajout dans une valeur déjà extensible ne justifiait pas, à lui seul, un nouveau numéro.

Ce dispositif protégeait un noyau commun strict, mais pas figé. Un ancien destinataire pouvait continuer à reconnaître l’enveloppe, tandis qu’un pair plus récent signalait qu’il saurait traiter davantage lors d’un échange futur.

Le chiffre annonçait un plafond, pas un inventaire

Dans le RFC 2068, toute application qui envoyait les requêtes ou réponses définies par le document devait inscrire HTTP/1.1 sur la première ligne. Cette inscription signifiait que l’application émettrice était au moins conforme sous conditions. La version d’une application correspondait au niveau HTTP le plus élevé pour lequel elle pouvait soutenir cette conformité.

Trois éléments de preuve devaient rester séparés. La syntaxe du message indiquait comment lire cette unité sur cette liaison. La version annoncée indiquait le plafond que l’émetteur prétendait pouvoir assumer. Les fonctions réellement présentes formaient un troisième ensemble, parfois très réduit.

Une requête HTTP/1.1 pouvait ainsi n’employer aucune nouveauté visible. Cela ne rabaissait pas nécessairement l’émetteur à HTTP/1.0 : le nombre pouvait préparer la réponse ou les requêtes suivantes. Inversement, voir HTTP/1.1 ne prouvait pas l’utilisation du transfert segmenté, d’une connexion persistante, d’une directive de cache ou d’une négociation de contenu.

La déclaration ne prouvait pas davantage l’identité de l’émetteur, la fidélité de son code, la conservation d’un champ par tous les intermédiaires, la réception par le serveur final ou la réussite d’une action métier. Elle donnait au prochain pair un renseignement borné, utilisable pour une décision bornée.

À chaque saut, un nouvel émetteur

Un proxy interprétait une requête avant de la reformuler. Il pouvait modifier des champs, traduire entre versions ou répondre lui-même. Le RFC 2068 lui interdisait donc d’envoyer un numéro supérieur à sa capacité réelle.

Face à une requête plus récente que lui, l’intermédiaire devait choisir : abaisser la version, renvoyer une erreur, ou devenir tunnel et cesser d’interpréter les messages HTTP transportés. Une requête plus ancienne pouvait parfois être rehaussée avant d’être transmise. La conversion pouvait exiger l’ajout ou la suppression de champs.

Le numéro reçu en amont n’était pas un droit transmissible. Un proxy HTTP/1.0 ne pouvait pas recopier HTTP/1.1 pour bénéficier du prestige ou des effets pratiques de la capacité du client. Dès qu’il construisait le message sortant, il prenait la responsabilité de la déclaration.

Le RFC 2145, publié en mai 1997 pour lever les ambiguïtés, a nommé cette propriété sans détour : les versions HTTP étaient des composants de saut en saut, et non de bout en bout. Un proxy ne « transférait » jamais le numéro d’une requête ou d’une réponse. Le champ Via pouvait conserver séparément les protocoles observés sur les segments précédents, sans transformer cette trace en garantie globale.

Cette architecture rend impossible une conclusion pourtant tentante. Le HTTP/1.1 reçu par l’origine ne démontre pas que le navigateur avait parlé HTTP/1.1 à chaque maillon. Celui que reçoit le navigateur ne démontre pas non plus que l’origine l’avait écrit. Il faut des observations par liaison.

Le test de suppression finançait l’évolution

Les versions mineures ne pouvaient rester compatibles que si les nouveautés n’altéraient pas secrètement le sens des anciens champs. Le RFC 2145 affirme que, dans une même version majeure, le numéro mineur ne devait pas changer leur interprétation. Il décrivait la capacité de l’émetteur, non un dictionnaire différent pour ce message.

Un émetteur récent pouvait tout de même ajouter un champ inconnu d’un destinataire plus ancien. Il ne pouvait simplement pas dépendre de sa compréhension. Pour un message HTTP/1.1 adressé à un destinataire HTTP/1.0, ou dont la version était inconnue, le message devait rester un message HTTP/1.0 valable lorsque les champs absents de l’ancienne spécification étaient supprimés.

La charge de la compatibilité pesait donc sur celui qui introduisait la nouveauté. Le destinataire ancien n’avait pas à deviner les futures extensions. L’émetteur récent devait préserver un résultat cohérent après retrait de ce que l’autre ne connaissait pas.

Cette tolérance avait des frontières. Un proxy devait normalement retransmettre un champ inconnu afin de ne pas étouffer une extension destinée à un pair plus lointain. En revanche, les champs nommés par Connection appartenaient à la liaison immédiate et devaient disparaître au prochain saut. Surtout, une fonction indispensable au cadrage ne pouvait pas être abandonnée comme une décoration. Un serveur HTTP/1.1 ne devait pas répondre en transfert segmenté à une requête HTTP/1.0 en supposant que l’ancien client ignorerait simplement l’en-tête.

La règle n’était donc pas « ignorer suffit ». Elle exigeait que le message résiduel possède encore une grammaire et un sens exploitables.

Pourquoi un RFC entier a été nécessaire pour expliquer deux chiffres

Le RFC 2145 constitue un document historique parce qu’il dit qu’une confusion réelle existait. Des lecteurs avaient compris les textes différemment ; des implémentations avaient suivi des politiques incompatibles ; des problèmes d’interopérabilité en avaient résulté. Le document ne fournit toutefois ni liste de produits ni mesure de fréquence. Il établit la frontière normative, pas l’ampleur du parc affecté.

Il a aussi encadré le choix du numéro envoyé. Un client devait normalement annoncer son niveau conforme le plus élevé, sous réserve de ne pas dépasser la version majeure supportée par le serveur lorsqu’elle était connue. Un serveur devait choisir son plus haut niveau conforme dont la partie majeure restait compatible avec la requête. Aucun ne devait revendiquer une version qu’il ne respectait pas.

L’abaissement volontaire pour contourner un pair défectueux restait possible après observation du défaut. Il ne devait pas devenir une habitude générale. Sans cette précaution, les programmes corrects auraient appris à mentir pour s’adapter aux programmes incorrects, transformant la version en folklore.

Le RFC 2616 a repris l’essentiel et renvoyé au RFC 2145. En 2014, le RFC 7230 les a remplacés et a reformulé l’idée de manière particulièrement claire : même si le message courant n’emploie qu’un sous-ensemble rétrocompatible, la version mineure annonce ce que l’émetteur peut comprendre plus tard. Il a également noté que le passage du RFC 2068 au RFC 2616 n’avait pas augmenté le numéro mineur. Une révision documentaire ne produisait donc pas mécaniquement un nouveau signal sur le fil.

Le RFC 9110 a ensuite séparé les sémantiques communes d’HTTP des syntaxes de message d’HTTP/1.1, HTTP/2 et HTTP/3. Ces grandes versions coexistent ; elles ne forment pas une simple échelle où la dernière efface les précédentes. Lorsqu’un intermédiaire transmet un message, la version reflète le protocole qu’il emploie lui-même, et Via garde une information distincte sur l’amont.

Une lecture rétrospective, pas une intention inventée

Le triptyque de Lu Heng — spécification initiale minimale, décision future localisée et adoption volontaire — aide à relire cette architecture. Le noyau commun est suffisamment précis pour une vérification locale. La décision de traiter un message reste entre les mains du pair qui exécute le code. Une capacité nouvelle devient réelle par l’implémentation et l’interopération, non par le seul fait qu’un document existe ou qu’un nombre plus élevé soit affiché.

Cette lecture date d’après les RFC étudiés. Elle ne prouve pas que leurs auteurs partageaient les thèses institutionnelles ou les propositions de registre distribué de Lu Heng. Elle sert à empêcher une erreur éditoriale : confondre une coordination publiée avec un fait exécuté.

La force du numéro de version venait finalement de sa modestie. Sur chaque saut, un émetteur disait ce qu’il pouvait assumer. Le destinataire conservait la décision locale. La nouveauté ne devenait compatible qu’en laissant un ancien message valide derrière elle. Rien dans ces deux chiffres ne remplaçait l’observation du reste de la chaîne.

Sources