Aller au contenu principal

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

  1. Reprise de téléchargement: Continuer après une interruption
  2. Téléchargement segmenté: Téléchargements parallèles multi-threads
  3. Navigation vidéo: Sauter à une position spécifique de la vidéo
  4. Aperçu PDF: Télécharger uniquement les premières pages
  5. 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

  1. Déclarer le support:

    Accept-Ranges: bytes
  2. Fournir ETag ou Last-Modified:

    ETag: "abc123"
    Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
  3. Valider correctement les plages:

    • Vérifier si la plage est dans la plage valide
    • Rejeter les plages invalides (renvoyer 416)
  4. 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

  1. Vérifier Accept-Ranges:

    if (response.headers.get('Accept-Ranges') === 'bytes') {
    // Requêtes de plage prises en charge
    }
  2. Utiliser If-Range pour assurer la cohérence:

    Range: bytes=1000-
    If-Range: "etag-value"
  3. 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
  4. 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

Retour à la documentation HTTP/1.1