Aller au contenu principal

14. Range Requests (Requêtes de plage)

Les clients rencontrent souvent des transferts interrompus ou ont besoin d'obtenir seulement un sous-ensemble d'une grande représentation. Les requêtes de plage sont une fonctionnalité optionnelle qui permet aux clients de demander une ou plusieurs sous-plages de la représentation sélectionnée, plutôt que la représentation entière.

Le mécanisme de requête de plage est utile dans plusieurs scénarios différents :

  • Les téléchargements partiels de gros fichiers peuvent être divisés en plusieurs requêtes simultanées, accélérant ainsi la récupération globale
  • Les transferts interrompus peuvent reprendre depuis le point d'interruption plutôt que de recommencer
  • Certains types de médias permettent un rendu ou une lecture incrémentale, et les agents utilisateurs peuvent commencer à traiter les données dès leur réception

Les serveurs ne sont pas tenus de prendre en charge les requêtes de plage. Cependant, les serveurs d'origine DEVRAIENT prendre en charge les requêtes de plage, car elles peuvent réduire l'utilisation du réseau et améliorer la réactivité du service.

14.1. Range Units (Unités de plage)

Les représentations peuvent être partitionnées en sous-plages de différentes manières. Une unité de plage définit comment les données de représentation sont partitionnées.

range-unit       = token

Tous les noms d'unités de plage sont insensibles à la casse et DEVRAIENT être enregistrés dans le registre HTTP Range Unit Registry.

14.1.1. Range Specifiers (Spécificateurs de plage)

Un spécificateur de plage définit une ou plusieurs sous-plages de données de représentation.

range-spec       = range-unit "=" range-set
range-set = 1#range-spec-value
range-spec-value = int-range / suffix-range / other-range

Les unités de plage permettent aux clients d'indiquer quel type de plage ils demandent.

14.1.2. Byte Ranges (Plages d'octets)

L'unité de plage "bytes" est définie pour HTTP, représentant des sous-plages d'une séquence d'octets (c'est-à-dire des plages d'octets).

byte-ranges-specifier = bytes-unit "=" byte-range-set
byte-range-set = 1#byte-range-spec
byte-range-spec = first-byte-pos "-" [ last-byte-pos ]
/ suffix-byte-range-spec
suffix-byte-range-spec = "-" suffix-length

first-byte-pos = 1*DIGIT
last-byte-pos = 1*DIGIT
suffix-length = 1*DIGIT
bytes-unit = "bytes"

La valeur first-byte-pos donne le décalage d'octet du premier octet de la plage. La valeur last-byte-pos donne le décalage d'octet du dernier octet de la plage ; c'est-à-dire que les positions d'octets spécifiées sont inclusives. Les décalages d'octets commencent à zéro.

Exemples :

  • bytes=0-499 représente les 500 premiers octets
  • bytes=500-999 représente les 500 deuxièmes octets
  • bytes=-500 représente les 500 derniers octets
  • bytes=500- représente tous les octets à partir de l'octet 500
  • bytes=0-0,-1 représente le premier et le dernier octet

14.2. Range

Le champ d'en-tête "Range" est utilisé pour demander une ou plusieurs sous-plages de données de représentation.

Range = range-unit "=" range-set

Un serveur PEUT ignorer le champ d'en-tête Range. Cependant, les serveurs d'origine et les caches intermédiaires DEVRAIENT prendre en charge les plages d'octets lorsque cela est possible, car la prise en charge des plages permet une récupération efficace des transferts partiellement échoués et une récupération partielle de grandes représentations.

Un serveur DOIT ignorer un champ d'en-tête Range reçu avec une méthode de requête autre que GET.

Un serveur d'origine qui prend en charge le champ d'en-tête Range DOIT, si toutes les préconditions sont vraies :

  1. Ignorer le champ d'en-tête Range s'il contient une unité de plage qu'il ne prend pas en charge
  2. Retourner un code d'état 416 (Range Not Satisfiable) si le champ d'en-tête Range est syntaxiquement invalide
  3. Retourner une réponse 206 (Partial Content) contenant une ou plusieurs représentations partielles si le champ d'en-tête Range contient un ensemble de plages d'octets satisfaisables

Exemple de requête :

GET /document HTTP/1.1
Host: www.example.com
Range: bytes=0-1023

14.3. Accept-Ranges

Le champ d'en-tête "Accept-Ranges" permet à un serveur d'indiquer qu'il prend en charge les requêtes de plage pour la ressource cible.

Accept-Ranges = acceptable-ranges
acceptable-ranges = 1#range-unit / "none"

Un serveur d'origine qui accepte les requêtes de plage pour une ressource cible donnée DEVRAIT envoyer un champ d'en-tête Accept-Ranges pour indiquer quelles unités de plage sont prises en charge. Un client PEUT générer des requêtes de plage sans recevoir ce champ d'en-tête.

Exemples :

Accept-Ranges: bytes
Accept-Ranges: none

La valeur "none" indique qu'aucune unité de plage n'est acceptée, ce qui signifie que le serveur ne prend en charge aucune requête de plage pour cette ressource.

14.4. Content-Range

Le champ d'en-tête "Content-Range" est envoyé dans une réponse 206 (Partial Content) à partie unique pour indiquer la plage d'octets de la représentation partielle incluse, ou dans une réponse 416 (Range Not Satisfiable) pour fournir des informations sur la représentation sélectionnée.

Content-Range       = range-unit SP
( range-resp / unsatisfied-range )

range-resp = byte-content-range
/ other-range-resp
byte-content-range = bytes-unit SP
( byte-range-resp / unsatisfied-range )

byte-range-resp = first-byte-pos "-" last-byte-pos
"/" ( complete-length / "*" )
complete-length = 1*DIGIT

unsatisfied-range = "*/" complete-length

other-range-resp = *CHAR

Exemples :

Content-Range: bytes 0-1023/5000
Content-Range: bytes 1024-2047/5000
Content-Range: bytes */5000

Le premier exemple indique que les 1024 premiers octets d'une représentation complète (d'une longueur de 5000 octets) sont en cours de transfert. Le troisième exemple indique qu'une requête de plage n'a pas pu être satisfaite car la longueur complète de la représentation sélectionnée est de 5000 octets.

14.5. Partial PUT (PUT partiel)

Une requête PUT partielle n'est pas une requête de plage, mais elle utilise le même mécanisme que les requêtes de plage pour décrire le contenu transféré. Un client peut envoyer un PUT partiel en incluant un champ d'en-tête Content-Range dans la requête PUT.

Cependant, le PUT partiel est rarement utilisé en pratique car :

  1. Il nécessite que le client connaisse l'état actuel de la ressource
  2. Il est vulnérable aux conditions de concurrence
  3. La plupart des serveurs d'origine ne le prennent pas en charge

Par conséquent, les clients NE DEVRAIENT PAS utiliser le PUT partiel à moins d'être certains que le serveur cible le prend en charge.

14.6. Media Type multipart/byteranges (Type de média multipart/byteranges)

Lors de l'envoi de plusieurs plages, un serveur DEVRAIT utiliser le type de média multipart/byteranges.

multipart/byteranges

Chaque partie de corps de ce type de média DOIT inclure :

  • Un champ d'en-tête Content-Type indiquant le type de média de la représentation contenue dans cette partie de corps
  • Un champ d'en-tête Content-Range indiquant la plage contenue

Exemple de réponse :

HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES

--THIS_STRING_SEPARATES
Content-Type: text/html
Content-Range: bytes 0-100/1234

[101 premiers octets]
--THIS_STRING_SEPARATES
Content-Type: text/html
Content-Range: bytes 500-999/1234

[octets 500-999]
--THIS_STRING_SEPARATES--

Lorsqu'un client demande plusieurs plages disjointes, un serveur DEVRAIT retourner une réponse multipartie uniquement si :

  1. Les plages ne se chevauchent pas
  2. L'ordre des plages est le même que leur ordre dans la représentation

Sinon, le serveur DEVRAIT retourner la représentation entière ou fusionner les plages qui se chevauchent.