Подтвердить что ты не робот

Как возобновить прерванную загрузку - часть 2

Это продолжение моего предыдущего вопроса, который я опубликовал, когда я не был зарегистрированным пользователем. Как обновить, я пытаюсь возобновить загрузку большого файла с моего Yahoo! сервер веб-сайта, когда загрузка прерывается. Ранее я думал, что прерывание было вызвано 100-секундным лимитом тайм-аута (потому что Yahoo! применяет это ограничение по пользовательским письменным сценариям). Однако, когда я измерял время прерываний загрузки, я видел, что время прерывания сильно варьируется (иногда загрузка выполняется без прерывания менее 100 секунд, а иногда и до семи минут). Поэтому я не знаю причины таймаутов, и я просто пытаюсь их обойти.

Я попробовал предложение naikus (спасибо) и, согласно дампу полей заголовка http, кажется, что мой Yahoo! сервер веб-сайта распознает свойство "range", которое должно позволить загрузке возобновиться со смещением прерывания. К сожалению, хотя диапазон байтов отображается правильно в заголовке http в возобновленных соединениях, передаваемый контент всегда перезапускается в начале файла. (Мой тестовый файл представляет собой массив из 50 000 4-байтовых целых чисел, который увеличивается с нуля до 0. Мой загруженный файл всегда начинает пересчитывать в 0 при каждом смещении, при котором произошло прерывание загрузки.)

Есть ли еще один запрос свойства http-соединения, который я должен сделать, чтобы получить Yahoo! сервер, чтобы фактически перейти к смещению файла, указанному в диапазоне байтов заголовка? Здесь код и то, что он выгружает:

         // Setup connection.
         URL url = new URL(strUrl[0]);
         URLConnection connection = url.openConnection();
         downloaded = Integer.parseInt(strUrl[3]);
         if (downloaded > 0) {
             connection.setRequestProperty("Range", "bytes="+downloaded+"-");
             connection.connect();
             fileLength = mDownloadFileLength;
             Log.d("AsyncDownloadFile", 
                 "new download seek: " + downloaded +
                 "; lengthFile: " + fileLength);
         }
         else {
             connection.connect();
             downloaded = 0;
             fileLength = connection.getContentLength();
             mDownloadFileLength = fileLength;
         }
         Map<String, List<String>> map = connection.getHeaderFields();
         Log.d("AsyncDownloadFile", "header fields: " + map.toString());

         // Setup streams and buffers.
         input = new BufferedInputStream(url.openStream(), 8192);
         outFile = new RandomAccessFile(strUrl[1], "rw");
         if (downloaded > 0)  
             outFile.seek(downloaded);
         byte data[] = new byte[1024];

         // Download file.
         for (int count=0, i=0; (count=input.read(data, 0, 1024)) != -1; i++) { 
             outFile.write(data, 0, count);
             downloaded += count; 
             if (downloaded >= fileLength)
                 break;

             // Display progress.
             Log.d("AsyncDownloadFile", "bytes: " + downloaded);
             if ((i%10) == 0)
                 publishProgress((int)(downloaded*100/fileLength));
             if (mFlagDisableAsyncTask) {
                 downloaded = 0;
                 break;
             }
         }

         // Close streams.
         outFile.close();
         input.close();

dump:

@ 4:08:24  
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[2000000], age=[0], serve
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:08:33 GMT]}  
D/AsyncDownloadFile( 2372): bytes: 1024  
D/AsyncDownloadFile( 2372): bytes: 1033  
D/AsyncDownloadFile( 2372): bytes: 2057  
D/AsyncDownloadFile( 2372): bytes: 2493  
D/AsyncDownloadFile( 2372): bytes: 3517  
D/AsyncDownloadFile( 2372): bytes: 3953  

.
.
.

@ 4:13:25  
D/AsyncDownloadFile( 2372): bytes: 386473  
D/AsyncDownloadFile( 2372): bytes: 387497  
D/AsyncDownloadFile( 2372): bytes: 387933  
D/AsyncDownloadFile( 2372): new download seek: 387933; lengthFile: 2000000  
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[1612067], age=[0], serve
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:13:29 GMT], co
ntent-range=[bytes 387933-1999999/2000000]}  
D/AsyncDownloadFile( 2372): bytes: 388957  
D/AsyncDownloadFile( 2372): bytes: 389981  
D/AsyncDownloadFile( 2372): bytes: 390409  
D/AsyncDownloadFile( 2372): bytes: 391433  
D/AsyncDownloadFile( 2372): bytes: 391869  
D/AsyncDownloadFile( 2372): bytes: 392893  

.
.
.

@ 4:18:45  
D/AsyncDownloadFile( 2372): bytes: 775413  
D/AsyncDownloadFile( 2372): bytes: 775849  
D/AsyncDownloadFile( 2372): bytes: 776873  
D/AsyncDownloadFile( 2372): bytes: 777309  
D/AsyncDownloadFile( 2372): new download seek: 777309; lengthFile: 2000000  
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[1222691], age=[0], serve
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:18:54 GMT], co
ntent-range=[bytes 777309-1999999/2000000]}  
D/dalvikvm( 2372): GC_FOR_MALLOC freed 11019 objects / 470560 bytes in 155ms  
D/AsyncDownloadFile( 2372): bytes: 778333  
D/AsyncDownloadFile( 2372): bytes: 779357  
D/AsyncDownloadFile( 2372): bytes: 779790  
D/AsyncDownloadFile( 2372): bytes: 780814  
D/AsyncDownloadFile( 2372): bytes: 781250  
D/AsyncDownloadFile( 2372): bytes: 782274  

.
.
.

@ 4:23:45  
D/AsyncDownloadFile( 2372): bytes: 1163334  
D/AsyncDownloadFile( 2372): bytes: 1163770  
D/AsyncDownloadFile( 2372): bytes: 1164794  
D/AsyncDownloadFile( 2372): bytes: 1165230  
D/AsyncDownloadFile( 2372): new download seek: 1165230; lengthFile: 2000000  
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[834770], age=[0], server
=[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:23:47 GMT], con
tent-range=[bytes 1165230-1999999/2000000]}  
D/AsyncDownloadFile( 2372): bytes: 1166246  
D/AsyncDownloadFile( 2372): bytes: 1167270  
D/AsyncDownloadFile( 2372): bytes: 1167706  
D/AsyncDownloadFile( 2372): bytes: 1168730  
D/AsyncDownloadFile( 2372): bytes: 1169754  
D/AsyncDownloadFile( 2372): bytes: 1170778  

.
.
.

@ 4:30:25  
D/AsyncDownloadFile( 2372): bytes: 1551255  
D/AsyncDownloadFile( 2372): bytes: 1551691  
D/AsyncDownloadFile( 2372): bytes: 1552715  
D/AsyncDownloadFile( 2372): bytes: 1553151  
D/AsyncDownloadFile( 2372): new download seek: 1553151; lengthFile: 2000000  
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[446849], age=[0], server
=[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:30:44 GMT], con
tent-range=[bytes 1553151-1999999/2000000]}  
D/AsyncDownloadFile( 2372): bytes: 1554167  
D/AsyncDownloadFile( 2372): bytes: 1554184  
D/AsyncDownloadFile( 2372): bytes: 1555208  
D/AsyncDownloadFile( 2372): bytes: 1555644  
D/AsyncDownloadFile( 2372): bytes: 1556668  
D/AsyncDownloadFile( 2372): bytes: 1557104  

.
.
.

@ 4:37:10  
D/AsyncDownloadFile( 2372): bytes: 1939188  
D/AsyncDownloadFile( 2372): bytes: 1939624  
D/AsyncDownloadFile( 2372): bytes: 1940648  
D/AsyncDownloadFile( 2372): bytes: 1941084  
D/AsyncDownloadFile( 2372): new download seek: 1941084; lengthFile: 2000000  
D/dalvikvm( 2372): GC_FOR_MALLOC freed 13701 objects / 604600 bytes in 128ms
D/AsyncDownloadFile( 2372): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[58916], age=[0], server=
[YTS/1.17.13], accept-ranges=[bytes], date=[Fri, 06 Aug 2010 20:37:16 GMT], cont
ent-range=[bytes 1941084-1999999/2000000]}  
D/AsyncDownloadFile( 2372): bytes: 1942108  
D/AsyncDownloadFile( 2372): bytes: 1942117  
D/AsyncDownloadFile( 2372): bytes: 1943141  
D/AsyncDownloadFile( 2372): bytes: 1943577  
D/AsyncDownloadFile( 2372): bytes: 1944601  
D/AsyncDownloadFile( 2372): bytes: 1945037  

.
.
.

@ 4:38:30  
D/AsyncDownloadFile( 2372): bytes: 1993217  
D/AsyncDownloadFile( 2372): bytes: 1994241  
D/AsyncDownloadFile( 2372): bytes: 1994677  
D/AsyncDownloadFile( 2372): bytes: 1995701  
D/AsyncDownloadFile( 2372): bytes: 1996137  
D/AsyncDownloadFile( 2372): bytes: 1997161  
D/AsyncDownloadFile( 2372): bytes: 1997597  
D/AsyncDownloadFile( 2372): bytes: 1998621  
D/AsyncDownloadFile( 2372): bytes: 1999057  
D/onPostExecute( 2372): download: unsuccessful  

- - -  

После подсказки от BalusC (спасибо), я изменил настройку соединения, но Yahoo! сервер продолжает reset до начала файла на каждом прерывании. Здесь измененный код и результирующие дампы:

            // Setup connection.
            URL url = new URL(strUrl[0]);
            URLConnection connection = url.openConnection();
            downloaded = Integer.parseInt(strUrl[3]);
            if (downloaded == 0) {
                connection.connect();
                strLastModified = connection.getHeaderField("Last-Modified");
                fileLength = connection.getContentLength();
                mDownloadFileLength = fileLength;
            }
            else {
                connection.setRequestProperty("Range", "bytes=" + downloaded + "-");
                connection.setRequestProperty("If-Range", strLastModified);
                connection.connect();
                fileLength = mDownloadFileLength;
                Log.d("AsyncDownloadFile", 
                        "new download seek: " + downloaded +
                        "; lengthFile: " + fileLength);
            }
            map = connection.getHeaderFields();
            Log.d("AsyncDownloadFile", "header fields: " + map.toString());

dump:

@12:36:40 started  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.c
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTP
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA P
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-m
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[2000000], age=[0], serv
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:36:56 GMT]}  
D/AsyncDownloadFile(  413): bytes: 1024  
D/AsyncDownloadFile(  413): bytes: 2048  
D/AsyncDownloadFile(  413): bytes: 2476  
D/AsyncDownloadFile(  413): bytes: 3500  
D/AsyncDownloadFile(  413): bytes: 3936  

...

@12:39:20 interrupted  
D/AsyncDownloadFile(  413): bytes: 388068  
D/AsyncDownloadFile(  413): bytes: 389092  
D/AsyncDownloadFile(  413): bytes: 389376  
D/AsyncDownloadFile(  413): new download seek: 389376; lengthFile: 2000000  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[1610624], age=[0], serve
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:39:21 GMT], co
ntent-range=[bytes 389376-1999999/2000000]}  
D/AsyncDownloadFile(  413): bytes: 390400  
D/AsyncDownloadFile(  413): bytes: 390409  
D/AsyncDownloadFile(  413): bytes: 391433  
D/AsyncDownloadFile(  413): bytes: 391869  

...

@12:44:10 interrupted  
D/AsyncDownloadFile(  413): bytes: 775413  
D/AsyncDownloadFile(  413): bytes: 775849  
D/AsyncDownloadFile(  413): bytes: 776873  
D/AsyncDownloadFile(  413): bytes: 777309  
D/AsyncDownloadFile(  413): new download seek: 777309; lengthFile: 2000000  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[1222691], age=[0], serve
r=[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:44:20 GMT], co
ntent-range=[bytes 777309-1999999/2000000]}  
D/dalvikvm(  413): GC_FOR_MALLOC freed 10869 objects / 465664 bytes in 122ms  
D/AsyncDownloadFile(  413): bytes: 778333  
D/AsyncDownloadFile(  413): bytes: 778342  
D/AsyncDownloadFile(  413): bytes: 779366  
D/AsyncDownloadFile(  413): bytes: 779802  

...

@12:49:30 interrupted  
D/AsyncDownloadFile(  413): bytes: 1163782  
D/AsyncDownloadFile(  413): bytes: 1164806  
D/AsyncDownloadFile(  413): bytes: 1165242  
D/AsyncDownloadFile(  413): new download seek: 1165242; lengthFile: 2000000  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[834758], age=[0], server
=[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:49:43 GMT], con
tent-range=[bytes 1165242-1999999/2000000]}  
D/AsyncDownloadFile(  413): bytes: 1166266  
D/AsyncDownloadFile(  413): bytes: 1167290  
D/AsyncDownloadFile(  413): bytes: 1167718  
D/AsyncDownloadFile(  413): bytes: 1168742  

...

@12:55:30 interrupted  
D/AsyncDownloadFile(  413): bytes: 1552722  
D/AsyncDownloadFile(  413): bytes: 1553158  
D/AsyncDownloadFile(  413): bytes: 1554182  
D/AsyncDownloadFile(  413): bytes: 1554618  
D/AsyncDownloadFile(  413): new download seek: 1554618; lengthFile: 2000000  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[445382], age=[0], server
=[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:55:39 GMT], con
tent-range=[bytes 1554618-1999999/2000000]}  
D/AsyncDownloadFile(  413): bytes: 1555642  
D/AsyncDownloadFile(  413): bytes: 1556666  
D/AsyncDownloadFile(  413): bytes: 1557094  
D/AsyncDownloadFile(  413): bytes: 1558118  

...

@12:57:20 interrupted  
D/AsyncDownloadFile(  413): bytes: 1941834  
D/AsyncDownloadFile(  413): bytes: 1942858  
D/AsyncDownloadFile(  413): bytes: 1943882  
D/AsyncDownloadFile(  413): bytes: 1943994  
D/AsyncDownloadFile(  413): new download seek: 1943994; lengthFile: 2000000  
D/AsyncDownloadFile(  413): header fields: {p3p=[policyref="http://info.yahoo.co
m/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi
 OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA PO
L HEA PRE LOC GOV"], content-type=[application/zip], connection=[close], last-mo
dified=[Fri, 06 Aug 2010 14:47:50 GMT], content-length=[56006], age=[0], server=
[YTS/1.17.13], accept-ranges=[bytes], date=[Sat, 07 Aug 2010 04:57:15 GMT], cont
ent-range=[bytes 1943994-1999999/2000000]}  
D/dalvikvm(  413): GC_FOR_MALLOC freed 13617 objects / 602200 bytes in 165ms  
D/AsyncDownloadFile(  413): bytes: 1945018  
D/AsyncDownloadFile(  413): bytes: 1946042  
D/AsyncDownloadFile(  413): bytes: 1946470  
D/AsyncDownloadFile(  413): bytes: 1947494  

...

@12:58:10 finished  
D/AsyncDownloadFile(  413): bytes: 1996103  
D/AsyncDownloadFile(  413): bytes: 1997127  
D/AsyncDownloadFile(  413): bytes: 1997563  
D/AsyncDownloadFile(  413): bytes: 1998587  
D/AsyncDownloadFile(  413): bytes: 1999023  
D/onPostExecute(  413): downloaded: unsuccessful  
4b9b3361

Ответ 1

Чтобы возобновить загрузку, вам необходимо отправить не только заголовок запроса Range, но также If-Range, который должен содержать либо уникальный идентификатор файла, либо временную метку изменения файла.

Если сервер возвращает заголовок ответа ETag при первоначальной загрузке, вы должны использовать его в заголовке If-Range последующие запросы резюме. Или, если он возвращает заголовок ответа Last-Modified, тогда вы должны использовать его в заголовке запроса If-Range.

Глядя на ваши журналы, сервер отправил заголовок ответа Last-Modified. Поэтому вы должны отправить его обратно в заголовок If-Range запроса возобновления.

// Initial download.
String lastModified = connection.getHeaderField("Last-Modified");

// ...

// Resume download.
connection.setRequestProperty("If-Range", lastModified); 

Сервер будет использовать эту информацию, чтобы проверить, запрашиваете ли вы тот же файл.

Ответ 2

Кажется, что проблема вызывает

input = new BufferedInputStream(url.openStream(), 8192);

вместо

input = new BufferedInputStream(connection.getInputStream(), 8192);

url.openStream() вызывает другой вызов openConnection() БЕЗ свойства диапазона.

Ответ 3

Мне удалось реализовать загрузку http resume на моем клиентском приложении Java, трюк состоял в том, чтобы использовать заголовок запроса If-Range: original_ETag, как указано в принятом ответе. Вот полная информация об отладке заголовка, которая может помочь вам понять, как работает резюме.

Нормальный ответ с сервера, файл читается от начала до конца. Значение ETag - это W/ "filesize_bytes-modified_utc" метаданные из файла диска. Это может быть что-то другое, но то, что Tomcat использует и обычно лучше всего подходит для обычного содержимого файла.

HTTP/1.1 200 OK 
ETag: W/"19097900-1410863319978" 
Last-Modified: Tue, 16 Sep 2014 10:28:39 GMT 
Content-Length: 19097900 
Content-Type: application/octet-stream 
Accept-Ranges: bytes 
Server: Apache-Coyote/1.1 
Date: Wed, 17 Sep 2014 10:39:52 GMT 

Клиент считывает данный фрагмент из файла, добавляя заголовки Range и If-Range. Диапазон байтов может быть открыт, поэтому сервер должен читать начиная с данного индекса до конца. Примечание. Content-Length - это не общая длина файла, а этот фрагмент байтов.

Range: bytes=10000000-
If-Range: W/"19097900-1410863319978"

HTTP/1.1 206 Partial Content 
ETag: W/"19097900-1410863319978" 
Last-Modified: Tue, 16 Sep 2014 10:28:39 GMT 
Content-Length: 9097900 
Content-Type: application/octet-stream 
Accept-Ranges: bytes 
Content-Range: bytes 10000000-19097899/19097900 
Server: Apache-Coyote/1.1 
Date: Wed, 17 Sep 2014 18:12:36 GMT 

Если удаленный файл был изменен, сервер не должен возвращать 206-PartialContent, но обычный ответ 200-OK. Сервер должен использовать значение If-Range для проверки на согласованность. Некоторые клиенты, такие как VLCPlayer, помещают поле Range без значения If-Range.

Когда клиент делает первоначальный запрос без заголовков Range + If-Range, он может добавить заголовок "If-Modified-Since: modified_http_date". Сервер может вернуть 304-NotModified статус и клиент выполнен. Если клиент дает byteStartIdx >= filesize, тогда сервер возвращает 416-RequestedRangeNotSatisfiable.

Дополнительные отладочные дампы, чтобы выяснить, как работает http-resume.

Range=bytes=0-0
If-Range=W/"19097900-1410863319978"

HTTP/1.1 206 Partial Content 
ETag=W/"19097900-1410863319978" 
Date=Fri, 19 Sep 2014 12:53:36 GMT 
Content-Length=1 
Last-Modified=Tue, 16 Sep 2014 10:28:39 GMT 
Content-Type=application/octet-stream 
Accept-Ranges=bytes 
Server=Apache-Coyote/1.1 
Content-Range=bytes 0-0/19097900 
- - - - -

Range=bytes=19097800-29097800
If-Range=W/"19097900-1410863319978"

HTTP/1.1 206 Partial Content 
ETag=W/"19097900-1410863319978" 
Date=Fri, 19 Sep 2014 12:59:24 GMT 
Content-Length=100 
Last-Modified=Tue, 16 Sep 2014 10:28:39 GMT 
Content-Type=application/octet-stream 
Accept-Ranges=bytes 
Server=Apache-Coyote/1.1 
Content-Range=bytes 19097800-19097899/19097900 
- - - - - - - - 

Range=bytes=19097899-19097899
If-Range=W/"19097900-1410863319978"

HTTP/1.1 206 Partial Content 
ETag=W/"19097900-1410863319978" 
Date=Fri, 19 Sep 2014 13:01:47 GMT 
Content-Length=1 
Last-Modified=Tue, 16 Sep 2014 10:28:39 GMT 
Content-Type=application/octet-stream 
Accept-Ranges=bytes 
Server=Apache-Coyote/1.1 
Content-Range=bytes 19097899-19097899/19097900