Cos'e HTTP 206 Partial Content
Il codice HTTP 206 Partial Content indica che il server ha soddisfatto correttamente una richiesta di tipo range da parte del client. Invece di inviare l'intera risorsa, il server restituisce solo la porzione di byte richiesta. E il fondamento dello streaming video, del resume dei download e di numerosi protocolli media moderni. Senza il 206, non sarebbe possibile spostare il cursore di un video lungo, riprendere un download interrotto o caricare progressivamente file di grandi dimensioni.
Header Range e Content-Range
La meccanica si basa su due header chiave:
- Range (request): il client specifica il segmento desiderato, es.
Range: bytes=0-1023. - Content-Range (response): il server conferma il range servito, es.
Content-Range: bytes 0-1023/5000000.
L'unita standard e bytes, ma la specifica permette altre unita custom (raramente usate). Il formato di Content-Range e sempre unit start-end/total dove total puo essere asterisco se sconosciuto.
Esempio completo
GET /video.mp4 HTTP/1.1
Host: cdn.gtechgroup.it
Range: bytes=500000-999999
User-Agent: Mozilla/5.0
HTTP/1.1 206 Partial Content
Content-Type: video/mp4
Content-Range: bytes 500000-999999/12345678
Content-Length: 500000
Accept-Ranges: bytes
Cache-Control: public, max-age=31536000
ETag: "v1234"
Video streaming progressivo
Quando guardi un video in HTML5, il tag <video> invia richieste range successive man mano che lo utente avanza la timeline. Senza 206, ogni seek (spostamento manuale del cursore di riproduzione) ricaricherebbe il file intero, sprecando banda e generando attese. Grazie al 206, il player scarica solo i segmenti necessari, ottimizzando banda e tempo di buffering. Netflix, YouTube, Vimeo e tutti i servizi di streaming si basano su questo meccanismo, spesso combinato con segmentazione DASH/HLS per ulteriore granularita.
Resume dei download
Tool come wget, curl -C -, aria2 e i download manager (JDownloader, Internet Download Manager) sfruttano il 206 per riprendere un download interrotto. Il client salva quanti byte ha già ricevuto e chiede al server Range: bytes=N- per scaricare solo il resto. Funzione vitale su connessioni instabili o per file molto grandi (ISO di sistemi operativi, dataset scientifici, archivi giganti). Il server deve garantire che il file non sia cambiato (ETag o Last-Modified) per evitare di assemblare pezzi di versioni diverse.
Multipart byteranges
Il client puo richiedere più range nella stessa richiesta:
Range: bytes=0-499,1000-1499,5000-5999
Il server risponde con Content-Type: multipart/byteranges e ogni segmento e separato da boundary, come negli upload multipart. Esempio:
HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES
--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 0-499/8000
...500 byte di dati...
--THIS_STRING_SEPARATES
Content-Type: application/pdf
Content-Range: bytes 1000-1499/8000
...500 byte di dati...
--THIS_STRING_SEPARATES--
Accept-Ranges
Per dichiarare il supporto al protocollo, il server include nelle risposte 200:
Accept-Ranges: bytes
Se invece il server non supporta range, restituisce Accept-Ranges: none oppure ignora completamente l'header. I client decidono in base a questo se proporre l'opzione "resume" o disabilitare seeking nei player.
Errori comuni: 416 Range Not Satisfiable
Se il client chiede un range fuori dai limiti del file (es. byte 99999999 su un file da 1MB), il server deve rispondere con 416 e includere Content-Range: bytes */dimensione. Mai 206 con dati sbagliati: i player si bloccherebbero in loop di errore. Anche range invertiti (start > end) o sintassi malformata generano 416.
Caching e CDN
Le risposte 206 sono cacheable, ma richiedono CDN che supportino range caching. Cloudflare, CloudFront, Fastly e Akamai lo fanno nativamente. Header ETag e If-Range assicurano che il client non assembli pezzi di versioni diverse della stessa risorsa. L'header If-Range e particolarmente elegante: "scarica questo range solo se la risorsa e ancora la versione X; se e cambiata, mandami l'intero file da capo (200) così posso riprovare".
Implementazione server
Nginx supporta le range request out-of-the-box per file statici. Apache idem. Per applicazioni dinamiche (PHP, Node, Python) occorre implementare manualmente la logica: leggere l'header Range, calcolare offset, settare Content-Range e usare fseek() o stream slicing. Pseudo-codice PHP:
$file = '/path/to/video.mp4';
$size = filesize($file);
list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
list($start, $end) = explode('-', $range, 2);
$start = intval($start);
$end = $end ? intval($end) : $size - 1;
header('HTTP/1.1 206 Partial Content');
header("Content-Range: bytes $start-$end/$size");
header('Content-Length: ' . ($end - $start + 1));
$fp = fopen($file, 'rb');
fseek($fp, $start);
echo fread($fp, $end - $start + 1);
fclose($fp);
Best practice
Sempre supportare 206 per asset binari grandi (video, audio, archivi). Includere ETag stabile per consentire If-Range. Validare range input per prevenire path traversal o overflow. Monitorare la percentuale di 206 vs 200 nei log: una percentuale alta di 206 indica streaming intensivo, utile per planning capacita banda.
Best practice
Sempre supportare 206 per asset binari grandi (video, audio, archivi). Includere ETag stabile per consentire If-Range. Validare range input per prevenire path traversal o overflow. Monitorare la percentuale di 206 vs 200 nei log: una percentuale alta di 206 indica streaming intensivo, utile per planning capacita banda. Sempre includere Accept-Ranges: bytes nelle risposte 200 di asset che supportano range, così i client sanno di poter chiedere range nelle richieste successive senza tentativo cieco.
206 nei mobile player
I player video mobile (AVPlayer iOS, ExoPlayer Android) usano range request intensivamente per seeking. Su rete cellulare con latenza alta, il numero di range request consecutive impatta UX. Buffer locale più grande riduce il numero di fetch. Range più grossi riducono overhead per fetch ma aumentano latenza di seek. Equilibrio importante.
Origin shielding
Per asset distribuiti via CDN multipli, origin shielding (un'edge designato fa caching primario, altri edge fanno fetch da esso) e efficace per asset con molte range request. Si evita amplificazione verso origin. Cloudflare Argo, Fastly Shielding sono esempi.
Hai bisogno di aiuto?
Se il tuo sito mostra errori HTTP, il team di G Tech Group puo aiutarti. Contattaci tramite il modulo di contatto.