Aller au contenu principal

4. Réponses à une requête de plage

4.1 206 Partial Content​

Le code d'état 206 (Partial Content) indique que le serveur satisfait avec succès une requête de plage pour la ressource cible en transférant une ou plusieurs parties de la représentation sélectionnée qui correspondent aux plages satisfaisables trouvées dans le champ d'en-tête Range de la requête (section 3.1).

Si une seule partie est transférée, le serveur qui génère la réponse 206 doit générer un champ d'en-tête Content-Range décrivant la plage de la représentation sélectionnée qui est incluse, ainsi qu'une charge utile constituée de cette plage (MUST). Par exemple :

HTTP/1.1 206 Partial Content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-Range: bytes 21010-47021/47022
Content-Length: 26012
Content-Type: image/gif

... 26012 bytes of partial image data ...

Si plusieurs parties sont transférées, le serveur qui génère la réponse 206 doit générer une charge utile "multipart/byteranges", telle que définie à l'annexe A, ainsi qu'un champ d'en-tête Content-Type contenant le type de média multipart/byteranges et son paramètre boundary obligatoire (MUST). Pour éviter toute confusion avec les réponses à partie unique, un serveur ne doit pas générer de champ d'en-tête Content-Range dans la section d'en-tête HTTP d'une réponse à plusieurs parties (ce champ est envoyé dans chaque partie à la place) (MUST NOT).

Dans la zone d'en-tête de chaque partie de corps de la charge utile multipart, le serveur doit générer un champ d'en-tête Content-Range correspondant à la plage incluse dans cette partie de corps (MUST). Si la représentation sélectionnée aurait eu un champ d'en-tête Content-Type dans une réponse 200 (OK), le serveur devrait générer ce même champ Content-Type dans la zone d'en-tête de chaque partie de corps (SHOULD). Par exemple :

HTTP/1.1 206 Partial Content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-Length: 1741
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES

--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 500-999/8000

...the first range...
--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 7000-7999/8000

...the second range
--THIS_STRING_SEPARATES--

Lorsque plusieurs plages sont demandées, un serveur peut fusionner celles qui se chevauchent, ou que sépare un intervalle inférieur au surcoût d'envoi de plusieurs parties, indépendamment de l'ordre dans lequel les byte-range-spec correspondantes apparaissaient dans le champ d'en-tête Range reçu (MAY). Le surcoût typique entre les parties d'une charge utile multipart/byteranges étant d'environ 80 octets, selon le type de média de la représentation sélectionnée et la longueur choisie pour le paramètre boundary, il peut être moins efficace de transférer de nombreuses petites parties disjointes que de transférer la représentation sélectionnée entière.

Un serveur ne doit pas générer de réponse multipart en réponse à une demande de plage unique, car un client qui ne demande pas plusieurs parties pourrait ne pas prendre en charge les réponses multipart (MUST NOT). Toutefois, un serveur peut générer une charge utile multipart/byteranges ne comportant qu'une seule partie de corps si plusieurs plages ont été demandées et qu'une seule plage s'est révélée satisfaisable, ou qu'une seule plage subsistait après fusion (MAY). Un client incapable de traiter une réponse multipart/byteranges ne doit pas générer de requête demandant plusieurs plages (MUST NOT).

Lorsqu'une charge utile de réponse multipart est générée, le serveur devrait envoyer les parties dans le même ordre que celui dans lequel les byte-range-spec correspondantes apparaissaient dans le champ d'en-tête Range reçu, à l'exclusion des plages jugées non satisfaisables et de celles fusionnées avec d'autres plages (SHOULD). Un client qui reçoit une réponse multipart doit examiner le champ d'en-tête Content-Range présent dans chaque partie de corps afin de déterminer quelle plage est contenue dans cette partie ; un client ne peut se fier ni à la réception des mêmes plages que celles qu'il a demandées, ni au même ordre que celui qu'il a demandé (MUST).

Lorsqu'une réponse 206 est générée, le serveur doit générer les champs d'en-tête suivants, en plus de ceux exigés ci-dessus, si le champ aurait été envoyé dans une réponse 200 (OK) à la même requête : Date, Cache-Control, ETag, Expires, Content-Location et Vary (MUST).

Si une réponse 206 est générée en réponse à une requête comportant un champ d'en-tête If-Range, l'expéditeur devrait éviter de générer d'autres champs d'en-tête de représentation que ceux exigés ci-dessus, car le client est censé posséder déjà une réponse antérieure contenant ces champs d'en-tête (SHOULD NOT). Sinon, l'expéditeur doit générer tous les champs d'en-tête de représentation qui auraient été envoyés dans une réponse 200 (OK) à la même requête (MUST).

Une réponse 206 est cachable par défaut ; autrement dit, sauf indication contraire de contrôles de cache explicites (voir la section 4.2.2 de [RFC7234]).

4.2 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 partielle de la représentation sélectionnée incluse comme charge utile du message, dans chaque partie d'une réponse 206 multipart pour indiquer la plage incluse dans chaque partie de corps, et dans les réponses 416 (Range Not Satisfiable) pour fournir des informations sur la représentation sélectionnée.

Content-Range = byte-content-range / other-content-range

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

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

complete-length = 1*DIGIT

other-content-range = other-range-unit SP other-range-resp
other-range-resp = *CHAR

Si une réponse 206 (Partial Content) contient un champ d'en-tête Content-Range dont l'unité de plage (section 2) n'est pas comprise par le destinataire, celui-ci ne doit pas tenter de la recombiner avec une représentation stockée (MUST NOT). Un mandataire qui reçoit un tel message devrait le transmettre en aval (SHOULD).

Pour les plages d'octets, un expéditeur devrait indiquer la longueur complète de la représentation de laquelle la plage a été extraite, sauf si cette longueur complète est inconnue ou difficile à déterminer (SHOULD). Un astérisque ("*") à la place de la longueur complète indique que la longueur de la représentation était inconnue lors de la génération du champ d'en-tête.

L'exemple suivant illustre le cas où l'expéditeur sait que la longueur complète de la représentation sélectionnée est de 1234 octets :

Content-Range: bytes 42-1233/1234

et ce second exemple illustre le cas où la longueur complète est inconnue :

Content-Range: bytes 42-1233/*

Une valeur de champ Content-Range est invalide si elle contient une byte-range-resp dont la valeur last-byte-pos est inférieure à sa valeur first-byte-pos, ou une valeur complete-length inférieure ou égale à sa valeur last-byte-pos. Le destinataire d'un Content-Range invalide ne doit pas tenter de recombiner le contenu reçu avec une représentation stockée (MUST NOT).

Un serveur qui génère une réponse 416 (Range Not Satisfiable) à une requête de plage d'octets devrait envoyer un champ d'en-tête Content-Range avec une valeur unsatisfied-range, comme dans l'exemple suivant (SHOULD) :

Content-Range: bytes */1234

La complete-length d'une réponse 416 indique la longueur courante de la représentation sélectionnée.

Le champ d'en-tête Content-Range n'a pas de signification pour les codes d'état qui ne décrivent pas explicitement sa sémantique. Pour la présente spécification, seuls les codes d'état 206 (Partial Content) et 416 (Range Not Satisfiable) décrivent une signification pour Content-Range.

Les exemples suivants sont des valeurs de Content-Range pour lesquelles la représentation sélectionnée contient un total de 1234 octets :

  • Les 500 premiers octets : Content-Range: bytes 0-499/1234

  • Les 500 octets suivants : Content-Range: bytes 500-999/1234

  • Tous sauf les 500 premiers octets : Content-Range: bytes 500-1233/1234

  • Les 500 derniers octets : Content-Range: bytes 734-1233/1234

4.3 Combinaison de plages​

Une réponse peut ne transférer qu'une sous-plage d'une représentation si la connexion a été fermée prématurément ou si la requête a utilisé une ou plusieurs spécifications Range. Après plusieurs transferts de ce type, un client peut avoir reçu plusieurs plages d'une même représentation. Ces plages ne peuvent être combinées en toute sécurité que si elles ont toutes en commun le même validateur fort (section 2.1 de [RFC7232]).

Un client qui a reçu plusieurs réponses partielles à des requêtes GET sur une ressource cible peut combiner ces réponses en une plage continue plus grande si elles partagent le même validateur fort (MAY).

Si la réponse la plus récente est une réponse 200 (OK) incomplète, les champs d'en-tête de cette réponse sont utilisés pour toute réponse combinée et remplacent ceux des réponses stockées correspondantes.

Si la réponse la plus récente est une réponse 206 (Partial Content) et qu'au moins une des réponses stockées correspondantes est une 200 (OK), les champs d'en-tête de la réponse combinée sont ceux de la réponse 200 la plus récente. Si toutes les réponses stockées correspondantes sont des réponses 206, la réponse stockée dont les champs d'en-tête sont les plus récents sert de source pour les champs d'en-tête de la réponse combinée, étant entendu que le client doit utiliser les autres champs d'en-tête fournis dans la nouvelle réponse, à l'exception de Content-Range, pour remplacer toutes les occurrences des champs d'en-tête correspondants dans la réponse stockée (MUST).

Le corps du message de réponse combinée est constitué de l'union des plages de contenu partiel de la nouvelle réponse et de chacune des réponses sélectionnées. Si cette union couvre la totalité de la plage de la représentation, le client doit traiter la réponse combinée comme s'il s'agissait d'une réponse 200 (OK) complète, y compris un champ d'en-tête Content-Length reflétant la longueur complète (MUST). Sinon, le client doit traiter l'ensemble des plages continues comme l'un des éléments suivants : une réponse 200 (OK) incomplète si la réponse combinée est un préfixe de la représentation, une réponse 206 (Partial Content) unique contenant un corps multipart/byteranges, ou plusieurs réponses 206 (Partial Content) contenant chacune une plage continue indiquée par un champ d'en-tête Content-Range (MUST).

4.4 416 Range Not Satisfiable​

Le code d'état 416 (Range Not Satisfiable) indique qu'aucune des plages du champ d'en-tête Range de la requête (section 3.1) ne recoupe l'étendue courante de la ressource sélectionnée, ou que l'ensemble des plages demandées a été rejeté en raison de plages invalides ou d'une demande excessive de plages petites ou se chevauchant.

Pour les plages d'octets, l'absence de recoupement de l'étendue courante signifie que les first-byte-pos de toutes les valeurs byte-range-spec étaient supérieures à la longueur courante de la représentation sélectionnée. Lorsque ce code d'état est généré en réponse à une requête de plage d'octets, l'expéditeur devrait générer un champ d'en-tête Content-Range spécifiant la longueur courante de la représentation sélectionnée (section 4.2) (SHOULD).

Par exemple :

HTTP/1.1 416 Range Not Satisfiable
Date: Fri, 20 Jan 2012 15:41:54 GMT
Content-Range: bytes */47022

Note : les serveurs étant libres d'ignorer Range, de nombreuses implémentations répondront simplement par la représentation sélectionnée entière dans une réponse 200 (OK). C'est en partie parce que la plupart des clients sont prêts à recevoir une 200 (OK) pour mener la tâche à bien (quoique moins efficacement), et en partie parce que les clients peuvent ne pas cesser d'émettre une requête partielle invalide avant d'avoir reçu une représentation complète. Ainsi, les clients ne peuvent pas compter sur la réception d'une réponse 416 (Range Not Satisfiable), même lorsqu'elle est la plus appropriée.