1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
---
title: Richieste HTTP range
slug: Web/HTTP/Range_requests
translation_of: Web/HTTP/Range_requests
original_slug: Web/HTTP/Richieste_range
---
<div>{{HTTPSidebar}}</div>
<p class="summary">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.</p>
<h2 id="Controllare_se_un_server_supporta_richieste_parziali">Controllare se un server supporta richieste parziali</h2>
<p>Se l'header {{HTTPHeader("Accept-Ranges")}} è presente nelle risposte HTTP (e il suo valore non è "<code>none</code>"), il server supporta richieste HTTP range. E' possibile controllarlo creando una richiesta {{HTTPMethod("HEAD")}} con cURL, ad esempio.</p>
<pre>curl -I http://i.imgur.com/z4d4kWk.jpg
HTTP/1.1 200 OK
...
Accept-Ranges: bytes
Content-Length: 146515
</pre>
<p>In questa risposta, <code>Accept-Ranges: bytes</code> indica che i bytes possono essere usati come unità base per definire un range (intervallo). Qui anche l'header {{HTTPHeader("Content-Length")}} è utile perché indica la dimensione dell'intero file contenente l'immagine.</p>
<p>Se il sito omette l'header <code>Accept-Ranges</code>, probabilmente non supporta richieste parziali. Alcuni siti mandano esplicitamente "<code>none</code>" come valore, indicando che non supportano la funzionalità. In questo caso, i download managers di alcune app disabiliteranno i loro pulsanti di pausa.</p>
<pre>curl -I https://www.youtube.com/watch?v=EwTZ2xpQwpA
HTTP/1.1 200 OK
...
Accept-Ranges: none
</pre>
<h2 id="Richiedere_un_range_specifico">Richiedere un range specifico</h2>
<p>Se il server supporta richieste range, è possibile effettuare questa richiesta tramite l'header {{HTTPHeader("Range")}}, che indica la parte o le parti di un documento con le quali il server dovrà rispondere.</p>
<h3 id="Range_formato_da_una_singola_parte">Range formato da una singola parte</h3>
<p>Possiamo richiedere un singolo range da una risorsa. Possiamo fare una richiesta di prova tramite cURL. L'opzione "<code>-H</code>" appenderà una riga all'header alla richiesta, in questo caso l'header <code>Range</code> che richiede i primi 1024 bytes.</p>
<pre>curl http://i.imgur.com/z4d4kWk.jpg -i -H "Range: bytes=0-1023"</pre>
<p>La richiesta effettuata è la seguente:</p>
<pre>GET /z4d4kWk.jpg HTTP/1.1
Host: i.imgur.com
Range: bytes=0-1023</pre>
<p>Il server risponde con lo stato {{HTTPStatus("206")}} <code>Partial Content</code>:</p>
<pre>HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/146515
Content-Length: 1024
...
(binary content)
</pre>
<p>L'header {{HTTPHeader("Content-Length")}} ora indica la dimensione dell'intervallo richiesto (non la dimensione totale dell'immagine). L'header {{HTTPHeader("Content-Range")}} nella risposta indica la posizione del messaggio parziale all'interno del file.</p>
<h3 id="Range_formato_da_più_parti">Range formato da più parti</h3>
<p>L'header {{HTTPHeader("Range")}} permette anche di ottenere più di un intervallo alla volta. Gli intervalli sono separati da una virgola.</p>
<pre>curl http://www.example.com -i -H "Range: bytes=0-50, 100-150"</pre>
<p>Il server risponde con lo stato {{HTTPStatus("206")}} <code>Partial Content</code> e l'header {{HTTPHeader("Content-Type")}}<code>: multipart/byteranges; boundary=3d6b6a416f9b5</code>, indicando che un range multiparte segue. Ogni parte contiene il proprio campo <code>Content-Type</code> and <code>Content-Range</code>.</p>
<pre>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--</pre>
<h3 id="Richieste_di_range_condizionali">Richieste di range condizionali</h3>
<p>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.</p>
<p>L'header della richiesta HTTP {{HTTPHeader("If-Range")}} rende una richiesta range condizionale: se la condizione è verificata, la richiesta verrà effettuata e il server restituirà lo stato {{HTTPStatus("206")}} <code>Partial Content</code> con il corpo appropriato. Se la condizione non è verificata, il server restituirà l'intera risorsa con status {{HTTPStatus("200")}} <code>OK</code>. Questo header può essere usato in combinazione con un validatore {{HTTPHeader("Last-Modified")}} oppure un {{HTTPHeader("ETag")}}, ma non entrambi.</p>
<pre>If-Range: Wed, 21 Oct 2015 07:28:00 GMT </pre>
<h2 id="Risposte_alle_richieste_parziali">Risposte alle richieste parziali</h2>
<p>Quando si lavora con richieste range, esistono tre stati rilevanti:</p>
<ul>
<li>In caso di richiesta riuscita, il server restituisce lo stato {{HTTPStatus("206")}} <code>Partial Content</code>.</li>
<li>In caso di una richiesta out of bounds (i valori di range si sovrappongono), il server risponde con lo stato {{HTTPStatus("416")}} <code>Requested Range Not Satisfiable</code>.</li>
<li>Se la richiesta range non è supportata verrà restituito lo stato {{HTTPStatus("200")}} <code>OK</code>.</li>
</ul>
<h2 id="Confronto_con_Transfer-Encoding_frammentato">Confronto con <code>Transfer-Encoding</code> frammentato</h2>
<p>L'header {{HTTPHeader("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.</p>
<h2 id="Vedi_anche">Vedi anche</h2>
<ul>
<li>Codici di stato: {{HTTPStatus("200")}}, {{HTTPStatus("206")}}, {{HTTPStatus("416")}}.</li>
<li>Headers: {{HTTPHeader("Accept-Ranges")}}, {{HTTPHeader("Range")}}, {{HTTPHeader("Content-Range")}}, {{HTTPHeader("If-Range")}}, {{HTTPHeader("Transfer-Encoding")}}.</li>
<li><a href="https://blogs.msdn.microsoft.com/ieinternals/2011/06/03/download-resumption-in-internet-explorer/">Riprendere i download in Internet Explorer</a></li>
</ul>
|