Annexe : structures de données minimales (Manifest/Chunk/State)

Cette annexe fournit des recommandations de structures de données minimales pour « découpage parallèle en blocs + transfert reprenable + nouvelles tentatives idempotentes ». L'objectif est de permettre une concurrence à haut débit et une reprise fiable après des pannes, sans transactions complexes.

Principes généraux

  • Gros objets et petit état : les blocs et le manifeste sont de gros objets stockés dans le stockage d'objets ; l'état est petit et stocké dans un magasin d'état.
  • Clés uniques et idempotence : un bloc DOIT être adressable de façon unique par (transferId, fileId, chunkIndex) afin de permettre des retransmissions idempotentes.
  • Reprise après incident : l'état DOIT exprimer l'« ensemble des blocs terminés » afin que la reprise puisse ignorer les parties terminées.
  • Aucune fuite d'informations sensibles : les clés d'objet et l'état DEVRAIENT éviter d'intégrer des champs sensibles tels que l'e-mail ou les noms de fichiers d'origine (le fait qu'ils soient chiffrés dépend de votre politique de confidentialité).

A.1 Champs minimaux du manifeste

Le manifeste est le « point d'entrée unique » du destinataire pour le téléchargement et le réassemblage. Recommandations minimales :

  • manifestVersion : DOIT. Sert aux mises à niveau de compatibilité (par ex. 1).
  • transferId : DOIT. Identifiant unique de la session de transfert.
  • createdAt / expiresAt : DEVRAIT. Pour la gestion du cycle de vie et les indications de l'interface.
  • policy : DEVRAIT. Un résumé de la politique (limites du nombre de téléchargements, exigence de mot de passe, partage autorisé ou non avant la fin du transfert, etc.).
  • files[] : DOIT. Description de la liste des fichiers (au minimum la taille des fichiers et les plages de blocs).
  • chunking : DOIT. Inclut chunkSize et la manière dont chunkCount est calculé, ou un chunkCount par fichier.
  • objectKeyRule : DOIT. Dériver les clés d'objet à partir de (transferId, fileId, chunkIndex), ou fournir une table de correspondance explicite.

A.1.1 Champs minimaux de files[]

  • fileId : DOIT. Identifiant de fichier unique (ne pas utiliser le nom de fichier comme clé unique).
  • size : DOIT. Taille en octets.
  • mime : PEUT. Pour l'affichage et les suggestions de téléchargement.
  • name : PEUT. Si vous voulez un Zero-Knowledge strict / une fuite minimale, omettez name ou stockez un nom chiffré.
  • chunkCount : DOIT. Nombre de blocs de ce fichier.
  • chunkOffset : PEUT. Si plusieurs fichiers partagent un chunkIndex global, un décalage est nécessaire ; sinon il peut être omis.

A.1.2 Champs d'intégrité et de vérification (facultatifs mais recommandés)

  • chunkHashes[] : DEVRAIT. Vérification par bloc (un élément ou une combinaison de hachage/longueur/etag).
  • fileHash : PEUT. Somme de contrôle du fichier entier (à vérifier après le téléchargement).
  • ciphertextLength : PEUT. Contrôles de cohérence de longueur au niveau du texte chiffré (sans avoir besoin du texte en clair).

A.2 Objets bloc (chunk) : contraintes minimales

  • Adressage unique : un bloc DOIT être adressable de façon unique par (transferId, fileId, chunkIndex).
  • Envoi idempotent : le renvoi du même bloc NE DOIT PAS corrompre l'état final (il peut écraser l'existant ou être rejeté, mais le comportement doit être cohérent).
  • Métadonnées minimales : le serveur PEUT n'enregistrer que la longueur du texte chiffré, l'heure d'écriture, l'etag/la version, etc., à des fins d'observabilité et de dépannage.

A.2.1 Règle de clé d'objet (exemple)

  • /transfers/{transferId}/chunks/{fileId}/{chunkIndex}
  • /transfers/{transferId}/manifest

Contrainte : les clés d'objet DOIVENT permettre un nettoyage en masse par préfixe transferId ; les clés d'objet DEVRAIENT éviter de porter des informations métier sensibles.

A.3 Enregistrements d'état : champs minimaux

L'état répond à « progression de l'envoi/du téléchargement et reprise ». Il doit être petit et rapide à lire/écrire.

  • transferId : DOIT.
  • status : DOIT. Valeurs suggérées : UPLOADING / READY / DELETED / EXPIRED.
  • uploadedSet : DOIT. Ensemble des blocs terminés ; DEVRAIT être compressé avec un bitmap / range-set.
  • uploadedBytes : DEVRAIT. Pour l'affichage de la progression et le contrôle des quotas (peut être déduit des blocs, mais le tenir à jour est plus rapide).
  • downloadCount : PEUT. Si vous appliquez des limites du nombre de téléchargements, il doit être enregistré et mis à jour de façon atomique (les détails dépendent de votre stockage).
  • expiresAt : DEVRAIT. Pour l'application de l'expiration et le nettoyage en arrière-plan.

A.3.1 Sortie minimale d'une API de reprise

Pour les transferts reprenables, le serveur DEVRAIT pouvoir renvoyer :

  • L'état du transfert (UPLOADING/READY/DELETED/EXPIRED)
  • uploadedSet (ensemble des blocs terminés)
  • Un résumé de la politique (par ex. quota dépassé, expiré, poursuite de l'envoi autorisée ou non)

Remarque : frontière avec le livre blanc sur la sécurité et la confidentialité

  • Cette annexe ne décrit que les « structures et contraintes » nécessaires au transfert et au stockage.
  • Pour les champs de chiffrement, la manière dont les éléments de clé sont transportés/dérivés et le comportement d'échec fermé (fail closed) en cas d'échec d'authentification, reportez-vous au livre blanc sur la sécurité et la confidentialité.