Richieste HTTP range

Le richieste HTTP range permettono di mandare una sola porzione di un messaggio HTTP da un server a un client invece del messaggio intero. Le richieste parziali sono utili per file di grandi dimensioni o per mettere un download in pausa e riprenderlo successivamente.

Controllare se un server supporta richieste parziali

Se l'header Accept-Ranges è presente nelle risposte HTTP (e il suo valore non è "none"), il server supporta richieste HTTP range. E' possibile controllarlo creando una richiesta HEAD con cURL, ad esempio.

curl -I http://i.imgur.com/z4d4kWk.jpg

HTTP/1.1 200 OK
...
Accept-Ranges: bytes
Content-Length: 146515

In questa risposta, Accept-Ranges: bytes indica che i bytes possono essere usati come unità base per definire un range (intervallo). Qui anche l'header Content-Length è utile perché indica la dimensione dell'intero file contenente l'immagine.

Se il sito omette l'header Accept-Ranges, probabilmente non supporta richieste parziali. Alcuni siti mandano esplicitamente "none" come valore, indicando che non supportano la funzionalità. In questo caso, i download managers di alcune app disabiliteranno i loro pulsanti di pausa.

curl -I https://www.youtube.com/watch?v=EwTZ2xpQwpA

HTTP/1.1 200 OK
...
Accept-Ranges: none

Richiedere un range specifico

Se il server supporta richieste range, è possibile effettuare questa richiesta tramite l'header Range, che indica la parte o le parti di un documento con le quali il server dovrà rispondere.

Range formato da una singola parte

Possiamo richiedere un singolo range da una risorsa. Possiamo fare una richiesta di prova tramite cURL. L'opzione "-H" appenderà una riga all'header alla richiesta, in questo caso l'header Range che richiede i primi 1024 bytes.

curl http://i.imgur.com/z4d4kWk.jpg -i -H "Range: bytes=0-1023"

La richiesta effettuata è la seguente:

GET /z4d4kWk.jpg HTTP/1.1
Host: i.imgur.com
Range: bytes=0-1023

Il server risponde con lo stato 206 Partial Content:

HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/146515
Content-Length: 1024
...
(binary content)

L'header Content-Length ora indica la dimensione dell'intervallo richiesto (non la dimensione totale dell'immagine). L'header Content-Range nella risposta indica la posizione del messaggio parziale all'interno del file.

Range formato da più parti

L'header Range permette anche di ottenere più di un intervallo alla volta. Gli intervalli sono separati da una virgola.

curl http://www.example.com -i -H "Range: bytes=0-50, 100-150"

Il server risponde con lo stato 206 Partial Content e l'header Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5, indicando che un range multiparte segue. Ogni parte contiene il proprio campo Content-Type and Content-Range.

HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5
Content-Length: 282

--3d6b6a416f9b5
Content-Type: text/html
Content-Range: bytes 0-50/1270

<!doctype html>
<html>
<head>
    <title>Example Do
--3d6b6a416f9b5
Content-Type: text/html
Content-Range: bytes 100-150/1270

eta http-equiv="Content-type" content="text/html; c
--3d6b6a416f9b5--

Richieste di range condizionali

Quando la richiesta è in pausa e viene successivamente ripresa, è necessario garantire che la risorsa remota non sia stata modificata da quando l'ultimo frammento è stato ricevuto.

L'header della richiesta HTTP If-Range rende una richiesta range condizionale: se la condizione è verificata, la richiesta verrà effettuata e il server restituirà lo stato 206 Partial Content con il corpo appropriato. Se la condizione non è verificata, il server restituirà l'intera risorsa con status 200 OK. Questo header può essere usato in combinazione con un validatore Last-Modified oppure un ETag, ma non entrambi.

If-Range: Wed, 21 Oct 2015 07:28:00 GMT 

Risposte alle richieste parziali

Quando si lavora con richieste range, esistono tre stati rilevanti:

  • In caso di richiesta riuscita, il server restituisce lo stato 206 Partial Content.
  • In caso di una richiesta out of bounds (i valori di range si sovrappongono), il server risponde con lo stato 416 Requested Range Not Satisfiable.
  • Se la richiesta range non è supportata verrà restituito lo stato 200 OK.

Confronto con Transfer-Encoding frammentato

L'header Transfer-Encoding permette la codifica a frammenti, che è utile quando grandi quantità di dati sono mandati al client e la dimensione totale della risposta non è conosciuta fino a quando la richiesta è stata processata. Il server manda dati al client immediatamente senza fare buffering della risposta o determinare la lunghezza esatta, migliorando la latenza. Richieste range e chunking sono compatibili e possono essere usate contemporaneamente.

Vedi anche