3. Requêtes de plage
3.1 Range
Le champ d'en-tête "Range" d'une requête GET modifie la sémantique de la méthode afin de demander le transfert d'une ou de plusieurs sous-plages des données de la représentation sélectionnée, plutôt que la totalité de ces données.
Range = byte-ranges-specifier / other-ranges-specifier
other-ranges-specifier = other-range-unit "=" other-range-set
other-range-set = 1*VCHAR
Un serveur peut ignorer le champ d'en-tête Range (MAY). Toutefois, les serveurs d'origine et les caches intermédiaires devraient prendre en charge les plages d'octets lorsque cela est possible, car Range permet une reprise efficace après un transfert partiellement échoué et l'extraction 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 (MUST).
Un serveur d'origine doit ignorer un champ d'en-tête Range qui contient une unité de plage qu'il ne comprend pas (MUST). Un mandataire peut abandonner un champ d'en-tête Range qui contient une unité de plage qu'il ne comprend pas (MAY).
Un serveur qui prend en charge les requêtes de plage peut ignorer ou rejeter un champ d'en-tête Range constitué de plus de deux plages qui se chevauchent, ou d'un ensemble de nombreuses petites plages qui ne sont pas listées par ordre croissant, car ces deux cas indiquent soit un client défectueux, soit une attaque par déni de service délibérée (section 6.1) (MAY). Un client devrait éviter de demander plusieurs plages dont le traitement et le transfert sont intrinsèquement moins efficaces qu'une plage unique englobant les mêmes données (SHOULD NOT).
Un client qui demande plusieurs plages devrait les lister par ordre croissant (l'ordre dans lequel elles seraient normalement reçues dans une représentation complète), sauf s'il a un besoin particulier d'obtenir plus tôt une partie ultérieure (SHOULD). Par exemple, un agent utilisateur traitant une grande représentation avec un catalogue interne de parties peut avoir besoin de demander d'abord les parties ultérieures, en particulier si la représentation est constituée de pages stockées dans l'ordre inverse et que l'agent utilisateur souhaite transférer une page à la fois.
Le champ d'en-tête Range est évalué après les champs d'en-tête de précondition définis dans [RFC7232], et uniquement si le résultat en l'absence du champ d'en-tête Range serait une réponse 200 (OK). Autrement dit, Range est ignoré lorsqu'un GET conditionnel aboutirait à une réponse 304 (Not Modified).
Le champ d'en-tête If-Range (section 3.2) peut être utilisé comme précondition à l'application du champ d'en-tête Range.
Si toutes les préconditions sont vraies, si le serveur prend en charge le champ d'en-tête Range pour la ressource cible et si la ou les plages spécifiées sont valides et satisfaisables (au sens de la section 2.1), le serveur devrait envoyer une réponse 206 (Partial Content) dont la charge utile contient une ou plusieurs représentations partielles correspondant aux plages satisfaisables demandées, comme défini à la section 4 (SHOULD).
Si toutes les préconditions sont vraies, si le serveur prend en charge le champ d'en-tête Range pour la ressource cible et si la ou les plages spécifiées sont invalides ou non satisfaisables, le serveur devrait envoyer une réponse 416 (Range Not Satisfiable) (SHOULD).
3.2 If-Range
Si un client possède une copie partielle d'une représentation et souhaite obtenir une copie à jour de la représentation entière, il peut utiliser le champ d'en-tête Range avec un GET conditionnel (au moyen de If-Unmodified-Since, de If-Match, ou des deux). Toutefois, si la précondition échoue parce que la représentation a été modifiée, le client doit alors effectuer une seconde requête pour obtenir la représentation courante entière.
Le champ d'en-tête "If-Range" permet à un client de « court-circuiter » cette seconde requête. De manière informelle, sa signification est la suivante : si la représentation est inchangée, envoyez-moi la ou les parties que je demande dans Range ; sinon, envoyez-moi la représentation entière.
If-Range = entity-tag / HTTP-date
Un client ne doit pas générer de champ d'en-tête If-Range dans une requête qui ne contient pas de champ d'en-tête Range (MUST NOT). Un serveur doit ignorer un champ d'en-tête If-Range reçu dans une requête qui ne contient pas de champ d'en-tête Range (MUST). Un serveur d'origine doit ignorer un champ d'en-tête If-Range reçu dans une requête portant sur une ressource cible qui ne prend pas en charge les requêtes de plage (MUST).
Un client ne doit pas générer de champ d'en-tête If-Range contenant une balise d'entité (entity-tag) marquée comme faible (MUST NOT). Un client ne doit pas générer de champ d'en-tête If-Range contenant une date HTTP, sauf si le client ne possède aucune balise d'entité pour la représentation correspondante et si cette date est un validateur fort au sens défini à la section 2.2.2 de [RFC7232] (MUST NOT).
Un serveur qui évalue une précondition If-Range doit utiliser la fonction de comparaison forte pour comparer les balises d'entité (section 2.3.2 de [RFC7232]) (MUST) et doit évaluer la condition comme fausse si une date HTTP est fournie comme validateur et que cette date n'est pas un validateur fort au sens défini à la section 2.2.2 de [RFC7232] (MUST). Une balise d'entité valide se distingue d'une date HTTP valide en examinant si les deux premiers caractères sont un DQUOTE.
Si le validateur fourni dans le champ d'en-tête If-Range correspond au validateur courant de la représentation sélectionnée de la ressource cible, le serveur devrait traiter le champ d'en-tête Range comme demandé (SHOULD). Si le validateur ne correspond pas, le serveur doit ignorer le champ d'en-tête Range (MUST). Notez que cette comparaison par correspondance exacte, y compris lorsque le validateur est une date HTTP, diffère de la comparaison « antérieure ou égale » utilisée lors de l'évaluation d'une condition If-Unmodified-Since.