Summary

  • La révision 05 du projet Byte Range PATCH explique qu’un serveur dépourvu du traitement « PUT partiel » peut ignorer Content-Range et remplacer toute la ressource par le fragment reçu.
  • Avec message/byterange, une position d’écriture fait partie du document PATCH. Le serveur doit rejeter une modification sans plage connue, avec une réponse 400 ou 422.
  • La taille d’une partie, si elle est indiquée par Content-Length, doit correspondre exactement à la plage. Un serveur qui accepte des trous dans le fichier ne doit jamais révéler des données non initialisées.

La démonstration du projet tient dans douze octets. Un document contient 0123456789 et une fin de ligne. On veut écrire wxyz aux positions 2 à 5. Après l’opération, on doit lire 01wxyz6789 et la même fin de ligne. Si le serveur traite les quatre nouveaux octets comme une nouvelle version complète, il ne reste que wxyz. Voilà une corruption qui a l’air d’une requête parfaitement ordinaire.

Le piège est dans la rencontre entre la méthode et le champ. Le projet rappelle qu’un Content-Range envoyé avec PUT exige une prise en charge particulière. Sans elle, le traitement normal de PUT peut ignorer le champ et remplacer la ressource entière. Le client a dit où écrire. Le serveur a reçu des octets. Pourtant aucun accord partagé n’a établi que ces octets sont une pièce du fichier plutôt que son successeur.

PATCH change le lieu de cet accord. Le type message/byterange décrit une seule plage contiguë ; multipart/byteranges en transporte plusieurs ; le projet ajoute aussi une forme binaire, application/byteranges. La position figure dans le document dont le type indique justement une écriture par plage. Un programme qui accepte ce type accepte son sens. Un programme qui ne le connaît pas doit le refuser avant la mutation. La capacité devient vérifiable, au lieu de dépendre d’un en-tête que l’autre côté peut laisser de côté.

Le numéro d’octet est une obligation

Chaque partie doit désigner une plage contiguë. Si sa position n’est pas connue, le serveur doit répondre 400 ou 422. Lorsque Content-Length apparaît dans la partie, il doit correspondre à la longueur de la plage. Cette arithmétique protège la frontière du document : on ne peut pas prétendre remplacer quatre octets tout en livrant cinq octets sans qu’une erreur soit constatée.

Le projet prévoit aussi Content-Offset lorsque la fin des données n’est pas connue au départ. Un flux dont la longueur reste ouverte peut ainsi nommer le point de départ. Content-Range peut, lui, annoncer une taille totale ou employer * si cette taille n’est pas fixée. Les formes changent selon le flux ; le serveur doit toujours savoir où commence l’écriture.

L’extrémité du fichier pose un second problème. Écrire juste après le dernier octet l’allonge. Écrire plus loin laisse un espace indéfini. Le projet recommande de refuser ce saut. Si un serveur autorise les fichiers clairsemés, il doit empêcher la divulgation de contenu non initialisé et devrait remplir les régions indéfinies de zéros. Une interface qui présente ces deux cas comme un simple « ajout » masque une différence matérielle.

La section 4 propose en outre Prefer: transaction=atomic et transaction=persist pour choisir le sort d’un transfert interrompu. Le serveur devrait signaler la préférence honorée avec Preference-Applied. Cette option traite le moment de l’engagement ou de la conservation des données. Le sens de l’écriture partielle doit déjà être établi avant le premier octet modifié.

L’RFC 5789 fournit Accept-Patch pour annoncer les formats de document PATCH pris en charge. Il manque un essai public comparant, sur plusieurs serveurs, le même PUT avec plage et le même PATCH message/byterange, avec octets avant et après, code de réponse et ETag. Ce relevé montrerait le comportement réellement déployé.

Projet et état · RFC 5789 · RFC 9110