RFC 7233 - HTTP/1.1: Requêtes de plage (Range Requests)
- Statut: Proposed Standard
- Publié: June 2014
- Stream: IETF
- Remplace: RFC2616
- Remplacé par: RFC9110
- Errata: Pas d'errata
Informations sur le document
- Numéro RFC: 7233
- Titre: Hypertext Transfer Protocol (HTTP/1.1): Range Requests
- Titre (Français): Protocole de transfert hypertexte (HTTP/1.1): Requêtes de plage
- Date de publication: Juin 2014
- Auteurs: R. Fielding (Adobe), Y. Lafon (W3C), J. Reschke (greenbytes)
- Remplace le document: RFC 2616
- Statut: Standards Track (Piste des normes)
Résumé
Les requêtes de plage permettent aux clients HTTP de demander un ou plusieurs sous-ensembles d'une ressource, plutôt que la représentation complète. Ceci est crucial pour la reprise de téléchargements interrompus, les téléchargements multi-threads et la lecture en continu de médias.
Concepts fondamentaux
Qu'est-ce qu'une requête de plage?
Les requêtes de plage permettent au client de dire: "Je n'ai besoin que d'une partie de cette ressource".
Ressource complète: [================100MB================]
↓
Requête de plage: [====10MB====]
Principaux cas d'utilisation
- Reprise de téléchargement: Continuer après une interruption
- Téléchargement segmenté: Téléchargements parallèles multi-threads
- Navigation vidéo: Sauter à une position spécifique de la vidéo
- Aperçu PDF: Télécharger uniquement les premières pages
- Optimisation de fichiers volumineux: Charger le contenu à la demande
Champ d'en-tête Range
Syntaxe de base
Range: bytes=<start>-<end>
Exemples
Plage unique:
GET /video.mp4 HTTP/1.1
Host: example.com
Range: bytes=0-1023
Demande les premiers 1024 octets.
Plages multiples:
GET /document.pdf HTTP/1.1
Host: example.com
Range: bytes=0-499, 1000-1499, 5000-5999
Demande trois plages non contiguës.
Plages ouvertes:
Range: bytes=1000- # De 1000 à la fin
Range: bytes=-500 # Les 500 derniers octets
Range: bytes=0- # Du début à la fin (équivalent à une requête complète)
En-tête Accept-Ranges
Le serveur utilise cet en-tête pour indiquer si les requêtes de plage sont prises en charge.
Requêtes de plage prises en charge:
HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 10485760
Requêtes de plage non prises en charge:
HTTP/1.1 200 OK
Accept-Ranges: none
Content-Length: 10485760
Réponse 206 Partial Content
Les requêtes de plage réussies renvoient le code de statut 206.
Réponse de plage unique
GET /video.mp4 HTTP/1.1
Range: bytes=1000-1999
HTTP/1.1 206 Partial Content
Content-Range: bytes 1000-1999/10485760
Content-Length: 1000
Content-Type: video/mp4
[1000 octets de données...]
En-tête Content-Range
Format:
Content-Range: bytes <start>-<end>/<total>
Exemple:
Content-Range: bytes 1000-1999/10485760
^^^^^ ^^^^^ ^^^^^^^^
Début Fin Taille totale
Réponse multi-plages
Utilise le type de média multipart/byteranges:
GET /file.txt HTTP/1.1
Range: bytes=0-50, 100-150
HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES
--THIS_STRING_SEPARATES
Content-Type: text/plain
Content-Range: bytes 0-50/1270
[Premiers 51 octets...]
--THIS_STRING_SEPARATES
Content-Type: text/plain
Content-Range: bytes 100-150/1270
[51 octets du milieu...]
--THIS_STRING_SEPARATES--
416 Range Not Satisfiable
Renvoyé lorsque la plage demandée est invalide.
GET /file.txt HTTP/1.1
Range: bytes=9999-10999
HTTP/1.1 416 Range Not Satisfiable
Content-Range: bytes */1234
Content-Length: 0
Causes courantes:
- Position de début dépasse la taille du fichier
- Position de début supérieure à la position de fin
- Erreur de format
Requête de plage conditionnelle If-Range
Combine les requêtes conditionnelles et les requêtes de plage pour s'assurer que la ressource n'a pas été modifiée.
GET /video.mp4 HTTP/1.1
Range: bytes=1000000-
If-Range: "etag-abc123"
Ressource inchangée (ETag correspond):
HTTP/1.1 206 Partial Content
ETag: "etag-abc123"
Content-Range: bytes 1000000-10485759/10485760
Ressource modifiée (ETag ne correspond pas):
HTTP/1.1 200 OK
ETag: "etag-xyz789"
Content-Length: 10485760
[Renvoyer la nouvelle ressource complète...]
Scénarios d'application pratiques
Scénario 1: Reprise de téléchargement
Premier téléchargement (interrompu):
→ GET /large-file.zip HTTP/1.1
← HTTP/1.1 200 OK
Content-Length: 104857600
ETag: "file-v1"
[Interrompu à 50MB...]
Reprise du téléchargement:
→ GET /large-file.zip HTTP/1.1
Range: bytes=52428800-
If-Range: "file-v1"
← HTTP/1.1 206 Partial Content
Content-Range: bytes 52428800-104857599/104857600
[Continuer à télécharger les 50MB restants...]
Scénario 2: Lecture en continu de vidéo
L'utilisateur clique sur la barre de progression (saute à 50%):
→ GET /movie.mp4 HTTP/1.1
Range: bytes=524288000-524877999
← HTTP/1.1 206 Partial Content
Content-Range: bytes 524288000-524877999/1048576000
Content-Type: video/mp4
[Renvoyer 590KB de données vidéo...]
Scénario 3: Téléchargement multi-thread
Thread 1:
→ Range: bytes=0-34999999
Thread 2:
→ Range: bytes=35000000-69999999
Thread 3:
→ Range: bytes=70000000-104857599
[Trois threads téléchargent en parallèle, puis fusionnent]
Scénario 4: Chargement partiel de PDF
Charger uniquement la table des matières et les 10 premières pages du PDF:
→ GET /document.pdf HTTP/1.1
Range: bytes=0-102400
← HTTP/1.1 206 Partial Content
Content-Range: bytes 0-102400/10485760
[Renvoyer l'en-tête du fichier et les 10 premières pages...]
En-tête de réponse Content-Range
Syntaxe complète
Content-Range: <unit> <range-start>-<range-end>/<size>
Content-Range: <unit> <range-start>-<range-end>/*
Content-Range: <unit> */<size>
Exemples
Taille totale connue:
Content-Range: bytes 200-1000/5000
Taille totale inconnue:
Content-Range: bytes 200-1000/*
Non satisfaisable (réponse 416):
Content-Range: bytes */5000
Meilleures pratiques pour les requêtes de plage
Côté serveur
-
Déclarer le support:
Accept-Ranges: bytes -
Fournir ETag ou Last-Modified:
ETag: "abc123"
Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT -
Valider correctement les plages:
- Vérifier si la plage est dans la plage valide
- Rejeter les plages invalides (renvoyer 416)
-
Optimiser les grandes requêtes de plage:
- Envisager de limiter le nombre de plages par requête
- Éviter les plages trop petites qui entraînent une surcharge excessive
Côté client
-
Vérifier Accept-Ranges:
if (response.headers.get('Accept-Ranges') === 'bytes') {
// Requêtes de plage prises en charge
} -
Utiliser If-Range pour assurer la cohérence:
Range: bytes=1000-
If-Range: "etag-value" -
Gérer différentes réponses:
- 200: Le serveur ignore Range, renvoie la ressource complète
- 206: Réponse partielle réussie
- 416: Plage invalide, peut nécessiter une nouvelle demande
-
Segmentation raisonnable:
Pas trop petit: bytes=0-1, bytes=1-2, bytes=2-3 ✗
Taille raisonnable: bytes=0-1048575 (1MB) ✓
Unités de plage
HTTP/1.1 prend principalement en charge l'unité bytes, mais la spécification permet des extensions:
Accept-Ranges: bytes, frames, segments
L'unité bytes est la plus couramment utilisée et standardisée.
Considérations de performance
Avantages
- Économiser la bande passante: Transférer uniquement la partie nécessaire
- Améliorer l'expérience: Prendre en charge la reprise de téléchargement et le saut rapide
- Téléchargement parallèle: Augmenter la vitesse de téléchargement
Problèmes potentiels
- Complexité du cache: La mise en cache des réponses partielles est plus complexe
- Surcharge du serveur: Nécessite la prise en charge de l'accès aléatoire
- Fragmentation de plage: Trop de petites requêtes de plage peuvent réduire l'efficacité
Recommandations d'optimisation
Tailles de plage recommandées:
- Streaming vidéo: 1-5MB
- Téléchargements de fichiers: 5-10MB
- Navigation de documents: 100KB-1MB
Considérations de sécurité
Attaques par déni de service
Les clients malveillants peuvent envoyer de nombreuses petites requêtes de plage:
Range: bytes=0-0, 1-1, 2-2, 3-3, ... (des milliers de plages)
Mesures défensives:
- Limiter le nombre de plages par requête (par exemple, maximum 5)
- Limiter la taille totale de la réponse
- Implémenter une limitation de débit
Fuite d'informations
Les requêtes de plage peuvent être utilisées pour deviner la taille ou la structure du fichier:
Range: bytes=0-0
→ Content-Range: bytes 0-0/[taille du fichier]
Pour les fichiers sensibles, envisagez de désactiver les requêtes de plage ou d'exiger une authentification.
Interaction avec d'autres fonctionnalités HTTP
Interaction avec le cache
Les requêtes de plage augmentent la complexité de la mise en cache:
Vary: Range
Cache-Control: private
Interaction avec la compression
Attention: Les requêtes de plage ne sont généralement pas utilisées avec Content-Encoding: gzip, car les décalages compressés sont imprévisibles.
Recommandation: Pour les fichiers volumineux nécessitant des requêtes de plage, n'utilisez pas la compression de transfert.
Interaction avec les redirections
Si une requête de plage rencontre une redirection:
GET /old-video.mp4 HTTP/1.1
Range: bytes=1000-1999
HTTP/1.1 302 Found
Location: /new-video.mp4
Le client doit renvoyer la requête de plage à la nouvelle URL.
Résumé
Les requêtes de plage sont une fonctionnalité clé de HTTP/1.1:
- Précision: Implémentation précise de la sémantique des plages d'octets
- Clarté: Expression claire des besoins en contenu partiel
- Élégance: Support élégant des fonctionnalités avancées des applications Web modernes
Grâce aux requêtes de plage, l'expérience utilisateur lors du transfert de fichiers volumineux et de la lecture de médias peut être considérablement améliorée.
RFCs associés:
- RFC 7230: HTTP/1.1 Syntaxe et routage des messages
- RFC 7231: HTTP/1.1 Sémantique et contenu
- RFC 7232: HTTP/1.1 Requêtes conditionnelles