Résumé

  • Une action de fichier FTP se déroulait sur deux voies : les données transportaient les octets, tandis que la connexion de contrôle conservait l’état de la commande. Une réponse 1yz était favorable mais incomplète.
  • La fermeture de la connexion de données n’avait pas un sens unique : fin normale, abandon, changement de port, disparition du contrôle ou erreur irrécupérable pouvaient produire le même événement de transport.
  • Pendant un ABOR actif, 426 clôt négativement le transfert d’origine puis 226 clôt positivement la commande d’abandon. Garder seulement le dernier code transforme une annulation réussie en transfert réussi.

Deux lignes vertes ne faisaient pas une preuve

Un opérateur voit parfois deux signes rassurants : le nombre d’octets attendu a été atteint et TCP a fermé sans réinitialisation. Il serait tentant d’en déduire que la commande RETR ou STOR est terminée. Pourtant, ces observations appartiennent au trajet des données. Elles ne disent pas encore comment l’interpréteur FTP du serveur a classé l’action demandée.

Cette retenue vient de l’architecture même de FTP. La connexion de contrôle était durable ; elle portait les commandes et les réponses à trois chiffres. Une connexion de données distincte s’ouvrait pour une liste, un fichier ou une série de fichiers, puis pouvait disparaître tandis que la session continuait. La voie chargée des octets savait qu’un flux s’était arrêté. La voie chargée du dialogue savait quelle action était en cours et quel résultat lui était attribué.

Il ne s’agissait donc pas d’un transfert avec deux copies du même reçu. Chaque canal détenait une partie différente du dossier. Confondre ces parties revenait à laisser un événement TCP décider à la place de l’application.

Dès 1972, une fermeture pouvait signifier deux choses

La distinction apparaît avant la nomenclature moderne. La RFC 354, publiée en juillet 1972, proposait 252 FTP transfer completed correctly. Elle proposait séparément 452 FTP: File transfer incomplete, data connection closed.

Dans les deux cas, la connexion de données pouvait être fermée. Le code disait si l’action était considérée comme achevée ou incomplète. Cette paire ancienne suffit à invalider une règle souvent introduite beaucoup plus tard dans les tableaux de bord : « fermeture propre égale succès ».

Les premiers FTP reliaient des systèmes dont les représentations, les structures de fichier et les mots machine différaient. L’interpréteur de protocole du serveur devait coordonner une opération locale avec un processus de transfert. Le flux de données ne pouvait pas résumer à lui seul une conversion, une erreur de stockage ou l’état d’une commande.

Il restait à rendre cette distinction plus facile à automatiser. Le texte libre des réponses variait. Un client devait savoir, grâce aux chiffres, s’il pouvait continuer, s’il fallait attendre, fournir une information ou considérer la demande comme terminée.

Le premier chiffre est devenu une petite machine à états

La RFC 640 de 1974 a réorganisé les réponses autour de l’état de la demande. 1yz signifie positif préliminaire : l’action a commencé, mais elle n’est pas achevée et une autre réponse doit suivre. 2yz signifie achèvement positif. 3yz accepte la commande tout en attendant une information supplémentaire. 4yz et 5yz terminent négativement la demande, avec des implications différentes pour une nouvelle tentative.

Le mot positif change donc de sens selon la classe. 150 n’est pas un petit 226. Il permet au client de se tourner vers les données ; il ne lui permet pas de conclure que le fichier a été transféré.

La RFC 640 a en outre avancé le moment de la réponse préliminaire. Le serveur pouvait l’envoyer lorsque le transfert était possible et que la connexion de données existait ou allait être tentée. L’échange gagnait en rapidité, mais la portée de la preuve devenait très précise : le serveur annonçait une progression, pas un résultat.

Une commande avait encore une réponse à recevoir

La RFC 765, puis la RFC 959 en 1985, ont conservé cette séquence. La RFC 959 n’autorise au plus qu’une réponse 1yz pour une commande ; une réponse d’achèvement doit ensuite arriver.

Les tables des commandes de fichier montrent le parcours. 125 indique que la connexion de données est déjà ouverte et que le transfert commence. 150 indique que l’état du fichier est satisfaisant et que le serveur va ouvrir la connexion. Puis viennent 226 ou 250 lorsque l’action de fichier réussit, ou une fin négative telle que 425, 426, 451, 551 ou 552.

La position dans la séquence est aussi importante que le nombre. Une trace avec 150, plusieurs gigaoctets et un FIN reste incomplète si la réponse terminale manque. À l’inverse, un échec terminal ne disparaît pas parce que le compteur d’octets correspond à la taille attendue.

Cette discipline explique aussi pourquoi le client attend normalement la fin avant d’envoyer une nouvelle commande ordinaire. L’interpréteur est encore engagé dans la demande précédente. ABOR et STAT sont des exceptions difficiles justement parce qu’ils doivent pouvoir atteindre un travail en cours.

Fermer les données ne donnait pas la cause

La RFC 959 énumère plusieurs raisons pour lesquelles le serveur ferme la connexion de données. Le transfert peut avoir atteint sa fin normale. Le client peut avoir demandé l’abandon. Une nouvelle commande peut modifier le port de données. La connexion de contrôle peut se fermer normalement ou anormalement. Une erreur irrécupérable peut survenir.

Ces situations produisent une apparence voisine au niveau transport, mais elles ne racontent pas la même histoire. Même un FIN ordonné ne prouve ni que l’action s’est arrêtée à la bonne limite, ni que l’effet local a été validé, ni que le serveur n’a pas obéi à un abandon.

En mode Stream, la fermeture peut servir de marque de fin de fichier. C’est une règle de cadrage, pas un verdict universel. La difficulté est particulièrement visible dans les mécanismes de reprise : sans le dialogue de contrôle, une fin normale et une interruption prématurée peuvent devenir indiscernables.

Une collecte fidèle enregistre donc « EOF ou fermeture observée sur les données » et « commande FTP achevée avec telle réponse » comme deux événements. Ils peuvent se suivre à quelques millisecondes ; ils ne sont pas interchangeables.

L’abandon réussi n’était pas un transfert réussi

ABOR fournit le test le plus net. Si le service précédent est déjà terminé, la commande d’abandon ne change plus rien. Le serveur peut néanmoins répondre 226 pour dire qu’il a traité ABOR. Cette réponse appartient à la demande d’abandon.

Si le transfert est encore actif, la RFC 959 impose deux réponses. 426 annonce d’abord la fermeture de la connexion et l’interruption anormale du transfert d’origine. 226 annonce ensuite que la commande ABOR elle-même a été correctement exécutée.

La chronologie porte donc deux résultats :

  1. transfert initial : échec par abandon (426) ;
  2. commande d’abandon : réussite (226).

Un collecteur qui ne conserve que le dernier code donne du crédit au mauvais travail. Un collecteur qui attache les deux codes au transfert risque au contraire de déclarer l’abandon en échec. Il faut conserver l’ordre et l’action à laquelle chaque réponse met fin.

Ce que 226 ne promettait pas

Pour un transfert ordinaire, 226 affirme au niveau FTP que la connexion de données se ferme et que l’action de fichier demandée a réussi. Le code ne contient pas d’empreinte cryptographique, d’identifiant de version ou de garantie de stockage durable. Il ne prouve pas qu’une sauvegarde existe, qu’une autre application a consommé le fichier, ni qu’une obligation contractuelle est remplie.

Ces preuves peuvent être ajoutées, mais elles doivent rester nommées : somme de contrôle pour le contenu, journal de synchronisation pour la persistance locale, identifiant immuable pour la version, accusé applicatif pour l’usage ultérieur.

L’absence de 226 ne prouve pas davantage l’absence d’effet. Le serveur peut avoir écrit le fichier, puis perdre la connexion de contrôle avant que le client reçoive sa réponse. Une répétition aveugle peut dupliquer ou écraser. Le bon état est alors « résultat FTP inconnu », non « rien ne s’est passé ».

Une piste d’audit devait garder les deux temps

Le dossier minimal comprend la commande et son rang, 125 ou 150, le point de données choisi, le résultat de l’ouverture, les octets, l’EOF, la cause de fermeture si elle est connue, toutes les réponses terminales dans l’ordre et la position temporelle d’un ABOR ou d’un STAT.

Il faut y joindre les faits extérieurs au reçu FTP : mode et représentation, résolution du chemin, effets locaux, persistance, empreinte et identité de l’objet. Les joindre ne signifie pas les fusionner.

Un simple booléen done est trop pauvre. Des états distincts sont nécessaires : préliminaire accepté, données en attente, données actives, données closes en attente de réponse, transfert achevé positivement, transfert achevé négativement, abandon demandé, transfert abandonné, abandon traité, résultat inconnu.

Une fois cette succession supprimée, aucun examen ultérieur ne peut recréer l’action à laquelle appartenait le dernier code. La perte irréversible est sémantique : le système ne sait plus distinguer une réussite d’une annulation réussie.

Sources et limite de la preuve

L’analyse s’appuie sur les RFC 354, RFC 542, RFC 640, RFC 765, RFC 959 et RFC 1123. Elles établissent la séparation des connexions, les classes de réponse, les causes de fermeture et la séquence d’abandon.

La RFC 1123 signalait en 1989 que la reprise, ABOR et le mode Block étaient utiles mais peu répandus. C’est une observation datée, non une mesure du marché actuel. Ces sources ne prouvent ni le comportement des produits contemporains, ni leur conformité, ni la durabilité d’un système de fichiers.